Patterns

2,278 views

Published on

  • Be the first to comment

Patterns

  1. 1. www,mondora.com Design pattern Elements of reusable Object-Oriented software Erich Gamma Richard Helm Ralph Johnson John Vlissides November 2009, Loquendo, Turin venerdì 13 novembre 2009
  2. 2. www,mondora.com Describe Design Pattern Pattern Name and Participants Classification Collaboration Intent Consequences Also Known As Implementation Motivation Sample Code Applicability Known Use Structure Related Pattern day2 November 2009, Loquendo, Turin venerdì 13 novembre 2009
  3. 3. www,mondora.com Structural Patterns loquendo November 2009, Loquendo, Turin venerdì 13 novembre 2009
  4. 4. www,mondora.com Structural Patterns Structural patterns are concerned with how classes Structural Patterns and objects are composed to form larger structures. Structural class patterns use inheritance to compose interfaces or implementations. venerdì 13 novembre 2009
  5. 5. www,mondora.com Structural Patterns Adapter [Flyweight] Bridge Composite Decorator Façade Proxy day2 November 2009, Loquendo, Turin venerdì 13 novembre 2009
  6. 6. www,mondora.com Adapter Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't Adapter otherwise because of incompatible interfaces. venerdì 13 novembre 2009
  7. 7. www,mondora.com Structure A class adapter Adapter An object adapter venerdì 13 novembre 2009
  8. 8. www,mondora.com Consequences Class and object adapters have different trade-offs. ★A class adapter •adapts Adaptee to Target by committing to a concrete Adapter class. As a consequence, a class adapter won't work when we want to adapt Adapter a class and all its subclasses. •letsAdapter override some of Adaptee's behavior, since Adapter is a subclass of Adaptee. •introduces only one object, and no additional pointer indirection is needed to get to the adaptee. ★An object adapter •lets a single Adapter work with many Adaptees—that is, the Adaptee itself and all of its subclasses (if any). The Adapter can also add functionality to all Adaptees at once. •makes it harder to override Adaptee behavior. It will require subclassing Adaptee. venerdì 13 novembre 2009
  9. 9. www,mondora.com Bridge Decouple an abstraction from its implementation so that the two can vary independently. Bridge venerdì 13 novembre 2009
  10. 10. www,mondora.com Structure Bridge Bridge Sample venerdì 13 novembre 2009
  11. 11. www,mondora.com Consequences •Decoupling interface and implementation. •An implementation is not bound permanently to an interface. The implementation of an abstraction can be configured at run-time. It's even possible for an object to change its implementation at run-time. •Decoupling Abstraction and Implementor also eliminates compile-time Bridge dependencies on the implementation. Changing an implementation class doesn't require recompiling the Abstraction class and its clients. This property is essential when you must ensure binary compatibility between different versions of a class library. •Furthermore, this decoupling encourages layering that can lead to a better- structured system. The high-level part of a system only has to know about Abstraction and Implementor. • Improved extensibility. You can extend the Abstraction and Implementor hierarchies independently. • Hiding implementation details from clients. You can shield clients from implementation details, like the sharing of implementor objects and the accompanying reference count mechanism (if any). venerdì 13 novembre 2009
  12. 12. www,mondora.com Composite Compose objects into tree structures to represent part-whole hierarchies. Composite Composite lets clients treat individual objects and compositions of objects uniformly. venerdì 13 novembre 2009
  13. 13. www,mondora.com Structure Composite Sample venerdì 13 novembre 2009
  14. 14. www,mondora.com Consequences • defines class hierarchies consisting of primitive objects and composite objects. Primitive objects can be composed into more complex objects, which in turn can be composed, and so on recursively. Wherever client code expects a primitive object, it can also Composite take a composite object. • makes the client simple. Clients can treat composite structures and individual objects uniformly. Clients normally don't know (and shouldn't care) whether they're dealing with a leaf or a composite component. • makes it easier to add new kinds of components. Newly defined Composite or Leaf subclasses work automatically with existing structures and client code. Clients don't have to be changed for new Component classes. • can make your design overly general. The disadvantage of making it easy to add new components is that it makes it harder to restrict the components of a composite. venerdì 13 novembre 2009
  15. 15. www,mondora.com Decorator Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to Decorator subclassing for extending functionality. venerdì 13 novembre 2009
  16. 16. www,mondora.com Structure Decorator Sample venerdì 13 novembre 2009
  17. 17. www,mondora.com Consequences The Decorator pattern has at least two key benefits and two liabilities: •More flexibility than static inheritance. •The Decorator pattern provides a more flexible way to add responsibilities to objects than can be had with static (multiple) inheritance. With decorators, responsibilities can be added Decorator and removed at run-time simply by attaching and detaching them. In contrast, inheritance requires creating a new class for each additional responsibility. •Avoids feature-laden classes high up in the hierarchy. •Decorator offers a pay-as-you-go approach to adding responsibilities. Instead of trying to support all foreseeable features in a complex, customizable class, you can define a simple class and add functionality incrementally with Decorator objects. Functionality can be composed from simple pieces. •A decorator and its component aren't identical. •A decorator acts as a transparent enclosure. But from an object identity point of view, a decorated component is not identical to the component itself. •Lots of little objects. •A design that uses Decorator often results in systems composed of lots of little objects that all look alike. The objects differ only in the way they are interconnected, not in their class or in the value of their variables. Although these systems are easy to customize by those who understand them, they can be hard to learn and debug. venerdì 13 novembre 2009
  18. 18. www,mondora.com Façade Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes Façade the subsystem easier to use. venerdì 13 novembre 2009
  19. 19. www,mondora.com Structure Façade Sample venerdì 13 novembre 2009
  20. 20. www,mondora.com Consequences The Façade pattern offers the following benefits: •It shields clients from subsystem components, thereby reducing the number of objects that clients deal with and making the subsystem easier to use. Façade •It promotes weak coupling between the subsystem and its clients. Often the components in a subsystem are strongly coupled. Weak coupling lets you vary the components of the subsystem without affecting its clients. Reducing compilation dependencies with facades can limit the recompilation needed for a small change in an important subsystem. •It doesn't prevent applications from using subsystem classes if they need to. Thus you can choose between ease of use and generality. venerdì 13 novembre 2009
  21. 21. www,mondora.com Proxy Provide a surrogate or placeholder for another object to control access to it. Proxy venerdì 13 novembre 2009
  22. 22. www,mondora.com Structure Proxy Sample venerdì 13 novembre 2009
  23. 23. www,mondora.com Consequences The Proxy pattern introduces a level of indirection when accessing an object. The additional indirection has many uses, depending on the kind of proxy: 1. A remote proxy can hide the fact that an object resides in a different address space. 2. A virtual proxy can perform optimizations such as creating an object on demand. 3. Both protection proxies and smart references allow additional housekeeping tasks Proxy when an object is accessed. There's another optimization that the Proxy pattern can hide from the client. It's called copy-on-write, and it's related to creation on demand. Copying a large and complicated object can be an expensive operation. If the copy is never modified, then there's no need to incur this cost. By using a proxy to postpone the copying process, we ensure that we pay the price of copying the object only if it's modified. To make copy-on-write work, the subject must be reference counted. Copying the proxy will do nothing more than increment this reference count. Only when the client requests an operation that modifies the subject does the proxy actually copy it. In that case the proxy must also decrement the subject's reference count. When the reference count goes to zero, the subject gets deleted. Copy-on-write can reduce the cost of copying heavyweight subjects significantly. venerdì 13 novembre 2009
  24. 24. www,mondora.com Flyweight Use sharing to support large numbers of fine-grained objects efficiently. Flyweight venerdì 13 novembre 2009
  25. 25. www,mondora.com Structure Flyweight venerdì 13 novembre 2009
  26. 26. www,mondora.com Consequences •Flyweights may introduce run-time costs associated with transferring, finding, and/or computing extrinsic state, especially if it was formerly stored as intrinsic state. However, such costs are offset by space savings, which increase as more flyweights are shared. •Storage savings are a function of several factors: Flyweight • the reduction in the total number of instances that comes from sharing; • the amount of intrinsic state per object; • whether extrinsic state is computed or stored. •The more flyweights are shared, the greater the storage savings. The savings increase with the amount of shared state. The greatest savings occur when the objects use substantial quantities of both intrinsic and extrinsic state, and •the extrinsic state can be computed rather than stored. Then you save on storage in two ways: Sharing reduces the cost of intrinsic state, and you trade extrinsic state for computation time. •The Flyweight pattern is often combined with the Composite pattern to represent a hierarchical structure as a graph with shared leaf nodes. A consequence of sharing is that flyweight leaf nodes cannot store a pointer to their parent. Rather, the parent pointer is passed to the flyweight as part of its extrinsic state. This has a major impact on how the objects in the hierarchy communicate with each other. venerdì 13 novembre 2009
  27. 27. www,mondora.com Creational Patterns loquendo November 2009, Loquendo, Turin venerdì 13 novembre 2009
  28. 28. www,mondora.com Creational Patterns Creational design patterns abstract the instantiation Creational Patterns process. They help make a system independent of how its objects are created, composed, and represented. A class creational pattern uses inheritance to vary the class that's instantiated, whereas an object creational pattern will delegate instantiation to another object. Creational patterns become important as systems evolve to depend more on object composition than class inheritance. venerdì 13 novembre 2009
  29. 29. www,mondora.com Creational Patterns Factory Method Abstract factory Singleton Prototype Builder day2 November 2009, Loquendo, Turin venerdì 13 novembre 2009
  30. 30. www,mondora.com Factory Method Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method Factory Method lets a class defer instantiation to subclasses. venerdì 13 novembre 2009
  31. 31. www,mondora.com Structure Factory Method venerdì 13 novembre 2009
  32. 32. www,mondora.com Consequences Factory methods eliminate the need to bind application-specific classes into your code. The code Factory Method only deals with the Product interface; therefore it can work with any user-defined ConcreteProduct classes. A potential disadvantage of factory methods is that clients might have to subclass the Creator class just to create a particular ConcreteProduct object. Subclassing is fine when the client has to subclass the Creator class anyway, but otherwise the client now must deal with another point of evolution. venerdì 13 novembre 2009
  33. 33. www,mondora.com Abstract Factory Provide an interface for creating families of related or dependent objects without specifying their concrete Abstract Factory classes. venerdì 13 novembre 2009
  34. 34. www,mondora.com Structure Abstract Factory venerdì 13 novembre 2009
  35. 35. www,mondora.com Abstract Factory It isolates concrete classes. The Abstract Factory pattern helps you control the classes of objects that an application creates. Because a factory encapsulates the Abstract Factory responsibility and the process of creating product objects, it isolates clients from implementation classes. Clients manipulate instances through their abstract interfaces. Product class names are isolated in the implementation of the concrete factory; they do not appear in client code. It makes exchanging product families easy. The class of a concrete factory appears only once in an application—that is, where it's instantiated. This makes it easy to change the concrete factory an application uses. It can use different product configurations simply by changing the concrete factory. Because an abstract factory creates a complete family of products, the whole product family changes at once. It promotes consistency among products. When product objects in a family are designed to work together, it's important that an application use objects from only one family at a time. AbstractFactory makes this easy to enforce. Supporting new kinds of products is difficult. Extending abstract factories to produce new kinds of Products isn't easy. That's because the AbstractFactory interface fixes the set of products that can be created. Supporting new kinds of products requires extending the factory interface, which involves changing the AbstractFactory class and all of its subclasses. venerdì 13 novembre 2009
  36. 36. www,mondora.com Singleton Ensure a class only has one instance, and provide a global point of access to it. Singleton venerdì 13 novembre 2009
  37. 37. www,mondora.com Structure Singleton venerdì 13 novembre 2009
  38. 38. www,mondora.com Consequences • Controlled access to sole instance. Because the Singleton class encapsulates its sole instance, it can have strict control over how and when clients access it. • Reduced name space. The Singleton pattern is an improvement Singleton over global variables. It avoids polluting the name space with global variables that store sole instances. • Permits refinement of operations and representation. The Singleton class may be subclassed, and it's easy to configure an application with an instance of this extended class. You can configure the application with an instance of the class you need at run-time. • Permits a variable number of instances. The pattern makes it easy to change your mind and allow more than one instance of the Singleton class. Moreover, you can use the same approach to control the number of instances that the application uses. Only the operation that grants access to the Singleton instance needs to change. venerdì 13 novembre 2009
  39. 39. www,mondora.com Prototype Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. Prototype venerdì 13 novembre 2009
  40. 40. www,mondora.com Structure Prototype venerdì 13 novembre 2009
  41. 41. www,mondora.com Consequences • Adding and removing products at run-time. Prototypes let you incorporate a new concrete product class into a system simply by registering a prototypical instance with the client. That's a bit more flexible than other creational patterns, because a client can install and remove prototypes at run-time. • Specifying new objects by varying values. Highly dynamic systems let you define new Prototype behavior through object composition—by specifying values for an object's variables, for example—and not by defining new classes. You effectively define new kinds of objects by instantiating existing classes and registering the instances as prototypes of client objects. A client can exhibit new behavior by delegating responsibility to the prototype. This kind of design lets users define new "classes" without programming. In fact, cloning a prototype is similar to instantiating a class. • Specifying new objects by varying structure. As long as the composite object implements Clone as a deep copy, objects with different structures can be prototypes. • Reduced subclassing. Factory Method often produces a hierarchy of Creator classes that parallels the product class hierarchy. The Prototype pattern lets you clone a prototype instead of asking a factory method to make a new object. Hence you don't need a Creator class hierarchy at all. • Configuring an application with classes dynamically. Some run-time environments let you load classes into an application dynamically. The Prototype pattern is the key to exploiting such facilities in a language like C++. venerdì 13 novembre 2009
  42. 42. www,mondora.com Builder Separate the construction of a complex object from its representation so that the same construction process can create different representations. Builder venerdì 13 novembre 2009
  43. 43. www,mondora.com Structure Builder venerdì 13 novembre 2009
  44. 44. www,mondora.com Consequences • It lets you vary a product's internal representation. The Builder object provides the director with an abstract interface for constructing the product. The interface lets the builder hide the representation and internal structure of the product. It also hides how the product gets assembled. Because the product is constructed through an abstract interface, all you have to do to change the product's internal representation is define a new kind of builder. Builder • It isolates code for construction and representation. The Builder pattern improves modularity by encapsulating the way a complex object is constructed and represented. Clients needn't know anything about the classes that define the product's internal structure; such classes don't appear in Builder's interface. Each ConcreteBuilder contains all the code to create and assemble a particular kind of product. The code is written once; then different Directors can reuse it to build Product variants from the same set of parts. • It gives you finer control over the construction process. Unlike creational patterns that construct products in one shot, the Builder pattern constructs the product step by step under the director's control. Only when the product is finished does the director retrieve it from the builder. Hence the Builder interface reflects the process of constructing the product more than other creational patterns. This gives you finer control over the construction process and consequently the internal structure of the resulting product. venerdì 13 novembre 2009
  45. 45. www,mondora.com Behavioral Patterns loquendo November 2009, Loquendo, Turin venerdì 13 novembre 2009
  46. 46. www,mondora.com Behavioral Patterns Behavioral patterns are concerned with algorithms Behavioral Patterns and the assignment of responsibilities between objects. Behavioral patterns describe not just patterns of objects or classes but also the patterns of communication between them. These patterns characterize complex control flow that's difficult to follow at run-time. venerdì 13 novembre 2009
  47. 47. www,mondora.com Behavioral Patterns Chain of responsibility Mediator Command Interpreter Iterator Memento Strategy Template method Observer Visitor State day3 November 2009, Loquendo, Turin venerdì 13 novembre 2009
  48. 48. www,mondora.com Chain of responsibility Chain of responsibility Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. venerdì 13 novembre 2009
  49. 49. www,mondora.com Structure Chain of responsibility venerdì 13 novembre 2009
  50. 50. www,mondora.com Consequences Chain of responsibility • Reduced coupling. The pattern frees an object from knowing which other object handles a request. An object only has to know that a request will be handled "appropriately." Both the receiver and the sender have no explicit knowledge of each other, and an object in the chain doesn't have to know about the chain's structure. As a result, Chain of Responsibility can simplify object interconnections. Instead of objects maintaining references to all candidate receivers, they keep a single reference to their successor. • Added flexibility in assigning responsibilities to objects. Chain of Responsibility gives you added flexibility in distributing responsibilities among objects. You can add or change responsibilities for handling a request by adding to or otherwise changing the chain at run-time. You can combine this with subclassing to specialize handlers statically. • Receipt isn't guaranteed. Since a request has no explicit receiver, there's no guarantee it'll be handled—the request can fall off the end of the chain without ever being handled. A request can also go unhandled when the chain is not configured properly. venerdì 13 novembre 2009
  51. 51. www,mondora.com Command Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable Command operations. venerdì 13 novembre 2009
  52. 52. www,mondora.com Structure Command venerdì 13 novembre 2009
  53. 53. www,mondora.com Consequences • Command decouples the object that invokes the operation from the one that knows how to perform it. • Command Commands are first-class objects. They can be manipulated and extended like any other object. • You can assemble commands into a composite command. In general, composite commands are an instance of the Composite pattern. • It's easy to add new Commands, because you don't have to change existing classes. venerdì 13 novembre 2009
  54. 54. www,mondora.com Iterator Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. Interpreter venerdì 13 novembre 2009
  55. 55. www,mondora.com Structure client Iterator venerdì 13 novembre 2009
  56. 56. www,mondora.com Consequences •It supports variations in the traversal of an aggregate. Complex aggregates may be traversed in many ways. For example, code generation and semantic checking involve traversing parse trees. Code generation may traverse the parse tree in order or pre order. Iterators make it easy to change the traversal algorithm: Just replace the iterator instance with Iterator a different one. You can also define Iterator subclasses to support new traversals. •Iterators simplify the Aggregate interface. Iterator's traversal interface obviates the need for a similar interface in Aggregate, thereby simplifying the aggregate's interface. • More than one traversal can be pending on an aggregate. An iterator keeps track of its own traversal state. Therefore you can have more than one traversal in progress at once. venerdì 13 novembre 2009
  57. 57. www,mondora.com Mediator Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping Mediator objects from referring to each other explicitly, and it lets you vary their interaction independently. venerdì 13 novembre 2009
  58. 58. www,mondora.com Structure Mediator venerdì 13 novembre 2009
  59. 59. www,mondora.com Consequences • It limits subclassing. A mediator localizes behavior that otherwise would be distributed among several objects. Changing this behavior requires subclassing Mediator only; Colleague classes can be reused as is. • It decouples colleagues. Mediator A mediator promotes loose coupling between colleagues. You can vary and reuse Colleague and Mediator classes independently. • It simplifies object protocols. A mediator replaces many-to-many interactions with one-to-many interactions between the mediator and its colleagues. One-to-many relationships are easier to understand, maintain, and extend. • It abstracts how objects cooperate. Making mediation an independent concept and encapsulating it in anobject lets you focus on how objects interact apart from their individual behavior. That can help clarify how objects interact in a system. • It centralizes control. The Mediator pattern trades complexity of interaction for complexity in the mediator. Because a mediator encapsulates protocols, it can become more complex than any individual colleague. This can make the mediator itself a monolith that's hard to maintain. venerdì 13 novembre 2009
  60. 60. www,mondora.com Observer Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. Observer venerdì 13 novembre 2009
  61. 61. www,mondora.com Structure Observer venerdì 13 novembre 2009
  62. 62. www,mondora.com Consequences • Abstract coupling between Subject and Observer. All a subject knows is that it has a list of observers, each conforming to the simple interface of the abstract Observer class. The subject doesn't know the concrete class of any observer. Thus the coupling between subjects and observers is abstract and minimal. Because Subject and Observer aren't tightly coupled, they can belong to different layers of abstraction in a system. A lower-level subject can communicate and inform Observer a higher-level observer, thereby keeping the system's layering intact. If Subject and Observer are lumped together, then the resulting object must either span two layers (and violate the layering), or it must be forced to live in one layer or the other (which might compromise the layering abstraction). • Support for broadcast communication. Unlike an ordinary request, the notification that a subject sends needn't specify its receiver. The notification is broadcast automatically to all interested objects that subscribed to it. The subject doesn't care how many interested objects exist; its only responsibility is to notify its observers. This gives you the freedom to add and remove observers at any time. It's up to the observer to handle or ignore a notification. • Unexpected updates. Because observers have no knowledge of each other's presence, they can be blind to the ultimate cost of changing the subject. A seemingly innocuous operation on the subject may cause a cascade of updates too Observers and their dependent objects. Moreover, dependency criteria that aren't well-defined or maintained usually lead to spurious updates, which can be hard to track down. This problem is aggravated by the fact that the simple update protocol provides no details on what changed in the subject. Without additional protocol to help observers discover what changed, they maybe forced to work hard to deduce the changes. venerdì 13 novembre 2009
  63. 63. www,mondora.com State Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. State venerdì 13 novembre 2009
  64. 64. www,mondora.com Structure State venerdì 13 novembre 2009
  65. 65. www,mondora.com Consequences • It localizes state-specific behavior and partitions behavior for different states. The State pattern puts all behavior associated with a particular state into one object. Because all state-specific code lives in a State subclass, new states and transitions can be added easily by defining new subclasses. An alternative is to use data values to define internal states and have Context operations check the data explicitly. But then we'd have look-alike conditional or case statements scattered throughout Context's implementation. Adding a new state could require changing several operations, which complicates maintenance. The State pattern avoids this problem but might introduce another, because the pattern distributes behavior for different states across several State subclasses. This increases the number of classes and is less compact than a single class. But such distribution is actually good if there are many states, which would otherwise necessitate large conditional State statements. Like long procedures, large conditional statements are undesirable. They're monolithic and tend to make the code less explicit, which in turn makes them difficult to modify and extend. The State pattern offers a better way to structure state-specific code. The logic that determines the state transitions doesn't reside in monolithic if or switch statements but instead is partitioned between the State subclasses. Encapsulating each state transition and action in a class elevates the idea of an execution state to full object status. That imposes structure on the code and makes its intent clearer. • It makes state transitions explicit. When an object defines its current state solely in terms of internal data values, its state transitions have no explicit representation; they only show up as assignments to some variables. Introducing separate objects for different states makes the transitions more explicit. Also, State objects can protect the Context from inconsistent internal states, because state transitions are atomic from the Context's perspective—they happen by rebinding one variable (the Context's State object variable), not several. • State objects can be shared. If State objects have no instance variables—that is, the state they represent is encoded entirely in their type—then contexts can share a State object. When states are shared in this way, they are essentially flyweights (see Flyweight) with no intrinsic state, only behavior. venerdì 13 novembre 2009
  66. 66. www,mondora.com Strategy Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from Strategy clients that use it. venerdì 13 novembre 2009
  67. 67. www,mondora.com Structure Strategy venerdì 13 novembre 2009
  68. 68. www,mondora.com Consequences • Families of related algorithms. Hierarchies of Strategy classes define a family of algorithms or behaviors for contexts to reuse. Inheritance can help factor out common functionality of the algorithms. • An alternative to subclassing. Strategy Inheritance offers another way to support a variety of algorithms or behaviors. You can subclass a Context class directly to give it different behaviors. But this hard-wires the behavior into Context. It mixes the algorithm implementation with Context's, making Context harder to understand, maintain, and extend. And you can't vary the algorithm dynamically. You wind up with many related classes whose only difference is the algorithm or behavior they employ. Encapsulating the algorithm in separate Strategy classes lets you vary the algorithm independently of its context, making it easier to switch, understand, and extend. • Strategies eliminate conditional statements. The Strategy pattern offers an alternative to conditional statements for selecting desired behavior. When different behaviors are lumped into one class, it's hard to avoid using conditional statements to select the right behavior. Encapsulating the behavior in separate Strategy classes eliminates these conditional statements. venerdì 13 novembre 2009
  69. 69. www,mondora.com Interpreter Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the Interpreter language. venerdì 13 novembre 2009
  70. 70. www,mondora.com Structure Interpreter venerdì 13 novembre 2009
  71. 71. www,mondora.com Consequences • It's easy to change and extend the grammar. Because the pattern uses classes to represent grammar rules, you can use inheritance to change or extend the grammar. Existing expression scan be modified incrementally, and new expressions can be defined as variations on old ones. Interpreter • Implementing the grammar is easy, too. Classes defining nodes in the abstract syntax tree have similar implementations. These classes are easy to write, and often their generation can be automated with a compiler or parser generator. • Complex grammars are hard to maintain. The Interpreter pattern defines at least one class for every rule in the grammar (grammar rules defined using BNF may require multiple classes). Hence grammars containing many rules can be hard to manage and maintain. Other design patterns can be applied to mitigate the problem (see Implementation). But when the grammar is very complex, other techniques such as parser or compiler generators are more appropriate. • Adding new ways to interpret expressions. The Interpreter pattern makes it easier to evaluate an expression in a new way. For example, you can support pretty printing or type-checking an expression by defining a new operation on the expression classes. If you keep creating new ways of interpreting an expression, then consider using the Visitor pattern to avoid changing the grammar classes. venerdì 13 novembre 2009
  72. 72. www,mondora.com Memento Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later. Memento venerdì 13 novembre 2009
  73. 73. www,mondora.com Structure Memento venerdì 13 novembre 2009
  74. 74. www,mondora.com Consequences • Preserving encapsulation boundaries. Memento avoids exposing information that only an originator should manage but that must be stored nevertheless outside the originator. The pattern shields other objects from potentially complex Originator internals, thereby preserving encapsulation boundaries. • It simplifies Originator. Memento In other encapsulation-preserving designs, Originator keeps the versions of internal state that clients have requested. That puts all the storage management burden on Originator. Having clients manage the state they ask for simplifies Originator and keeps clients from having to notify originators when they're done. • Using mementos might be expensive. Mementos might incur considerable overhead if Originator must copy large amounts of information to store in the memento or if clients create and return mementos to the originator often enough. Unless encapsulating and restoring Originator state is cheap, the pattern might not be appropriate. See the discussion of incrementality in the Implementation section. • Defining narrow and wide interfaces. It may be difficult in some languages to ensure that only the originator can access the memento's state. • Hidden costs in caring for mementos. A caretaker is responsible for deleting the mementos it cares for. However, the caretaker has no idea how much state is in the memento. Hence an otherwise lightweight caretaker might incur large storage costs when it stores mementos. venerdì 13 novembre 2009
  75. 75. www,mondora.com Template Method Define the skeleton of an algorithm in an operation, Template Method deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure. venerdì 13 novembre 2009
  76. 76. www,mondora.com Structure Template Method venerdì 13 novembre 2009
  77. 77. www,mondora.com Consequences • Template methods are a fundamental technique for Template Method code reuse. They are particularly important in class libraries, because they are the means for factoring out common behavior in library classes. • Template methods lead to an inverted control structure that's sometimes referred to as "the Hollywood principle," that is, "Don't call us, we'll call you". This refers to how a parent class calls the operations of a subclass and not the other way around. venerdì 13 novembre 2009
  78. 78. www,mondora.com Visitor Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it Visitor operates. venerdì 13 novembre 2009
  79. 79. www,mondora.com Structure client Visitor venerdì 13 novembre 2009
  80. 80. www,mondora.com Consequences • Visitor makes adding new operations easy. Visitors make it easy to add operations that depend on the components of complex objects. You can define a new operation over an object structure simply by adding a new visitor. In contrast, if you spread functionality over many classes, then you must change each class to define a new operation. • A visitor gathers related operations and separates unrelated ones. Related behavior isn't spread over the classes defining the object structure; it's localized in a visitor. Unrelated sets Visitor of behavior are partitioned in their own visitor subclasses. That simplifies both the classes defining the elements and the algorithms defined in the visitors. Any algorithm-specific data structures can be hidden in the visitor. • Adding new ConcreteElement classes is hard. The Visitor pattern makes it hard to add new subclasses of Element. Each new ConcreteElement gives rise to a new abstract operation on Visitor and a corresponding implementation in every ConcreteVisitor class. Sometimes a default implementation can be provided in Visitor that can be inherited by most of the ConcreteVisitors, but this is the exception rather than the rule. So the key consideration in applying the Visitor pattern is whether you are mostly likely to change the algorithm applied over an object structure or the classes of objects that make up the structure. The Visitor class hierarchy can be difficult to maintain when new ConcreteElement classes are added frequently. In such cases, it's probably easier just to define operations on the classes that make up the structure. If the Element class hierarchy is stable, but you are continually adding operations or changing algorithms, then the Visitor pattern will help you manage the changes. • Visiting across class hierarchies. An iterator (see Iterator) can visit the objects in a structure as it traverses them by calling their operations. But an iterator can't work across object structures with different types of elements. venerdì 13 novembre 2009
  81. 81. www,mondora.com Design Pattern relationship venerdì 13 novembre 2009
  82. 82. www,mondora.com Design Pattern relationship classification from http://reference.kfupm.edu.sa/content/r/e/relationships_between_design_patterns__148528.pdf venerdì 13 novembre 2009
  83. 83. www,mondora.com More about patterns loquendo November 2009, Loquendo, Turin venerdì 13 novembre 2009
  84. 84. www,mondora.com AntiPattern An AntiPattern is a literary form that describes a commonly occurring solution to a problem that generates decidedly negative consequences. The AntiPattern may be the result of a manager or developer not knowing any better, not having sufficient knowledge or extra experience in solving a particular type of problem, or having applied a perfectly good pattern in the wrong context. The term was coined in 1995 by Andrew Koenig, inspired by Gang of Four's book Design Patterns, which developed the concept of design patterns in the software field. The term was widely popularized three years later by the book AntiPatterns, which extended the use of the term beyond the field of software design and into general social interaction. venerdì 13 novembre 2009
  85. 85. www,mondora.com Design anti patterns Anemic Domain Model: The use God object: Concentrating too many of domain model without any business logic functions in a single part of the design (class) design anti patterns which is not OOP because each object should have both attributes and behaviors Object cesspool: Reusing objects whose state does not conform to the BaseBean: Inheriting functionality from (possibly implicit) contract for re-use a utility class rather than delegating to it Object orgy: Failing to properly Call super: Requiring subclasses to call encapsulate objects permitting unrestricted a superclass's overridden method access to their internals Circle-ellipse problem: Subtyping Poltergeists: Objects whose sole variable-types on the basis of value- purpose is to pass information to another subtypes object Circular dependency: Introducing Sequential coupling: A class that unnecessary direct or indirect mutual requires its methods to be called in a dependencies between objects or software particular order modules Yo-yo problem: A structure (e.g., of Constant interface: Using inheritance) that is hard to understand due to interfaces to define constants excessive fragmentation November 2009, Loquendo, Turin venerdì 13 novembre 2009
  86. 86. www,mondora.com Anemic Domain Model is a pejorative term used to describe the use of a software domain model where the business logic is design anti patterns implemented outside the domain objects. logic is typically implemented in separate classes which transform the state of the domain objects. This pattern is a common approach in enterprise Java applications, possibly encouraged by technologies such as early versions of EJB's Entity Beans, as well as in .NET applications following the Three-Layered Services Application architecture where such objects fall into the category of "Business Entities". venerdì 13 novembre 2009
  87. 87. www,mondora.com Base bean is a utility object from which concrete entities are derived (via subclassing). design anti patterns Proper design suggests that the inherited functionality should be provided via delegation instead. A class should not inherit from another class simply because the parent class contains functionality needed in the subclass. Instead, delegation (has- a relationship) should be used to obtain the business logic or data structure that is required. In technical terms, this case warrants composition over inheritance. In some cases a static utility class can be created to contain necessary functionality. venerdì 13 novembre 2009
  88. 88. www,mondora.com call super You are inheriting from a super-class in order to plug into some framework. The documentation says something like "to do your own thing, just design anti patterns subclass the process method. However it's important to remember to start your method with a call to the super-class". public class TransferEventHandler public class EventHandler ... extends EventHandler... public void handle (BankingEvent e) { public void handle(BankingEvent e) { housekeeping(e); super.handle(e); } initiateTransfer(e); } Whenever you have to remember to do something every time, that's a sign of a bad API. Instead the API should remember the housekeeping call for you. The usual way to do this is to make the handle method a Template Method. venerdì 13 novembre 2009
  89. 89. www,mondora.com call super The usual way to do this is to make the handle method a Template Method, like this. design anti patterns public class EventHandler ... public class TransferEventHandler public void handle (BankingEvent e) { extends EventHandler ... housekeeping(e); doHandle(e); protected void doHandle(BankingEvent e) { } initiateTransfer(e); protected void doHandle(BankingEvent e) { } } venerdì 13 novembre 2009
  90. 90. www,mondora.com Circle-ellipse problem illustrates a number of pitfalls which can arise when using subtype polymorphism in object modelling. The issues are most commonly design anti patterns encountered when using object-oriented programming. The problem concerns what subtyping/inheritance relationship should exist between classes which represent circles and ellipses (or, similarly, rectangles and squares). More generally, the problem illustrates the difficulties which can occur when a base class contains methods which mutate an object in a manner which might invalidate a (stronger) invariant found in a derived class, causing the Liskov substitution principle to be violated. the set of circles is a subset of the set of ellipses; circles can be defined as ellipses whose major and minor axes are the same length. If Circle inherits from Ellipse, it must also have a method stretchX, but the result of this method would be to change a circle into something which is no longer a circle. The Circle class can not simultaneously satisfy its own invariant, and the behavioral requirements of the Ellipse::stretchX method. venerdì 13 novembre 2009
  91. 91. www,mondora.com Circular dependency is a relation between two or more modules which either directly or indirectly depend on each other to function properly. design anti patterns Circular dependencies can cause many unwanted effects in software programs. Most problematic from a software design point of view is the tight coupling of the mutually dependent modules which reduces or makes impossible the separate re- use of a single module. Circular dependencies can cause a domino effect when a small local change in one module spreads into other modules and has unwanted global effects (program errors, compile errors). Circular dependencies can also result in infinite recursions or other unexpected failures. Circular dependencies are often introduced by inexperienced programmers who need to implement some kind of callback functionality. Experienced programmers avoid such unnecessary circular dependencies by applying design patterns like the observer pattern. venerdì 13 novembre 2009
  92. 92. www,mondora.com Constant interface describes the use of an interface solely to define constants, and having classes implement that design anti patterns interface in order to achieve convenient syntactic access to those constants. In general, collecting system constants into classes independent of behaviour, might create a poor object-oriented design, because it is often a sign of low cohesion. It is for these reasons that implementing constants interfaces is considered to be an anti-pattern. venerdì 13 novembre 2009
  93. 93. www,mondora.com God Object knows too much or does too much. most of a program's overall functionality is coded into a single design anti patterns "all-knowing" object, which maintains most of the information about the entire program and provides most of the methods for manipulating this data. Because this object holds so much data and requires so many methods, its role in the program becomes God-like (all-encompassing). Instead of program objects communicating amongst themselves directly, the other objects within the program rely on the God object for most of their information and interaction. Since the God object is referenced by so much of the other code, maintenance becomes more difficult than it otherwise would in a more evenly divided programming design. venerdì 13 novembre 2009
  94. 94. www,mondora.com Object cesspool When writing an object pool, the programmer has to be careful to make sure the state of the objects returned to the pool is reset back to a sensible state for the next use of the object. design anti patterns If this is not observed, the object will often be in some state that was unexpected by the client program and may cause the client program to fail. The pool is responsible for resetting the objects, not the clients. Object pools full of objects with dangerously stale state are sometimes called object cesspools. Inadequate resetting of objects may also cause an information leak. If an object contains confidential data (e.g. a user's credit card numbers) that isn't cleared before the object is passed to a new client, a malicious or buggy client may disclose the data to an unauthorized party. If the pool is used by multiple threads, it may need means to prevent parallel threads from grabbing and trying to reuse the same object in parallel. This is not necessary if the pooled objects are immutable or otherwise thread-safe. venerdì 13 novembre 2009
  95. 95. www,mondora.com Object orgy describing a common failure in object-oriented design or programming. design anti patterns In an object orgy, objects are insufficiently encapsulated, allowing unrestricted access to their internals, usually leading to unmaintainable complexity. Encapsulation may be weakened by declaring internal members public or by providing free access to data via public getter/setter methods. venerdì 13 novembre 2009
  96. 96. www,mondora.com Object orgy Unrestricted access makes it hard for the reader to reason about the behavior of an object. This is because direct access to its consequences internal state means any other part of the system can manipulate it, increasing the amount of code to be examined, and opening the door to future abuse. As a consequence of the difficulty of reasoning, “design by contract” is effectively impossible. If much code takes advantage of the lack of encapsulation, the result is a scarcely maintainable maze of interactions, commonly known as a rat's nest, ravioli code or spaghetti code. The original design is obscured by the excessively broad interfaces to objects. The broad interfaces make it harder to re-implement a class without disturbing the rest of the system. venerdì 13 novembre 2009
  97. 97. www,mondora.com Poltergeist is a short-lived, typically stateless object used to perform initialization or to invoke methods in another, design anti patterns more permanent class. “As a poltergeist appear and disappear mysteriously, so does this short lived object. As a consequence the code is more difficult to maintain and there is unnecessary resource waste. The typical cause for this antipattern is poor object design." A poltergeist can often be identified by its name; they are often called "manager_", "controller_", "start_process" venerdì 13 novembre 2009
  98. 98. www,mondora.com Sequential coupling refers to a class that requires its methods to be called in a particular sequence. design anti patterns Methods whose name starts with Init, Begin, Start, etc. may indicate the existence of sequential coupling. Using a car as an analogy, if the user steps on the gas without first starting the engine, the car does not crash, fail, or throw an exception - it simply fails to accelerate. venerdì 13 novembre 2009
  99. 99. www,mondora.com Yo-yo problem when a programmer has to read and understand a program whose inheritance graph is so long and design anti patterns complicated that the programmer has to keep flipping between many different class definitions in order to follow the control flow of the program. It often happens in object-oriented programming. The term comes from comparing the bouncing attention of the programmer to the up-down movement of a toy yo-yo. Most practices of object-oriented programming recommend keeping the inheritance graph as shallow as possible, in part to avoid this problem. The use of composition instead of inheritance is also strongly preferred, although this still requires that a programmer keep multiple class definitions in mind at once. venerdì 13 novembre 2009
  100. 100. www,mondora.com More Antipatterns Methodological anti-patterns copy and paste programmers golden hammer Organizational anti-patterns analysis paralysis Vendor lock-in Software design anti-patterns Big ball of mud Interface bloat extra November 2009, Loquendo, Turin venerdì 13 novembre 2009
  101. 101. www,mondora.com Copy and Paste programmer pejorative term to describe highly repetitive computer programming code apparently produced by copy and Methodological paste operations. frequently symptomatic of a lack of programming competence In certain contexts it has legitimate value, if used with care. One of the most harmful forms of copy-and-paste programming occurs in code that performs a repetitive task. Each repetition is copied from above and pasted in again, with minor modifications. venerdì 13 novembre 2009
  102. 102. www,mondora.com Copy and Paste programmer • The result risks being a disjointed clash of styles, and may have superfluous code that tackles problems for which solutions are no longer required. • Bugs can also easily be introduced by assumptions and design choices made in the separate sources that no longer apply when effects placed in a new environment. • If changes are needed, time is wasted hunting for all the duplicate locations • An object oriented approach would abstract the algorithm into a reusable encapsulated class. • For repetitive tasks, the copy and paste approach often leads to large methods. The general rule of thumb applicable to this case is "don't repeat yourself" venerdì 13 novembre 2009
  103. 103. www,mondora.com Golden hammer is an over-reliance on a familiar tool; Methodological as Abraham Maslow said in 1962, "When the only tool you have is a hammer, it is tempting to treat everything as if it were a nail." The concept is also known as the law of the instrument, Maslow's hammer. venerdì 13 novembre 2009
  104. 104. www,mondora.com Analisys paralisys describes a situation where the opportunity cost of decision analysis exceeds the Organizational benefits that could be gained by enacting some decision, or an informal or non-deterministic situation where the sheer quantity of analysis overwhelms the decision making process itself, thus preventing a decision. venerdì 13 novembre 2009
  105. 105. www,mondora.com Vendor Lock-in also known as proprietary lock-in, or customer lock- in Organizational • makes a customer dependent on a vendor for products and services, • unable to use another vendor without substantial switching costs. Example: SIM locking may be considered a vendor lock-in tactic as phones purchased from the vendor will work with SIM cards only from the same network. venerdì 13 novembre 2009
  106. 106. www,mondora.com Big ball of mud The term was popularized in Brian Foote and Joseph Yoder's 1999 paper of the same name, which defines the term thus: Software design A Big Ball of Mud is a haphazardly structured, sprawling, sloppy, duct-tape-and-baling-wire, spaghetti-code jungle. These systems show unmistakable signs of unregulated growth, and repeated, expedient repair. Information is shared promiscuously among distant elements of the system, often to the point where nearly all the important information becomes global or duplicated. The overall structure of the system may never have been well defined. If it was, it may have eroded beyond recognition.... "Big ball of mud" systems have usually been developed over a long period of time, with different individuals working on various pieces and parts. venerdì 13 novembre 2009
  107. 107. www,mondora.com Interface bloat is a term used to describe interfaces that try to incorporate all possible operations on some data into Software design an interface, only to find that most of the objects cannot perform the given operations. One might consider using visitor pattern, Adapter Pattern, or interface separation instead. also called fat interfaces by Bjarne Stroustrup and Refused Bequests by Martin Fowler venerdì 13 novembre 2009
  108. 108. www,mondora.com Pattern oriented software architecture A system of Patterns Frank Buschmann Peter Sommerland Regine Meunier Michael Stal Hans Rohnert November 2009, Loquendo, Turin venerdì 13 novembre 2009
  109. 109. www,mondora.com Intent Architectural patterns express fundamental structural organization schemas for software systems. They provide a set of predefined subsystems, specify p.o.s.a. their responsibilities, and include rules and guidelines for organizing the relationships between them. Architectural patterns represent the highest-level patterns in our pattern system. They help you to specify the fundamental structure of an application. venerdì 13 novembre 2009
  110. 110. www,mondora.com Architectural patterns Layers structure applications that Model-View-Controller can be decomposed into groups of divides an interactive application into subtasks in which each group of three components. subtasks is at a particular level of abstraction. Presentation- Pipes and Filters provides a Abstraction -Control p.o.s.a. defines a structure for interactive structure for systems that process a software systems in the form of a stream of data. hierarchy of cooperating agents Blackboard is useful for Microkernel applies to software problems for which non deterministic systems that must be able to adapt solution strategies are known. to changing system requirements. Broker structure distributed Reflection a mechanism for software systems with decoupled changing structure and behavior of components that interact by remote software systems dynamically. service invocations. November 2009, Loquendo, Turin venerdì 13 novembre 2009
  111. 111. www,mondora.com Model-View-Controller The Model-View-Controller architectural pattern (MVC) divides an interactive application into three components. The model contains the core functionality and data. Views display information to p.o.s.a. the user. Controllers handle user input. Views and controllers together comprise the user interface. A change- propagation mechanism ensures consistency between the user interface and the model. The pattern isolates business logic from input and presentation, permitting independent development, testing and maintenance of each. venerdì 13 novembre 2009
  112. 112. www,mondora.com Model It is the domain-specific representation of the data on which the application operates. Domain logic adds meaning to raw data (for example, calculating whether today is the user's birthday, or the totals, taxes, and shipping charges for shopping cart items). When mvc a model changes its state, it notifies its associated views so they can refresh. Many applications use a persistent storage mechanism (such as a database) to store data. MVC does not specifically mention the data access layer because it is understood to be underneath or encapsulated by the model. Models are not data access objects although in very simple apps, with little domain logic, there is no real distinction to be made. venerdì 13 novembre 2009
  113. 113. www,mondora.com View-Controller • View Renders the model into a form suitable for interaction, typically a user interface element. Multiple views can exist for a single model for mvc different purposes. • Controller Receives input and initiates a response by making calls on model objects. venerdì 13 novembre 2009
  114. 114. www,mondora.com Structure client mvc high level Model-View-Controller concept. Note: The solid line represents a direct a s s o c i a t i o n , t h e d a s h e d a n i n d i re c t association via an observer venerdì 13 novembre 2009
  115. 115. www,mondora.com Structure mvc Sun’s view venerdì 13 novembre 2009
  116. 116. www,mondora.com Structure official mvc static class diagram venerdì 13 novembre 2009
  117. 117. www,mondora.com Sequence sequence diagram official mvc venerdì 13 novembre 2009
  118. 118. www,mondora.com Homework Exercise your design pattern comprehension November 2009, Loquendo, Turin venerdì 13 novembre 2009
  119. 119. www,mondora.com Object Oriented Sanity Check term definition? match definition Protecting an object’s internal state and implementation 1 polymorphism through a public interface. 2 encapsulation Reuse of functionality by referencing another object. composition over A principle that encourages reuse through reference variables 3 inheritance instead of the extends keyword. program to an interface, Ability for variables to refer to generalized objects and to 4 not an implementation determine the destination of a method invocation at runtime. The measure of how much classes within a system are 5 composition dependent on each other. The measure of how much a component or class supports a 6 coupling singular purpose within a system. Explicitly separating the interface of a class from the definition 7 cohesion of that class. venerdì 13 novembre 2009
  120. 120. www,mondora.com Hotel application Exercise in creating an application in Hotel system domain object model: • reservation context • checkin and checkout • billing • integration venerdì 13 novembre 2009
  121. 121. www,mondora.com Reservation Subsystem identify and design 1 identify the object-oriented design principle violations 2 draw a class diagram that improves the design on object-oriented design principles. venerdì 13 novembre 2009
  122. 122. www,mondora.com Hotel application design an hotel application that includes check-out and check-in. Evolve and Redesign This system should do the following: •When a guest checks out, the hotel system disable the phone, and put the room in green mode. Adjust the thermostat to save energy, turn off the electricity to the room, ... •When a guest checks in, the system should wake up the room from the green mode. Activate the phone, set the thermostat to 20 degrees Celsius, turn on the electricity to the room, and set the digital clock to the current time, turn on the Television with a welcome movie. This system enable these activities to occur whenever a guest checks in or checks out of the hotel. Note that the room is network-enabled and instrumented through 3rd party lib technology application. Non functional requirements : • check-in or check-out processes must easily added or removed according to changes in the business requirements without rewriting/redeploying the software infrastructure. venerdì 13 novembre 2009
  123. 123. www,mondora.com Hotel application • The current hotel reservation system allows guests to search for room availability and make reservations. Evolve and Redesign • Hotel chains have merged. • They each have their own database systems. Each database requires different code to access it. • Each employee inform all others Hotels when a VIP checkin and checkout • Each guest checkin and checkout must be logged to a journaling system • With a special checkin authorization, guest are accepted “for free” • Quality assurance officer, should can inspect each Hotel, room and facility • Calculate the room bill for each guest upon check-out. This subsystem must enable to use for each guest, a custom billing calculation and include the following: • The base calculation for the actual room rate charge • The room phone bill venerdì 13 novembre 2009
  124. 124. www,mondora.com References Design Pattern, Elements of Reusable Object-Oriented Software - Gamma, Helm, Johnson, Vlissides Pattern-oriented software architecture, a system of Patterns - Buschmann, Meunier, Rohnert, Sommerlad, Stal http://en.wikipedia.org/ http://hillside.net/patterns AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis, Brown, Malveau, McCormick, Mowbray Designing Enterprise Applications with the J2EE Platform, Second Edition - Inderjeet Singh, Beth Stearns, Mark Johnson, and the Enterprise Team ©®™ November 2009, Loquendo, Turin venerdì 13 novembre 2009
  125. 125. www,mondora.com Thank you! “We hope you think differently.” GOF, Design Patterns michele.mondora@mondora.com skype:mmondora twitter:mmondora andrea.tibi@mondora.com November 2009, Loquendo, Turin venerdì 13 novembre 2009

×