Skip to content

kabragaurav/gof-design-patterns

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Design Patterns with Java (LLD)

by Gaurav Kabra

Read this README as a webpage here

Creational

1. Singleton

Logger, DB Connector Disadv:

  • Multi threaded env: access must be thread safe
  • Dependency inversion regards this as an anti-pattern since use of private and static methods

2. Factory

Singleton, in some sense, is also a factory pattern but returns only one type of object.

Also, in factory pattern, clients do not even know the name of class for which object is to be generated. They only know Factory name.

E.g. DB Connector Factory using getConnection method, depending on DB driver. E.g. Oracle driver:

Connection conn = DriverManager.getConnection("url", "uname", "pwd");

Now different DB vendors have different URL formats.

Different vendors implement the JDBC interfaces.

3. Abstract Factory

Factory for factories. E.g. a factory that returns Maruti factory or Skoda factory:

4. Prototype

For cloning - shallow or deep.

In Java, unlike Python, we have to implement our own shallow/deep copy methods.

Structural

1. Adapter

When we do not have src code, so no modification is possible.

2. Proxy

Unlike Adapter, which does "conversion", in Proxy pattern, one object represents another.

Both RealSubject and Proxy must have same method signatures.

Useful in caching responses (optimizations), where first time original class fetches from DB but then proxy caches the response.

RMI

(Now deprecated due to RPC)

A method can call only method within same JVM. But RMI allows it to invoke method in another JVM, may be on another OS.

Communication happens via RMI interface (proprietary to Java) unlike HTTPS. Stub and Skeleton are generated by RMI. Stub passes information like method to be invoked and parameters. Skeleton executes using this info and returns results.

3. Facade

E.g. customer service can answer all queries, we reach to warden regarding any hostel query etc.

4. Decorator

If classA has features f1 and f2 and a classB has features f13 and f4 and we just want features f1 and f4.

It helps avoid inheritance.

Base class will be same to have common behaviour.

Unlike inheritance, decorator is plug-n-play.

Behavioral

1. Strategy

With composition, it's easy to change behavior on the fly with Dependency Injection / Setters. Inheritance is more rigid as most languages do not allow you to derive from more than one type.

Does TypeB want to expose the complete interface (all public methods no less) of TypeA? Indicates Inheritance.

Does TypeB want only some/part of the behavior exposed by TypeA? Indicates need for Composition.

2. Chain of Responsibility

When enter corporate SEZ, multiple layer of security. Similarly in govt work, file moves through hierarchy/layers.

Useful in performing incremental operations (pipeline), doing auth then logging and so on (Servlet FilterChain).

If 100 cannot handle 2140, it delegates to 50 and so on:

3. Observer

1-N dependency, event handling and decoupling

4. State

State vs Chain of Responsibility
  • In State, they act on same object, so that they form finite state automaton
  • In CoR, each class gets different objects from previous class that does processing and then passes

5. Command

We don't need if we use Reflection, but that is generally an anti-pattern.

On a complex operation on DB, invoker should not know what is to execute. Whatever instructions you set as a command, it should execute.


Resources

https://sourcemaking.com

About

Gang-of-4 Design Patterns

Topics

Resources

Stars

Watchers

Forks

Languages