Design Patterns

Bridge Pattern
  • Abstraction and implementation are not bound at compile time
  • Uses composition over inheritance.
  • Abstractions and implementations should be changed independently
  • Abstraction not tied to the Implementation: The abstraction interface (or abstract class with most of the behavior abstract) would not know/contain the implementation interface reference
  • The intent is to completely decouple the Abstraction from the Implementation

What is an abstraction?
It’s a generalized way of looking at something that makes it so you don’t have to know the details of how that thing is implemented.

A car steering wheel is an abstraction on top of a car. The car steering wheel abstracts away what is really going on to make a car change direction.



https://simpleprogrammer.com/design-patterns-simplified-the-bridge-pattern/
https://springframework.guru/gang-of-four-design-patterns/bridge-pattern/


Strategy Pattern

  • Define a separate (strategy) object that encapsulates an algorithm. That is, define an interface (Strategy) for performing an algorithm, and define classes that implement the interface (algorithm) in different ways.
  • A class delegates an algorithm to a strategy object at run-time instead of implementing an algorithm directly (that is, instead of committing to an algorithm at compile-time).
  • Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it.
This makes a class independent of a particular algorithm (how an algorithm is implemented).



Decorator Pattern
  • Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
  • Client-specified embellishment of a core object by recursively wrapping it.
  • Wrapping a gift, putting it in a box, and wrapping the box.




Decorator vs Inheritance
The decorator pattern can be used to make it possible to extend (decorate) the functionality of a certain object at runtime.
The decorator pattern is an alternative to subclassing. Subclassing adds behavior at compile time, and the change affects all instances of the original class; decorating can provide new behavior at runtime for individual objects.

Suppose you have a TextView class. Then in some place, you want a scrolled text view, so you subclass TextView and create ScrolledTextView class. And in some other place, you want a border around text view. So you subclass again and create BorderedTextView. Well, now in some place you want border and scroll both. None of the previous two subclasses have both capabilities. So you need to create a 3rd one. When creating a ScrolledBorderedTextView you are actually duplicating the effort. You don't need this class if you have any way to compose the capability of the previous two. Well, things can go worse and these may lead to an unnecessary class explosion.
Adapter

The adapter is used when you're trying to unify the interfaces of some incompatible classes that already exist. The Adapter functions as a kind of translator to implementations that could be considered legacy.




Singleton vs Static

  • Singleton objects are stored in Heap, but static objects are stored in the stack
  • We can clone (if the designer did not disallow it) the singleton object, but we can not clone the static class object
  • Singleton classes follow the OOP (object-oriented principles), static classes do not
  • We can implement an interface with a Singleton class, but a class's static methods (or e.g. a C# static class) cannot


Visitor Pattern

The visitor pattern is useful when you want to process a data structure containing different kinds of objects, and you want to perform a specific operation on each of them, depending on its type.

The important point is that this effectively allows us to define new methods for all classes in some hierarchy without editing those classes. This is useful in two cases:
  • We cannot edit the original hierarchy because it's some external library.
  • We need many unrelated operations and don't want to put different operations into the same class. This is indicated by the Single Responsibility Principle.
The drawback of the Visitor Pattern is that we have now lost the ability to add new Animalsubclasses. We would have to add them to the interfaceAnimalVisitor as well, and that would break all existing visitors.

Mediator

Mediator,   multiple elements trying to communicate over a single broker/hub to reduce communication noise and each object are equally important in terms of having the ability to signal a state change. For example, think of multiple aircraft approaching an airport. Each should communicate over the pylon (mediator) rather than communicating with each other. (Think of 1000 aircraft communicating with each other when landing).

With the mediator pattern, communication between objects is encapsulated within a mediator object. Objects no longer communicate directly with each other, but instead, communicate through the mediator. This reduces the dependencies between communicating objects, thereby reducing coupling.



Facade Pattern

Facade links to various existing classes of a subsystem to add some typical functionality that simplifies the use of the subsystem.
  • To make a complex subsystem easier to use, a simple interface should be provided for a set of interfaces in the subsystem.
  • The dependencies on a subsystem should be minimized.


Facade vs Mediator

  • Facade is like a gateway and collects information or interacts with various sub-systems and pass the result back to client.  It is Unidirectional ; client and other sub-systems are separated by facade. 

  • Where as Mediator sits at the center of all sub-systems , sub-systems inform specific information to mediator and mediator co-oridinates other sub-systems. It is Multidirectional ; Mediator is surrounded by all sub-systems. 

Observer vs Mediator

Observer is used to broadcasting a state change of a particular object, from the object itself. So the change happens in the central object that is also responsible for signalling it. However, in Mediator, the state change can happen in any object but it's broadcasted by a mediator. So there's a difference in the flow.

State Pattern
  • An object should change its behavior when its internal state changes.
  • State-specific behavior should be defined independently. That is, new states should be added and the behavior of existing states should be changed independently.
  • Define separate (state) objects that encapsulate state-specific behavior for each state.



Command Pattern

Encapsulate a request in an object

  • allows the parameterization of clients with different requests
  • allows saving the requests in a queue


The classes participating in the pattern are:

  • Command - declares an interface for executing an operation;
  • ConcreteCommand - extends the Command interface, implementing the Execute method by invoking the corresponding operations on Receiver. It defines a link between the Receiver and the action.
  • Client - creates a ConcreteCommand object and sets its receiver;
  • Invoker - asks the command to carry out the request;
  • Receiver - knows how to perform the operations;



http://www.bogotobogo.com/DesignPatterns/command.php

Builder Pattern

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

When using Builder Pattern, there are four collaborators:


  • Director - it says to Abstract Builder what are the construction steps (In case of tree structure, steps are: create root, add child, ...)
  • Abstract Builder - is abstraction used by Director.
  • Concrete Builder - is concrete implementation of Abstract Builder (Could be XMLBuilder, ObjectBuilder,...)
  • Client - says to Director to initiate the construction.



