Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition)

Category: Programming
Author: Craig Larman
4.2
All Stack Overflow 22
This Year Stack Overflow 5
This Month Stack Overflow 3

Comments

by que que   2019-07-21

I am currently half-way through the following book:

http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062

I cannot recommend this book strongly enough in terms of learning a real-life, professional-grade, practical approach to drafting and applying a well-formed and iterative design strategy before diving into code.

I, too, read the "Head First" book and felt that I was much better off for having read it.

After having a few years of working-world experience, I now view the Craig Larman book that I am recommending to be a perfect "next step" for me.

About the Presence of "UML" in this Book Title:

Whether you have positive feelings or negative feelings about UML notation, please do not let that influence your decision to buy the book (ISBN 0131489062) in either direction.

The prominence of "UML" in the title is misleading. While the author does use and explain UML notation, these explanations are extremely well-woven into relevant design discussions, and at no time does this book read like a boring UML spec.

In fact, here is a quote taken directly from the book:

What's important is knowing how to think and design in objects, which is a very different and much more valuable skill than knowing UML notation. While drawing a diagram, we need to answer key questions: What are the responsibilities of the object? Who does it collaborate with? What design patterns should be applied? Far more important than knowing the difference between UML 1.4 and 2.0 !

This book at times seems like it is "speaking to" a lead architect or a project manager. What I mean to say by that is that it assumes that the reader has significant control over the planning and direction of a software project.

Nonetheless, even if you are only responsible for some very small piece of your company's projects and products, I would still recommend this book and encourage you to apply some "scaled down" modifications of the book's advice to your piece of the project.

by anonymous   2019-07-21

Might I suggest Peter Coad's Java Design as a good guide for doing OO/Java design? Something much more heavy weight and rigorous: http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062/ref=sr_1_1?s=books&ie=UTF8&qid=1288364561&sr=1-1

As for starting with Reqs- I suggest writing brief use cases and tie reqs to them so the reqs are in context.

by anonymous   2019-07-21

This is a pretty common problem - and there are different solutions for different scenarios.

If the different types of product and their attributes are fixed and known at development time, you could look at the description in Craig Larman's book (http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062/ref=sr_1_1/002-2801511-2159202?ie=UTF8&s=books&qid=1194351090&sr=1-1) - there's a section on object-relational mapping and how to handle inheritance. This boils down to "put all the possible columns into one table", "create one table for each sub class" or "put all base class items into a common table, and put sub class data into their own tables".

This is by far the most natural way of working with a relational database - it allows you to create reports, use off-the-shelf tools for object relational mapping if that takes your fancy, and you can use standard concepts such as "not null", indexing etc.

Of course, if you don't know the data attributes at development time, you have to create a flexible database schema.

I've seen 3 general approaches.

The first is the one described by davogotland. I built a solution on similar lines for an ecommerce store; it worked great, and allowed us to be very flexible about the product database. It performed very well, even with half a million products. Major drawbacks were creating retrieval queries - e.g. "find all products with a price under x, in category y, whose manufacturer is z". It was also tricky bringing in new developers - they had a fairly steep learning curve. It also forced us to push a lot of relational concepts into the application layer. For instance, it was hard to create foreign keys to other tables (e.g. "manufacturer") and enforce them using standard SQL functionality.

The second approach I've seen is the one you mention - storing the variable data in some kind of serialized format. This is a pain when querying, and suffers from the same drawbacks with the relational model. Overall, I'd only want to use serialization for data you don't have to be able to query or reason about.

The final solution I've seen is to accept that the addition of new product types will always require some level of development effort - you have to build the UI, if nothing else. I've seen applications which use a scaffolding style approach to automatically generate the underlying database structures when a new product type is created. This is a fairly major undertaking - only really suitable for major projects, though the use of ORM tools often helps.

by nickmancol   2018-09-24
Definitely Applying UML and Patterns https://www.amazon.com/Applying-UML-Patterns-Introduction-Ob...
by anonymous   2017-08-20

According to Wikipedia:

A Controller object is a non-user interface object responsible for receiving or handling a system event.

From Applying UML and Patterns:

What first object beyond the UI layer first receives and coordinates ("controls") a system operation?

Controllers, across the board - be it in MVC or GRASP or Patterns of EAA - are all about receiving input and responding to events.

I conceptualize it very literally: think of a video game controller. NES controller

It responds to input events - the user pressing buttons. It doesn't necessarily know what to do when you hit a button, but it at least receives the event.

Looking at the controller, one can easily figure out what the system events are - that is to say what inputs it responds to and how the user interacts with the system. On a Nintendo Controller, it's evident that system events are:

  • Press A
  • Press B
  • Press X
  • Press Y
  • Press
  • Press
  • Press
  • Press
  • Press L
  • Press R

If we were to take all these events and build a software controller to deal with them, it would be an MVC controller: these events are all concerned with the physical controller as presented to the user - it's "view", if you will. But there's a second layer of input events for most video games, where button mashing maps on to specific system operations. For example, if you're playing as Scorpion in Mortal Kombat 2, pressing ← ← B triggers one of your special moves. In that case, the system could need different controllers which deal with these different kinds of events:

UML diagram of various controller classes - a Button Controller with methods for each button press, and then various controller objects for different playable characters. Each player controller exposes methods corresponding to the character's special moves.

Here, the NES Button Controller is a MVC controller which would keep track of the state of UI elements - for example, remembering what buttons were pressed in what order. Depending on application state (see Application Controller - another one!) the NES Button Controller would response to certain button combinations by invoking methods on the other controllers - for example the Scorpion Controller - which are Use Case Controllers.

