Design patterns

Object oriented principles

  • Encapsulate what varies.
  • Favor composition over inheritance.
  • Program to interface, not to implemenation.
  • Strive for loosely coupled designs between objects that interact.
  • Class should be open for extension but closed for modification.
  • Depend on abstractions. Do not depend on concrete classes.

Object oriented design principles

Encapsulates What Varies

Encapsulates what varies so it won’t affect the rest of the code if it changes

  • Design Pattern. Strategy pattern.
  • Meaning. If there are some aspects of the code that could change with every new requirements then it is a behavior that need to be pulled out and separated from stuff that doesn’t change.
  • Key points.
    • Identify the aspects of the application that vary and separate them from what stays the same.
    • Take parts that vary and encapsulate them, so that later you can later or extend the parts that vary without affecting those that don’t.
    • Base of all design patterns. All patterns provides a way to let some part of a system vary independently of all other parts.

Program to an Interface not to an Implementation

Encapsulates what varies so it won’t affect the rest of the code if it changes

  • Design Pattern. Strategy pattern.
  • Meaning. Program to an interface means program to a supertype usually an abstract class or an interface so that the class declaring them doesn’t have to know about the actual object types.
  • Key points.
    • A behavior, for instance, can be represented by an interface so that the actual implementation of the behavior wont be locked by a class or subclass.
    • Behavior are no longer hidden into a class but can be reused and new behaviors can be added without modifying any of the existing classes.
    • Behavior are no longer hidden into a class but can be reused and new behaviors can be added without modifying any of the existing classes.

Favor Composition Over Inheritance

Getting behavior by being composed is better than inherit them.

  • Design Pattern. Strategy pattern.
  • Key points.
    • Composition gives more flexibility.
    • Allow to encapsulate family of algorithms into their own set of classes.
    • Allow to change behavior at runtime.

The Open-Closed Principle

Classes should be opened for extension but closed for modification.

  • Design Pattern. Decorator pattern.
  • Meaning. It allows code to be extended without direct modification.
  • Key points.
    • introduce new levels of abstraction which adds complexity to the code
    • concentrate on those area are likely to change in your design
    • do not apply the open-close principle everywhere, it is unnecessary, leads to complexity and hard to understand code

Loosely Coupled Design Principle

Strive for loosely coupled designs between objects that interact.

  • Design Pattern. Obsever pattern.
  • Meaning. Loosely coupled designs allow to build flexible systems minimizing the interdependency between objects.
  • Loosely coupling power.
    • An observer has to implement an interface, can be added or removed at any time.
    • The Subject just deliver notifications to any objects implementing the Observer interface.
    • Any object can get notifications, it has just to implement the Observer interface.
    • A Subject and an Observer can change independenlty as long as they respect the respective interfaces.

The Dependency Inversion Principle

Depend upon abstractions, do not depend upon concrete classes.

  • Design Pattern. Factory Method pattern is one of the possible way to respect this principle.
  • Meaning.
    • Start from the top, high-level components and go down to the bottom, the concrete classes.
    • Look at how classes are linked and the direction of the arrows when the code depends on concrete implementation using new and compare with arrows when factory method is involved.
    • The factory method returns a concrete type implementing a given interface and the client is just waiting for something respecting that interface without considering a specific type.
    • The return in the factory method reverts the direction of the creation arrows.
    • Now both low-level (concrete cars) and high-level (car manufacturers) components depend on the abstraction (the abstract car).
    • Invertion. Start at Pizzas level and see what you can abstract and then go back to PizzaStore.
  • Key points.
    • Similar to “Program to an interface, not an implementation” but stronger about abstraction.
    • High-level and low-level components depend only on the abstraction, that is Pizza.
    • PizzaStore is the high level component and depends on concrete pizza classes.
    • Pizzas are the low-level components.
  • Guideline to follow the principle.
    • No variable should hold a reference to a concrete class. Do not use new but a factory to get around that.
    • No class should derive from a concrete class. Deriving from a concrete class implies a dependency on that concrete class.
      • Derive instead from abstraction or interface.
    • No method should override an implemented method of any of its base classes. Overriding a method means that the base class was not really an abstraction.
      • Methods in the base class are meant to be shared among subclasses.

The Hollywood Principle

  • Definition. Don’t call us, we’ll call you.
  • Design Pattern. Template Method pattern.
  • Meaning. This principle allows low-level components to hook themselves into a system, but the high-level components determine when they are needed and how. The high-level components give the low-level components a “don’t call us, se’ll call you” treatment.
    • The abstract class is the high-level component, it has the control over the algorithm.
      • Abstract class calls the subclasses only when an implementation of a method is needed.
      • Client will depend on the class abstraction rather than on concrete class reducing the dependencies in the system.
    • Subclasses are the low-level components used to provide implementation details.
    • A low-level component never calls directly a high-level component, it can be hooked into the computation without creating dependencies between low-level and high-level layers.
    • High-level components reserve the low-level components a “don’t call us, we’ll call you” treatment.
  • Key points.
    • Technique for creating designs that allow low-level structure to interoperate while preventing other classes from becoming too dependent on them
    • Avoid explicit circular dependencies between the low-level components and the high-level ones
  • Advantages. Decoupling, lower-level components can be hooked into the computation without creating dependencies between the lower-level components and the higher-level layers.

Principle of Least Knowledge (aka Law of Demeter)

  • Definition. Talk only to your immediate friends.
  • Design Pattern.
  • Meaning. It reduces the interaction between objects to just a few close friends.
  • Key points. Invoke only methods that belong to
    • the object itself
    • objects passed in as a parameter to the method
    • any object the method creates or instantiates
    • any components of the object (HAS-A relationship)
  • Advantages.
    • For any object be careful of the number of classes it interacts with and also how it interacts.
    • Prevent the creation of a large number of classes coupled together (changes in one part cascade to the others).
    • Many dependencies between many classes the system will be fragile:
      • difficult to maintain
      • complex for others to understand.
  • Disadvantages.
    • More wrapper classes being written to handle method calls to other components:
      • increase complexity, development time and runtime performance