Factory Method Pattern

Define an interface for creating an object, but let subclasses decide which class to instantiate. The Factory method lets a class defer instantiation it uses to subclasses.

    The classes and objects participating in this pattern are:
  • Product  
    • defines the interface of objects the factory method creates
  • ConcreteProduct  
    • implements the Product interface
  • Creator  
    • declares the factory method, which returns an object of type Product. Creator may also define a default implementation of the factory method that returns a default ConcreteProduct object. 
    • may call the factory method to create a Product object. 
  • ConcreteCreator  
    • overrides the factory method to return an instance of a ConcreteProduct.

https://sourcemaking.com/design_patterns/factory_method/java/1


Abstract Factory Pattern

We need an abstract factory when different polymorphic classes have different instantiation procedure.

The objects participating in this pattern are: 
  • AbstractFactory 
    • declares an interface for creating products
  • ConcreteFactory 
    • a factory object that 'manufactures' new products
    • the create() method returns new products
  • Products
    • the product instances being created by the factory
  • AbstractProduct
    • declares an interface for the products that are being created


Factory Method vs Abstract Factory

  • Factory Method is used to create one product only but Abstract Factory is about creating families of related or dependent products. 
  • With the Abstract Factory pattern, a class delegates the responsibility of object instantiation to another object via composition whereas the Factory Method pattern uses inheritance and relies on a subclass to handle the desired object instantiation.
  • Abstract Factory is one level higher in abstraction than Factory Method. Factory Method abstracts the way objects are created, while Abstract Factory also abstracts the way factories are created which in turn abstracts the way objects are created.
  • The most important point to grasp here is that the abstract factory is injected into the client. This is why we say that Abstract Factory is implemented by Composition.
  • The most important point to grasp here is that the ConcreteCreator is the client. In other words, the client is a subclass whose parent defines the factoryMethod(). This is why we say that Factory Method is implemented by Inheritance
  • And finally, the third point to note is that the Creator (parent) class invokes its own factoryMethod(). If we remove anOperation() from the parent class, leaving only a single method behind, it is no longer the Factory Method pattern. Factory Method cannot be implemented with less than two methods in the parent class; and one must invoke the other.
https://stackoverflow.com/questions/5739611/what-are-the-differences-between-abstract-factory-and-factory-design-patterns

Template Method

the AbstractClass defines a templateMethod() operation that defines the skeleton (template) of a behavior by
  • implementing the invariant parts of the behavior and
  • sending to self the messages  primitive1() and primitive2() , which, because they are implemented in SubClass1 , allow that subclass to provide a variant implementation of those parts of the algorithm.

Flyweight pattern


A flyweight is an object that minimizes memory usage by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory. Often some parts of the object state can be shared, and it is common practice to hold them in external data structures and pass them to the objects temporarily when they are used.



Visitor



Represent an operation to be performed on elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

Visitor implements "double dispatch". OO messages routinely manifest "single dispatch" - the operation that is executed depends on: the name of the request, and the type of the receiver. In "double dispatch", the operation executed depends on: the name of the request, and the type of TWO receivers (the type of the Visitor and the type of the element it visits).

interface Element {
    void accept(Visitor v);
}

class FOO implements Element {
    public void accept(Visitor v) {
        v.visit(this);
    }

    public String getFOO() {
        return "FOO";
    }
}

class BAR implements Element {
    public void   accept( Visitor v ) {
        v.visit( this );
    }

    public String getBAR() {
        return "BAR";
    }
}

class BAZ implements Element {
    public void accept(Visitor v) {
        v.visit(this);
    }

    public String getBAZ() {
        return "BAZ";
    }
}

interface Visitor {
    void visit(FOO foo);
    void visit(BAR bar);
    void visit(BAZ baz);
}

class UpVisitor implements Visitor {
    public void visit(FOO foo) {
        System.out.println("do Up on " + foo.getFOO());
    }

    public void visit(BAR bar) {
        System.out.println("do Up on " + bar.getBAR());
    }

    public void visit(BAZ baz) {
        System.out.println( "do Up on " + baz.getBAZ() );
    }
}

class DownVisitor implements Visitor {
    public void visit(FOO foo) {
        System.out.println("do Down on " + foo.getFOO());
    }

    public void visit(BAR bar) {
        System.out.println("do Down on " + bar.getBAR());
    }

    public void visit(BAZ baz ) {
        System.out.println("do Down on " + baz.getBAZ());
    }
}

public class VisitorDemo {
    public static void main( String[] args ) {
        Element[] list = {new FOO(), new BAR(), new BAZ()};
        UpVisitor up = new UpVisitor();
        DownVisitor down = new DownVisitor();
        for (Element element : list) {
            element.accept(up);
        }
        for (Element element : list) {
            element.accept(down);
        }
    }
}

Repository 

A repository is a specialisation of the Facade pattern which is structural. When  users launch an app, they expect the app to show data quickly. You can achieve this goal by implementing offline caching. Offline caching means that your app saves data fetched from the network on the device's local storage, resulting in faster access.

Because the app will be able to get data from the network as well as keep an offline cache of previously downloaded results, you'll need a way for your app to organize these multiple sources of data. You'll do this by implementing a repository class, which will serve as a single source of truth for the app's data, and abstract the source of the data (network, cache, etc.) out of the view model.


Data Access Object (DAO) pattern is a structural pattern that allows us to isolate the application/business layer from the persistence layer (usually a relational database but could be any other persistence mechanism) using an abstract API.



Comments

Popular posts from this blog

Thread & Locks

Opengl-es Buffer

Kernel Startup