What's important is that by looking at the design of these controller objects, you can quickly and easily enumerate the system events they respond to.

Altogether, in the end, the MVC Controller is still a kind of GRASP Controller - as its methods tend to represent system events, which respond to user input. But there are other GRASP controllers which are not MVC controllers: Use Case controllers. A GRASP Use Case controller might respond to system events such as "user creates a new sale" while an MVC controller would respond to events like "system receives a PUT request for /sales/new" or "a java.awt.event.ActionEvent fires`".

by anonymous   2017-08-20

The famous coffee maker problem from Martin Fowler.

  • Coffee Maker
  • Another to look at
  • Interesting problem to solve without procedural code Jeff Bay mentioned it in this post: OOD / OOP Etudes / Code exercises
  • Problems with solutions explained. This is very good

Finally buy this book specifically for its treatment of the GRASP principles

by anonymous   2017-08-20

Many examples of Adapter are trivial or unrealistic (Rectangle vs. LegacyRectangle, Ratchet vs. Socket, SquarePeg vs RoundPeg, Duck vs. Turkey). Worse, many don't show multiple Adapters for different Adaptees (someone cited Java's Arrays.asList as an example of the adapter pattern). Adapting an interface of only one class to work with another seems a weak example of the GoF Adapter pattern. This pattern uses inheritance and polymorphism, so one would expect a good example to show multiple implementations of adapters for different adaptees.

The best example I found is in Chapter 26 of Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition). The following images are from the instructor material provided on an FTP site for the book.

The first one shows how an application can use multiple implementations (adaptees) that are functionally similar (e.g., tax calculators, accounting modules, credit authorization services, etc.) but have different APIs. We want to avoid hard-coding our domain-layer code to handle the different possible ways to calculate tax, post sales, authorize credit card requests, etc. Those are all external modules that might vary, and for which we can't modify the code. The adapter allows us to do the hard-coding in the adapter, whereas our domain-layer code always uses the same interface (the IWhateverAdapter interface).

Fig. 26.1

We don't see in the above figure the actual adaptees. However, the following figure shows how a polymorphic call to postSale(...) in the IAccountingAdapter interface is made, which results in a posting of the sale via SOAP to an SAP system.

Fig. 26.2

by anonymous   2017-08-20

I like Craig Larman's Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition). Most PHP programmers would do well to learn habits like design patterns and GRASP.

You could also "keep it in the family" and read the free online book Building Skills in Object-Oriented Design by Stack Overflow top-ten scorer Steven Lott.

by anonymous   2017-08-20

The solution of Strategy was already proposed https://stackoverflow.com/a/32798708/1168342, but this answer has some advantages.

Discounts and Orders are common domain problems. This wheel has been reinvented a few times. I'll cite a solution from chapter 26 of Craig Larman's "Applying UML and Patterns" book:

Pricing Strategy classes (part of Figure 26.9)

In this solution, a Sale is like your Order and ISalePricingStrategy is like your DiscountCalculator.

ISalePricingStrategy is an application of the Strategy pattern (the name is in the interface), and Strategies are always attached to a context object. In this case, it's the Sale (or in yours, IOrder).

Mapping to your problem

Here's the UML of how I see your problem fitting into Larman's suggested use of pricing strategies:

Pricing Strategy applied

Both your cases are composite instances of the AbsoluteDiscountOverThresholdPricingStrategy if I understand properly. Let's take the code from your conditional for OnlineOrders:

if (order.GetTotalPrice() < 100)
  return 2;
else
  return 5;

This is like adding to your order two instances of

onlineOrder.addPricingStrategy(new AbsoluteDiscountOverThresholdPricingStrategy(2,0));  // orders under 100
onlineOrder.addPricingStrategy(new AbsoluteDiscountOverThresholdPricingStrategy(5,100));  // orders >= 100

So, Larman goes a step further and explains that you can combine such strategies using the Composite pattern. I'll apply it to your problem (the hint is in the add... method above):

Composite strategies per Larman, figure 26.14

The two classes I put in pink are optional. If you always give the best strategy to the customer (as in the pseudocode of the note I attached to GetTotalPrice) you don't need them. Larman explains you can go a step further and say that if more than one strategy applies, the calculation is either in favor of the store or the customer. Again, it's a question of instantiating the class and attaching it. The code to do this could be run from a "Configuration" menu command in your software.

The code to use this would look something like:

IOrder onlineOrder = new OnlineOrder();  //...
...
CompositePricingStrategy comp = new CompositePricingStrategy();
comp.add(new AbsoluteDiscountOverThresholdPricingStrategy(2,0));  // orders under 100
comp.add(new AbsoluteDiscountOverThresholdPricingStrategy(5,100));  // orders >= 100
onlineOrder.setPricingStrategy(comp);
// repeat as above for instoreOrders ...

There are more flexible ways again to do this, using factories. See Larman's book for very cool examples in Java/.NET.

Advantages

Since this answer is similar to another one, I want to explain some advantages of this method, even though it's more complicated. If you use GetTotal() in the discount logic, it has some advantages over GetDiscount():

  • GetTotal() handles (encapsulates) all the logic to calculate the total.
  • If multiple strategies apply (e.g., online orders get 5% discount, orders over $200 get 10% discount) you may want to code how this is handled. Larman gives an example using Composite pattern where again GetTotal() works impeccably without the client code having to do anything special.
  • You can extend other types of Strategies and instantiate them as needed. For example, for any order over $500 you can make the discount 50. It's a question of instantiating the new class in the code (not coding the logic).