├── README.md
└── patterns
├── behavioral-patterns
├── Chain-of-Responsibility
│ ├── README.md
│ └── src
│ │ ├── Account.java
│ │ ├── Bank.java
│ │ ├── Bitcoin.java
│ │ └── Paypal.java
├── Command
│ ├── README.md
│ └── src
│ │ ├── Bulb.java
│ │ ├── Command.java
│ │ ├── RemoteController.java
│ │ ├── TurnOff.java
│ │ └── TurnOn.java
├── Observer
│ ├── README.Md
│ └── src
│ │ ├── Agency.java
│ │ ├── Channel.java
│ │ ├── NewsAgency.java
│ │ └── NewsChannel.java
├── README.md
├── State
│ ├── README.md
│ └── src
│ │ ├── Default.java
│ │ ├── LowerCase.java
│ │ ├── TextEditor.java
│ │ ├── UpperCase.java
│ │ └── WritingState.java
└── Strategy
│ ├── README.md
│ └── src
│ ├── BubbleStrategySort.java
│ ├── QuickSortStrategy.java
│ ├── Sorter.java
│ └── StrategySort.java
├── creational-patterns
├── Abstract-Factory
│ └── README.md
├── Builder
│ ├── README.md
│ └── src
│ │ └── User.java
├── Factory-Method
│ ├── README.md
│ └── src
│ │ ├── CommunityExecutive.java
│ │ ├── Developer.java
│ │ ├── DevelopmentManager.java
│ │ ├── HiringManager.java
│ │ ├── Interviewer.java
│ │ └── MarketingManager.java
├── Prototype
│ ├── README.md
│ └── src
│ │ ├── CloneFactory.java
│ │ ├── Dog.java
│ │ ├── Prototype.java
│ │ └── Sheep.java
├── README.md
└── Singleton
│ ├── README.md
│ └── src
│ └── President.java
├── images
├── abstract-factory.png
├── adapter-example.png
├── adapter.png
├── bridge-schema.png
├── bridge.png
├── builder.png
├── chain-of-responsibility-example.png
├── chain-of-responsibility.png
├── command-example.png
├── command.png
├── composite-example.png
├── composite.png
├── decorator-example.png
├── decorator.png
├── facade.png
├── factory-method-example.png
├── factory-method.png
├── observer-example.png
├── observer.png
├── prototype-example.png
├── prototype.png
├── proxy.png
├── singleton-example.png
├── singleton.png
├── state-example.png
├── state.png
├── strategy-example.png
└── strategy.png
└── structural-patterns
├── Adapter
├── README.md
└── src
│ ├── EnemyAttacker.java
│ ├── EnemyRobot.java
│ └── EnemyRobotAdapter.java
├── Bridge
├── README.md
└── src
│ ├── About.java
│ ├── Careers.java
│ ├── DarkTheme.java
│ ├── LightTheme.java
│ ├── Theme.java
│ └── WebPage.java
├── Composite
├── README.md
└── src
│ ├── Designer.java
│ ├── Developer.java
│ ├── Employee.java
│ └── Organization.java
├── Decorator
├── README.md
└── src
│ ├── AirConditioner.java
│ ├── BasicCar.java
│ ├── Car.java
│ ├── CarDecorator.java
│ └── SpeedRegulator.java
├── Facade
└── README.md
├── Flyweight
└── README.md
├── Proxy
└── README.md
└── README.md
/README.md:
--------------------------------------------------------------------------------
1 | # 📝 Design-Pattern-Java-notes
2 |
3 | ## Introduction : what is design patterns ?
4 |
5 | > In software engineering, a software design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design. -Wikipedia
6 |
7 | A Design Pattern is not a code that is ready to be used in your application, but it is a model that we can use to solve a problem,Good design patterns help make your software more flexible and reusable , They can be applied to any laguage that supports object-orientation.
8 |
9 | ## Gang of four (GOF)
10 |
11 | In the year of 1995, four developers, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, also known as ‘Gang of Four’ (GoF), published the book ‘Design Patterns: Elements of Reusable Object-Oriented Software’, and they introduced the concept of patterns, introducing 23 patterns of design. Those patterns from Gang of Four (GoF), are generally considered the foundation for all other patterns, and they are categorized into three groups:
12 |
13 | - [Creational](./patterns/creational-patterns/README.md) — provide object creation mechanisms that increase flexibility and reuse of existing code.
14 | - [Structural](./patterns/structural-patterns/README.md)— explain how to assemble objects and classes into larger structures, while keeping the structures flexible and efficient.
15 | - [Behavioral](./patterns/behavioral-patterns/README.md) — take care of effective communication and the assignment of responsibilities between objects.
16 |
17 | ## The elements of a design pattern
18 |
19 | The four essential elements of a design patter :
20 |
21 | - A name — describe a design problem, the solution and the consequences.
22 | - The problem — The context to apply the pattern.
23 | - The solution — The elements that make up the design, the relationships, the responsibilities and collaborations.
24 | - The consequences — The results of applying the pattern.
25 |
26 | ## The 23 patterns from the book
27 |
28 | - [Creational Pattern](./patterns/creational-patterns/README.md)
29 | - [Abstract Factory](./patterns/creational-patterns/Abstract-Factory) — Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
30 | - [Builder](./patterns/creational-patterns/Builder) — Separate the construction of a complex object from its representation so that the same construction process can create different representations.
31 | - [Factory Method](./patterns/creational-patterns/Factory-Method) — Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
32 | - [Prototype](./patterns/creational-patterns/Prototype) — Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
33 | - [Singleton](./patterns/creational-patterns/Singleton) — Ensure a class only has one instance, and provide a global point of access to it.
34 | - [Structural Pattern](./patterns/structural-patterns/README.md)
35 | - [Adapter](./patterns/structural-patterns/Adapter) — Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.
36 | - [Bridge](./patterns/structural-patterns/Bridge) — Decouple an abstraction from its implementation so that the two can vary independently.
37 | - [Composite](./patterns/structural-patterns/Composite) — Compose objects into tree structures to represent part-wholehierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
38 | - [Decorator](./patterns/structural-patterns/Decorator) — Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
39 | - [Facade](./patterns/structural-patterns/Facade) — Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
40 | - [Flyweight](./patterns/structural-patterns/Flyweight) — Use sharing to support large numbers of fine-grained objects
41 | efficiently.
42 | - [Proxy](./patterns/structural-patterns/Proxy) — Provide a surrogate or placeholder for another object to control access to it.
43 | - [Behavioral Pattern](./patterns/behavioral-patterns/README.md)
44 | - [Chain of Responsibility](./patterns/behavioral-patterns/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.
45 | - [Command](./patterns/behavioral-patterns/Command) — Encapsulate a request as an object, thereby letting you parameterized clients with different requests, queue or log requests, and support undoable operations.
46 | - Interpreter — Given a language, define a represention for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
47 | - Iterator — Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
48 | - Mediator — Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
49 | - Memento — Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.
50 | - [Observer](./patterns/behavioral-patterns/Observer) — Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
51 | - [State](./patterns/behavioral-patterns/State) — Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
52 | - [Strategy](./patterns/behavioral-patterns/Strategy) — Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
53 | - Template Method — Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.
54 | - 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 operates.
55 |
56 | ## Ressources
57 |
58 | Design Patterns: Elements of Reusable Object-Oriented Software - by (GOF)
59 |
60 | Design Patterns : https://cs.lmu.edu/~ray/notes/designpatterns/
61 |
62 | Refactoring guru: https://refactoring.guru/design-patterns
63 |
64 | Examples from : https://roadmap.sh/guides/design-patterns-for-humans
65 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Chain-of-Responsibility/README.md:
--------------------------------------------------------------------------------
1 | # 🔗 Chain of Responsibility
2 |
3 | Chain of responsibility is a behavioral design pattern that lets you pass requests along a chain of handlers. Upon receiving a request, each handler decides either to process the request or to pass it to the next handler in the chain.
4 |
5 | ## Applicability
6 |
7 | Use Chain of responsibility when :
8 |
9 | - more than one object may handle a request, and the handler isn't known a
10 | priori. The handler should be ascertainedautomatically.
11 | - you want to issue a request to one ofseveral objectswithout specifyingthe
12 | receiver explicitly.
13 | - the set of objects that can handle a request should be specified dynamically.
14 |
15 | ## General structure
16 |
17 |
18 |
19 |
20 |
21 | - Handler :
22 | - defines an interface for handling requests.
23 | - (optional) implements the successor link.
24 | - Concrete Handler :
25 | - handles requests it is responsible for.
26 | - can access its successor.
27 | - if the ConcreteHandler can handle the request, it does so; otherwise it
28 | forwards the request to its successor.
29 | - Client : initiates the request to a ConreteHandler object on the chain.
30 |
31 | ## Example
32 |
33 | For example, you have three payment methods (A, B and C) setup in your account; each having a different amount in it. A has 100 USD, B has 300 USD and C having 1000 USD and the preference for payments is chosen as A then B then C. You try to purchase something that is worth 210 USD. Using Chain of Responsibility, first of all account A will be checked if it can make the purchase, if yes purchase will be made and the chain will be broken. If not, request will move forward to account B checking for amount if yes chain will be broken otherwise the request will keep forwarding till it finds the suitable handler. Here A, B and C are links of the chain and the whole phenomenon is Chain of Responsibility.
34 |
35 |
36 |
37 |
38 |
39 | - Handler : Account.
40 | - ConcreteHandlers : Bank, Paypal, Bitcoin.
41 |
42 | The code source : [source folder](./src)
43 |
44 | ```Java
45 | public static void main(String[] args) throws Exception {
46 |
47 | // Let's prepare a chain like below
48 | // bank -> paypal -> bitcoin
49 | //
50 | // First priority bank
51 | // => If bank can't pay then paypal
52 | // => If paypal can't pay then bitcoin
53 | Bank bank = new Bank(100);
54 | Paypal paypal = new Paypal(200);
55 | Bitcoin bitcoin = new Bitcoin(300);
56 |
57 | bank.setNext(paypal);
58 | paypal.setNext(bitcoin);
59 |
60 | // Let's try to pay using the first priority i.e. bank
61 | bank.pay(259);
62 | }
63 |
64 | ```
65 |
66 | Output :
67 |
68 | ```
69 | Cannot pay 259.0 using Bank Proceeding...
70 | Cannot pay 259.0 using Paypal Proceeding...
71 | Paid 259.0 using Bitcoin
72 | ```
73 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Chain-of-Responsibility/src/Account.java:
--------------------------------------------------------------------------------
1 | public abstract class Account {
2 |
3 | protected Account successor;
4 | protected double balance;
5 |
6 | public void setNext(Account account) {
7 | this.successor = account;
8 | }
9 |
10 | public void pay(double montant) throws Exception {
11 | if (this.canPay(montant)) {
12 | System.out.println("Paid " + montant + " using " + getClass().getName());
13 | } else if (this.successor != null) {
14 | System.out.println("Cannot pay " + montant + " using " + getClass().getName() + " Proceeding...");
15 | this.successor.pay(montant);
16 | } else {
17 | throw new Exception("None of the accounts have enough balance");
18 | }
19 | }
20 |
21 | public boolean canPay(double montant) {
22 | return this.balance >= montant ? true : false;
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Chain-of-Responsibility/src/Bank.java:
--------------------------------------------------------------------------------
1 | public class Bank extends Account {
2 |
3 | public Bank(double balance) {
4 | this.balance = balance;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Chain-of-Responsibility/src/Bitcoin.java:
--------------------------------------------------------------------------------
1 | public class Bitcoin extends Account {
2 |
3 | public Bitcoin(double balance) {
4 | this.balance = balance;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Chain-of-Responsibility/src/Paypal.java:
--------------------------------------------------------------------------------
1 | public class Paypal extends Account {
2 |
3 | public Paypal(double balance) {
4 | this.balance = balance;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Command/README.md:
--------------------------------------------------------------------------------
1 | # 👮 Command
2 |
3 | Command is a behavioral design pattern that turns a request into a stand-alone object that contains all information about the request. This transformation lets you pass requests as a method arguments, delay or queue a request’s execution, and support undoable operations.
4 |
5 | ## Applicability
6 |
7 | Use the Command pattern when you want to :
8 |
9 | - parameterize objects by an actiontoperform, asMenultem objects did above.
10 | You can express such parameterization in a procedural language with a
11 | callback function, that is, a function that's registered somewhere to be called
12 | at a later point. Commands are an object-oriented replacement for callbacks.
13 | - specify, queue, and execute requests at different times. A Command object
14 | can have a lifetime independent of the original request. If the receiver of a
15 | request can be represented in an address space-independent way, then you
16 | can transfer a command object for the request to a different process and fulfill
17 | the request there.
18 | - support undo. TheCommand's Execute operation can store state for reversing its effects in the command itself. The Command interface must have an
19 | added Unexecute operation that reverses the effects of a previous call to Execute. Executed commands are stored in a history list. Unlimited-level undo
20 | and redo is achieved by traversing this list backwards and forwards calling
21 | Unexecute and Execute,respectively.
22 | - support logging changes so that they can be reapplied in case of a system
23 | crash. By augmenting the Command interface with load and store operations, you can keep a persistent log of changes. Recovering from a crash
24 | involves reloading logged commands from disk and reexecuting them with
25 | the Execute operation.
26 | - structure a system around high-level operations built on primitives operations. Such a structure is common in informationsystems that support transactions. A transaction encapsulates a set of changes to data. The Command
27 | pattern offers a way to model transactions. Commands have a common interface, letting you invoke all transactions the same way. The pattern also
28 | makes it easy to extend the system with new transactions.
29 |
30 | ## General structure
31 |
32 |
33 |
34 |
35 |
36 | - Command : declares an interface for executing an operation.
37 | - ConcreteCommand :
38 | - defines a binding between a Receiver object and an action.
39 | - implements Execute by invoking the corresponding operation(s) on Receiver.
40 | - Client : creates a ConcreteCommand object and sets its receiver.
41 | - Invoker : asks the command to carry out the request.
42 | - Receiver : knows how to perform the operations associated with carrying out a request. Any class may serve as a Receiver.
43 |
44 | ## Example
45 |
46 | A generic example would be you ordering food at a restaurant. You (i.e. Client) ask the waiter (i.e. Invoker) to bring some food (i.e. Command) and waiter simply forwards the request to Chef (i.e. Receiver) who has the knowledge of what and how to cook. Another example would be you (i.e. Client) switching on (i.e. Command) the television (i.e. Receiver) using a remote control (Invoker).
47 |
48 |
49 |
50 |
51 |
52 | - Command : Command
53 | - ConcreteCommand : TurnOn and TurnOff
54 | - Invoker : RemoteController
55 | - Receiver : The Bulb
56 |
57 | The code source : [source folder](./src)
58 |
59 | ```Java
60 | public static void main(String []args) {
61 |
62 | //Create the instance of bulb
63 | Bulb bulb = new Bulb();
64 |
65 | //Creating Concrete commands
66 | TurnOn turnOn = new TurnOn(bulb);
67 | TurnOff turnOff = new TurnOff(bulb);
68 |
69 | //Create the invoker (Remote controller)
70 | RemoteController remote = new RemoteController();
71 |
72 | //Turn On the bulb
73 | System.out.println(remote.submit(turnOn));
74 |
75 | //Turn Off the buld
76 | System.out.println(remote.submit(turnOff));
77 |
78 | }
79 |
80 | ```
81 |
82 | Output :
83 |
84 | ```
85 | Bulb has been lit
86 | Darkness!
87 | ```
88 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Command/src/Bulb.java:
--------------------------------------------------------------------------------
1 | public class Bulb {
2 |
3 | public String turnOn() {
4 | return "Bulb has been lit";
5 | }
6 |
7 | public String turnOff() {
8 | return "Darkness!";
9 | }
10 |
11 | }
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Command/src/Command.java:
--------------------------------------------------------------------------------
1 | public interface Command {
2 |
3 | public String execute();
4 |
5 | public String undo();
6 |
7 | public String redo();
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Command/src/RemoteController.java:
--------------------------------------------------------------------------------
1 | public class RemoteController {
2 |
3 | public String submit(Command command) {
4 | return command.execute();
5 | }
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Command/src/TurnOff.java:
--------------------------------------------------------------------------------
1 | public class TurnOff implements Command {
2 |
3 | protected Bulb bulb;
4 |
5 | public TurnOff(Bulb bulb) {
6 | this.bulb = bulb;
7 | }
8 |
9 | @Override
10 | public String execute() {
11 | return bulb.turnOff();
12 | }
13 |
14 | @Override
15 | public String undo() {
16 | return bulb.turnOn();
17 | }
18 |
19 | @Override
20 | public String redo() {
21 | return this.execute();
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Command/src/TurnOn.java:
--------------------------------------------------------------------------------
1 | public class TurnOn implements Command {
2 |
3 | protected Bulb bulb;
4 |
5 | public TurnOn(Bulb bulb) {
6 | this.bulb = bulb;
7 | }
8 |
9 | @Override
10 | public String execute() {
11 | return bulb.turnOn();
12 | }
13 |
14 | @Override
15 | public String undo() {
16 | return bulb.turnOff();
17 | }
18 |
19 | @Override
20 | public String redo() {
21 | return this.execute();
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Observer/README.Md:
--------------------------------------------------------------------------------
1 | # 😎 Observer
2 |
3 | Observer is a behavioral design pattern that lets you define a subscription mechanism to notify multiple objects about any events that happen to the object they’re observing.
4 |
5 | ## Applicability
6 |
7 | Use the Observer pattern in any of the following situations:
8 |
9 | - When an abstraction has two aspects, one dependent on the other. Encapsulating these aspects in separate objects lets you vary and reuse them independently.
10 | - When a change to one object requires changing others, and you don't know
11 | how many objects need to be changed.
12 | - When an object should be able to notify other objects without making assumptions about who these objects are. In other words, you don't want these
13 | objects tightly coupled.
14 |
15 | ## General structure
16 |
17 |
18 |
19 |
20 |
21 | - Subject :
22 | - knows its observers. Any number of Observer objects may observe a subject.
23 | - provides an interface for attachingand detaching Observer objects.
24 | - Observer :
25 | - defines an updating interface for objects that should be notified of changes in a subject.
26 | - ConcreteSubject :
27 | - stores state ofinterest toConcreteObserver objects.
28 | - sends a notification to its observers when itsstate changes.
29 | - ConcreteObserver ;
30 | - maintains a reference to a ConcreteSubject object.
31 | - stores state that should stay consistent with the subject's.
32 | - implements the Observer updating interface to keep its state consistent
33 | with the subject's.
34 |
35 | ## Example
36 |
37 | For example, a news agency can notify channels when it receives news. Receiving news is what changes the state of the news agency, and it causes the channels to be notified.
38 |
39 |
40 |
41 |
42 |
43 | - Subject : Agency
44 | - Observer : Channel
45 | - ConcreteSubject : NewsAgency
46 | - ConcreteObserver ; NewsChannel
47 |
48 | The code source : [source folder](./src)
49 |
50 | ```Java
51 | public static void main(String[] args) {
52 | NewsAgency observable = new NewsAgency();
53 | NewsChannel observer = new NewsChannel();
54 |
55 | observable.addObserver(observer);
56 | observable.setNews("Today's news !");
57 |
58 | System.out.println(observer.getNews());
59 | }
60 |
61 | ```
62 |
63 | Output :
64 |
65 | ```
66 | Today's news !
67 | ```
68 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Observer/src/Agency.java:
--------------------------------------------------------------------------------
1 | import java.nio.channels.Channel;
2 |
3 | public interface Agency {
4 |
5 | void addObserver(Channel channel);
6 |
7 | void removeObserver(Channel channel);
8 |
9 | void setNews(String news);
10 | }
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Observer/src/Channel.java:
--------------------------------------------------------------------------------
1 | import java.util.Observer;
2 |
3 | public interface Channel {
4 | void update(String news);
5 | }
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Observer/src/NewsAgency.java:
--------------------------------------------------------------------------------
1 | import java.util.ArrayList;
2 | import java.util.List;
3 |
4 | public class NewsAgency implements Agency {
5 |
6 | private String news;
7 | private List channels = new ArrayList<>();
8 |
9 | @Override
10 | public void addObserver(Channel channel) {
11 | this.channels.add(channel);
12 | }
13 |
14 | @Override
15 | public void removeObserver(Channel channel) {
16 | this.channels.remove(channel);
17 | }
18 |
19 | @Override
20 | public void setNews(String news) {
21 | this.news = news;
22 | for (Channel channel : this.channels) {
23 | channel.update(news);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Observer/src/NewsChannel.java:
--------------------------------------------------------------------------------
1 | public class NewsChannel implements Channel {
2 |
3 | private String news;
4 |
5 | @Override
6 | public void update(String news) {
7 | this.news = news;
8 | }
9 |
10 | public String getNews() {
11 | return this.news;
12 | }
13 |
14 | }
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/README.md:
--------------------------------------------------------------------------------
1 | # Behavioral patterns
2 |
3 | Behavioral design patterns are concerned with algorithms and the assignment of responsibilities between objects.
4 |
5 | ## Table of contents :
6 |
7 | | Scope | Class | Object |
8 | | ---------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
9 | | Behavioral | Interpreter , Template Method | [Chain of Responsiblity](./Chain-of-Responsibility) , [State](./State) , [Command](./Command) , Iterator , Mediator , Memento , [Observer](./Observer) , [Strategy](./Strategy) , Visitor |
10 |
11 | ## Note :
12 |
13 | [Some further explanation about scope](../creational-patterns/README.md#note-)
14 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/State/README.md:
--------------------------------------------------------------------------------
1 | # 💢 State
2 |
3 | State is a behavioral design pattern that lets an object alter its behavior when its internal state changes. It appears as if the object changed its class.
4 |
5 | ## Applicability
6 |
7 | We use the State pattern in either of the following cases:
8 |
9 | - An object's behavior depends on its state, and it must change its behavior at
10 | run-time depending on that state.
11 | - Operations have large, multipart conditional statements that depend on the
12 | object's state. This state is usually represented by one or more enumerated
13 | constants. Often, several operations will contain this same conditional structure. The Statepattern puts each branch ofthe conditional in a separate class.This lets you treat the object's state as an object in its own right that can vary
14 | independently from other objects.
15 |
16 | ## General Structure
17 |
18 |
19 |
20 |
21 |
22 | - Context stores a reference to one of the concrete state objects and delegates to it all state-specific work. The context communicates with the state object via the state interface. The context exposes a setter for passing it a new state object.
23 | - The State interface declares the state-specific methods. These methods should make sense for all concrete states because you don’t want some of your states to have useless methods that will never be called.
24 | - Concrete States provide their own implementations for the state-specific methods. To avoid duplication of similar code across multiple states, you may provide intermediate abstract classes that encapsulate some common behavior.
25 | State objects may store a backreference to the context object. Through this reference, the state can fetch any required info from the context object, as well as initiate state transitions.
26 |
27 | ## Example
28 |
29 | Let's take an example of text editor, it lets you change the state of text that is typed i.e. if you have selected bold, it starts writing in bold, if italic then in italics etc.
30 |
31 |
32 |
33 |
34 |
35 | The code source : [source folder](./src)
36 |
37 | ```Java
38 | public static void main(String []args) {
39 |
40 | //Create the instance with the Default state
41 | TextEditor editor = new TextEditor(new Default());
42 | System.out.println(editor.request("First Line!"));
43 |
44 | //Change the state to the UpperCase state
45 | editor.setState(new UpperCase());
46 | System.out.println(editor.request("Second line!"));
47 |
48 | //Change the state to the LowerCase state
49 | editor.setState(new LowerCase());
50 | System.out.println(editor.request("THIRD LINE!"));
51 |
52 | }
53 |
54 | ```
55 |
56 | Output :
57 |
58 | ```
59 | First Line!
60 | SECOND LINE!
61 | third line!
62 | ```
63 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/State/src/Default.java:
--------------------------------------------------------------------------------
1 | public class Default implements WritingState {
2 |
3 | @Override
4 | public String write(String words) {
5 | return words.trim();
6 | }
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/State/src/LowerCase.java:
--------------------------------------------------------------------------------
1 | public class LowerCase implements WritingState {
2 |
3 | @Override
4 | public String write(String words) {
5 | return words.toLowerCase();
6 | }
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/State/src/TextEditor.java:
--------------------------------------------------------------------------------
1 | public class TextEditor {
2 | private WritingState state;
3 |
4 | // Constructor
5 | public TextEditor(WritingState state) {
6 | this.state = state;
7 | }
8 |
9 | // state setter
10 | public void setState(WritingState state) {
11 | this.state = state;
12 | }
13 |
14 | // the request method
15 | public String request(String words) {
16 | return this.state.write(words);
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/State/src/UpperCase.java:
--------------------------------------------------------------------------------
1 | public class UpperCase implements WritingState {
2 |
3 | @Override
4 | public String write(String words) {
5 | return words.toUpperCase();
6 | }
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/State/src/WritingState.java:
--------------------------------------------------------------------------------
1 | public interface WritingState {
2 | public String write(String words);
3 | }
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Strategy/README.md:
--------------------------------------------------------------------------------
1 | # 💡 Strategy
2 |
3 | Strategy is a behavioral design pattern that lets you define a family of algorithms, put each of them into a separate class, and make their objects interchangeable.
4 |
5 | ## Applicability
6 |
7 | Use the Strategy pattern when
8 |
9 | - many related classes differ only in their behavior. Strategies provide a way
10 | to configure a class with one of many behaviors.
11 | - you need different variants of an algorithm. For example, you might define algorithms reflecting different space/time trade-offs. Strategies can be
12 | used when these variants are implemented as a class hierarchy of algorithms.
13 | - an algorithm uses data that clients shouldn't know about. Use the Strategy
14 | pattern to avoid exposing complex, algorithm-specific data structures.
15 | - a class defines many behaviors, and these appear as multiple conditional
16 | statements in its operations. Instead of many conditionals, move related
17 | conditional branches into their own Strategy class.
18 |
19 | ## General structure
20 |
21 |
22 |
23 |
24 |
25 | - Strategy : declares an interface common to all supported algorithms. Context uses this interface to call the algorithm defined by a ConcreteStrategy.
26 | - ConcreteStrategy : implements the algorithm using the Strategy interface.
27 | - Context : is configured with a ConcreteStrategy object.
28 | - maintains a reference to a Strategy object.
29 | - may define an interface that lets Strategy access its data.
30 |
31 | ## Example
32 |
33 | Consider the example of sorting, we implemented bubble sort but the data started to grow and bubble sort started getting very slow. In order to tackle this we implemented Quick sort. But now although the quick sort algorithm was doing better for large datasets, it was very slow for smaller datasets. In order to handle this we implemented a strategy where for small datasets, bubble sort will be used and for larger, quick sort.
34 |
35 |
36 |
37 |
38 |
39 | - Strategy : SortStrategy
40 | - ConcreteStrategy : BubbleStrategySort & QuickSortStrategy
41 | - Context : Sorter
42 |
43 | The code source : [source folder](./src)
44 |
45 | ```Java
46 | public static void main(String []args){
47 |
48 | int[] dataset = { 1, 5, 4, 3, 2, 8 };
49 |
50 | //Bubble sort strategy
51 | Sorter sorter = new Sorter(new BubbleStrategySort());
52 | dataset = sorter.sort(dataset);
53 |
54 | //Quick sort strategy
55 | sorter = new Sorter(new QuickSortStrategy());
56 | dataset = sorter.sort(dataset);
57 |
58 | }
59 |
60 | ```
61 |
62 | Output :
63 |
64 | ```
65 | Sorting using bubbleSort
66 | Sorting using QuickSort
67 | ```
68 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Strategy/src/BubbleStrategySort.java:
--------------------------------------------------------------------------------
1 | public class BubbleStrategySort implements StrategySort {
2 |
3 | @Override
4 | public int[] sort(int[] array) {
5 |
6 | System.out.println("Sorting using bubbleSort");
7 |
8 | // Do sorting
9 |
10 | return array;
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Strategy/src/QuickSortStrategy.java:
--------------------------------------------------------------------------------
1 | public class QuickSortStrategy implements StrategySort {
2 |
3 | @Override
4 | public int[] sort(int[] array) {
5 |
6 | System.out.print("Sorting using QuickSort");
7 |
8 | // Do sorting
9 |
10 | return array;
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Strategy/src/Sorter.java:
--------------------------------------------------------------------------------
1 | public class Sorter {
2 |
3 | protected StrategySort strategySort;
4 |
5 | public Sorter(StrategySort strategySort) {
6 | this.strategySort = strategySort;
7 | }
8 |
9 | public int[] sort(int[] array) {
10 | return this.strategySort.sort(array);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/patterns/behavioral-patterns/Strategy/src/StrategySort.java:
--------------------------------------------------------------------------------
1 | public interface StrategySort {
2 |
3 | public int[] sort(int[] array);
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Abstract-Factory/README.md:
--------------------------------------------------------------------------------
1 | # 🔨 Abstract factory
2 |
3 | Abstract Factory is a creational design pattern that lets you produce families of related objects without specifying their concrete classes.
4 |
5 | ## Applicability
6 |
7 | We use the Abstract Factory pattern when :
8 |
9 | - System should be independent of how its products are created, composed,
10 | and represented.
11 | - System should be configured with one of multiple families of products.
12 | - Family of related product objects is designed to be used together, and you
13 | need to enforce this constraint.
14 | - We want to provide a class library of products, and you want to reveal just
15 | their interfaces, not their implementations.
16 |
17 | ## General Structure
18 |
19 |
20 |
21 |
22 |
23 | ## Example
24 |
25 | Consider, you are building a house and you need doors. Based on your needs you might get a wooden door from a wooden door shop, iron door from an iron shop or a PVC door from the relevant shop. Plus you might need a guy with different kind of specialities to fit the door, for example a carpenter for wooden door, welder for iron door etc. As you can see there is a dependency between the doors now, wooden door needs carpenter, iron door needs a welder etc.
26 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Builder/README.md:
--------------------------------------------------------------------------------
1 | # 👷 Builder
2 |
3 | Builder is a creational design pattern that lets you construct complex objects step by step. The pattern allows you to produce different types and representations of an object using the same construction code.
4 |
5 | ## Applicability
6 |
7 | We use the Builder pattern when
8 |
9 | - The algorithm for creating a complex object should be independent of the
10 | parts that make up the object and how they're assembled.
11 | - The construction process must allow different representations for the object
12 | that's constructed.
13 |
14 | ## General Structure
15 |
16 |
17 |
18 |
19 |
20 | - The Builder interface declares product construction steps that are common to all types of builders.
21 | - Concrete Builders provide different implementations of the construction steps. Concrete builders may produce products that don’t follow the common interface.
22 | - Products are resulting objects. Products constructed by different builders don’t have to belong to the same class hierarchy or interface.
23 | - The Director class defines the order in which to call construction steps, so you can create and reuse specific configurations of products.
24 |
25 | ## Example
26 |
27 | For example we have a user management module, primary entity is `User`, let’s say. Ideally and practically as well, once a user object is fully created, we will not want to change it’s state , and let’s assume, our User object has following 5 attributes i.e. firstName, lastName, age, phone and address.
28 |
29 | In normal practice, if we want to make a immutable User class, then we must pass all five information as parameters to constructor. It will look like this:
30 |
31 | ```Java
32 | public User (String firstName, String lastName, int age, String phone, String address){
33 | this.firstName = firstName;
34 | this.lastName = lastName;
35 | this.age = age;
36 | this.phone = phone;
37 | this.address = address;
38 | }
39 | ```
40 |
41 | Now what if only firstName and lastName are mandatory and rest 3 fields are optional. Problem !! We need more constructors.
42 |
43 | Let’s solve the above problem in code. The given solution uses an additional class UserBuilder which helps us in building desired User instance with all mandatory attributes and combination of optional attributes, without losing the immutability.
44 |
45 | Please note that the User object does not have any setter method, so its state can not be changed once it has been built. This provides the desired immutability.
46 |
47 | The code source : [source folder](./src)
48 |
49 | ```Java
50 | public static void main(String[] args) {
51 | User user1 = new User.UserBuilder("Lokesh", "Gupta")
52 | .age(30)
53 | .phone("1234567")
54 | .address("Fake address 1234")
55 | .build();
56 |
57 | System.out.println(user1);
58 |
59 |
60 | User user2 = new User.UserBuilder("Super", "Man")
61 | //No age
62 | //No phone
63 | //no address
64 | .build();
65 |
66 | System.out.println(user2);
67 | }
68 | ```
69 |
70 | Output :
71 |
72 | ```
73 | User: Lokesh,Gupta,30,1234567,Fake address 1234
74 | User: Super,Man
75 | ```
76 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Builder/src/User.java:
--------------------------------------------------------------------------------
1 | public class User {
2 | // All final attributes
3 | private final String firstName; // required
4 | private final String lastName; // required
5 | private final int age; // optional
6 | private final String phone; // optional
7 | private final String address; // optional
8 |
9 | private User(UserBuilder builder) {
10 | this.firstName = builder.firstName;
11 | this.lastName = builder.lastName;
12 | this.age = builder.age;
13 | this.phone = builder.phone;
14 | this.address = builder.address;
15 | }
16 |
17 | // All getter, and NO setter to provde immutability
18 | public String getFirstName() {
19 | return firstName;
20 | }
21 |
22 | public String getLastName() {
23 | return lastName;
24 | }
25 |
26 | public int getAge() {
27 | return age;
28 | }
29 |
30 | public String getPhone() {
31 | return phone;
32 | }
33 |
34 | public String getAddress() {
35 | return address;
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | return "User: " + this.firstName + ", " + this.lastName + ", " + this.age + ", " + this.phone + ", "
41 | + this.address;
42 | }
43 |
44 | public static class UserBuilder {
45 | private final String firstName;
46 | private final String lastName;
47 | private int age;
48 | private String phone;
49 | private String address;
50 |
51 | public UserBuilder(String firstName, String lastName) {
52 | this.firstName = firstName;
53 | this.lastName = lastName;
54 | }
55 |
56 | public UserBuilder age(int age) {
57 | this.age = age;
58 | return this;
59 | }
60 |
61 | public UserBuilder phone(String phone) {
62 | this.phone = phone;
63 | return this;
64 | }
65 |
66 | public UserBuilder address(String address) {
67 | this.address = address;
68 | return this;
69 | }
70 |
71 | // Return the finally consrcuted User object
72 | public User build() {
73 | User user = new User(this);
74 | validateUserObject(user);
75 | return user;
76 | }
77 |
78 | private void validateUserObject(User user) {
79 | // Do some basic validations to check
80 | // if user object does not break any assumption of system
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/patterns/creational-patterns/Factory-Method/README.md:
--------------------------------------------------------------------------------
1 | # 🏭 Factory Method
2 |
3 | Factory Method is a creational design pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created.
4 |
5 | ## Applicability
6 |
7 | we use the Factory Method pattern when :
8 |
9 | - Class can't anticipate the class of objects it must create.
10 | - Class wants it's subclass to specify the objects it creates.
11 | - Classes deleguate responsability to one of several helper subclasses, and we want to localize the knowledge of which helper subclass is the delegate.
12 |
13 | ## General Structure
14 |
15 |
16 |
17 |
18 |
19 | - The creator class can contain all the methods used to
20 | handle the products but the "factoryMethod()" method remains abstract.
21 |
22 | - The concrete creator classes implement the "factoryMethod()" method which
23 | instantiates and returns the concrete products. Every concrete creator can
24 | therefore create products for which he is responsible.
25 |
26 | - Finally all the products implement the same interface so that the
27 | classes using the products (such as the creator) can refer to them without
28 | know the concrete types.
29 |
30 | ## Example
31 |
32 | Consider the case of a hiring manager. It is impossible for one person to interview for each of the positions. Based on the job opening, she has to decide and delegate the interview steps to different people.
33 |
34 |
35 |
36 |
37 |
38 | First of all we have an `Interviewer` interface and some implementations for it,then we created abstract class `HiringManager` , Now any child can extend it and provide the required interviewer `DevelopementManager` and `MarketingManager`.
39 | And then it can be used as :
40 |
41 | The code source : [source folder](./src)
42 |
43 | ```Java
44 | public static void main(String []args){
45 |
46 | DevelopmentManager developmentManager = new DevelopmentManager();
47 | MarketingManager marketingManager = new MarketingManager();
48 |
49 | developmentManager.takeInterview();
50 | marketingManager.takeInterview();
51 |
52 | }
53 |
54 | ```
55 |
56 | Output :
57 |
58 | ```
59 | Asking about design patterns!
60 | Asking about community building!
61 | ```
62 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Factory-Method/src/CommunityExecutive.java:
--------------------------------------------------------------------------------
1 | public class CommunityExecutive implements Interviewer {
2 |
3 | @Override
4 | public void askQuestions() {
5 | System.out.println("Asking about community building!");
6 | }
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Factory-Method/src/Developer.java:
--------------------------------------------------------------------------------
1 | public class Developer implements Interviewer {
2 |
3 | @Override
4 | public void askQuestions() {
5 | System.out.println("Asking about design pattern!");
6 | }
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Factory-Method/src/DevelopmentManager.java:
--------------------------------------------------------------------------------
1 | public class DevelopmentManager extends HiringManager {
2 |
3 | @Override
4 | public Interviewer makeInterviewer() {
5 | return new Developer();
6 | }
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Factory-Method/src/HiringManager.java:
--------------------------------------------------------------------------------
1 | public abstract class HiringManager {
2 |
3 | // Factory method
4 | abstract Interviewer makeInterviewer();
5 |
6 | public void takeInterview() {
7 | Interviewer interviewer = makeInterviewer();
8 | interviewer.askQuestions();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Factory-Method/src/Interviewer.java:
--------------------------------------------------------------------------------
1 | interface Interviewer {
2 | public void askQuestions();
3 | }
--------------------------------------------------------------------------------
/patterns/creational-patterns/Factory-Method/src/MarketingManager.java:
--------------------------------------------------------------------------------
1 | public class MarketingManager extends HiringManager {
2 |
3 | @Override
4 | public Interviewer makeInterviewer() {
5 | return new CommunityExecutive();
6 | }
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Prototype/README.md:
--------------------------------------------------------------------------------
1 | # 🐑 Prototype
2 |
3 | Prototype is a creational design pattern that lets you copy existing objects without making your code dependent on their classes.
4 |
5 | ## Applicability
6 |
7 | Use the Prototype pattern when a system should be independent of how its
8 | products are created, composed, and represented; and
9 |
10 | - When the classes to instantiate are specified at run-time, for example, by
11 | dynamic loading.
12 | - To avoid building a class hierarchy offactories that parallels the class hierarchy of products.
13 | - When instances of a class can have one of only a few different combinations
14 | of state. It may be more convenient to install a corresponding number of
15 | prototypes and clone them rather than instantiating the class manually, each
16 | time with the appropriate state.
17 |
18 | ## General Structure
19 |
20 |
21 |
22 |
23 |
24 | - Prototype : declares an interface for cloning itself.
25 | - ConcretePrototype : implements an operation for cloning itself.
26 | - Client : creates a new object by asking a prototype to clone itself.
27 |
28 | ## Example
29 |
30 | Remember Dolly? The sheep that was cloned! Lets not get into the details but the key point here is that it is all about cloning.
31 |
32 | In plain words : Create an object based on an existing object through cloning.
33 |
34 |
35 |
36 |
37 |
38 | In Java, the prototype pattern is recommended to be implemented as follows. First, create an interface with a method for cloning objects. In this example, Prototype interface accomplishes this with its copy method.
39 |
40 | The code source : [source folder](./src)
41 |
42 | ```Java
43 | public static void main(String []args){
44 |
45 | CloneFactory animalMaker = new CloneFactory();
46 |
47 | //Create object type sheep and dog
48 | Sheep sally = new Sheep();
49 | Dog max = new Dog();
50 |
51 | //Clone sheep and dog instance
52 | Sheep clonedSheep = (Sheep) animalMake.getClone(sally);
53 | Dog clonedDog = (Dog) animalMake.getClone(max);
54 |
55 | System.out.println("Sally hashCode:- "+ sally.hashCode());
56 | System.out.println("SallyClone hashCode:- "+ clonedSheep.hashCode());
57 |
58 | System.out.println("\nMax hashCode:- "+ max.hashCode());
59 | System.out.println("MaxClone hashCode:- "+ clonedDog.hashCode());
60 |
61 | }
62 |
63 | ```
64 |
65 | Output :
66 |
67 | ```
68 | Sally hashCode:- 1435741095
69 | SallyClone hashCode:- 1981243562
70 |
71 | Max hashCode:- 1550089733
72 | MaxClone hashCode:- 1346782756
73 |
74 | ```
75 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Prototype/src/CloneFactory.java:
--------------------------------------------------------------------------------
1 | public class CloneFactory {
2 |
3 | public Prototype getClone(Prototype prototypeSample) {
4 | return prototypeSample.makeCopy();
5 | }
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Prototype/src/Dog.java:
--------------------------------------------------------------------------------
1 | public class Dog implements Prototype {
2 |
3 | public Dog() {
4 |
5 | System.out.println("Dog is made");
6 | }
7 |
8 | @Override
9 | public Prototype makeCopy() {
10 |
11 | System.out.println("Dog is being made");
12 | Dog dogObject = null;
13 |
14 | try {
15 |
16 | dogObject = (Dog) super.clone();
17 |
18 | } catch (CloneNotSupportedException e) {
19 |
20 | e.printStackTrace();
21 |
22 | }
23 |
24 | return dogObject;
25 | }
26 |
27 | public String toString() {
28 | return "I am a dog";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Prototype/src/Prototype.java:
--------------------------------------------------------------------------------
1 | public interface Prototype extends Cloneable {
2 |
3 | public Prototype makeCopy();
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Prototype/src/Sheep.java:
--------------------------------------------------------------------------------
1 | public class Sheep implements Prototype {
2 |
3 | public Sheep() {
4 |
5 | System.out.println("Sheep is made");
6 | }
7 |
8 | @Override
9 | public Prototype makeCopy() {
10 |
11 | System.out.println("Sheep is being made");
12 | Sheep sheepObject = null;
13 |
14 | try {
15 |
16 | sheepObject = (Sheep) super.clone();
17 |
18 | } catch (CloneNotSupportedException e) {
19 |
20 | e.printStackTrace();
21 |
22 | }
23 |
24 | return sheepObject;
25 | }
26 |
27 | public String toString() {
28 | return "Dolly is my hero!";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/README.md:
--------------------------------------------------------------------------------
1 | # Creational patterns
2 |
3 | These patterns provide various object creation mechanisms, which increase flexibility and reuse of existing code.
4 |
5 | ## Table of contents :
6 |
7 | | Scope | Class | Object |
8 | | ---------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
9 | | Creational | [Factory Method](./Factory-Method/) | [Abstract Factory](./Abstract-Factory) , [Builder](./Builder/) , [Prototype](./Prototype) , [Singleton](./Singleton) |
10 |
11 | ## Note :
12 |
13 | Some further explanation of what scope means, and how it impacts each design pattern is essential when it comes to classifying each design pattern. Scope refers to the extent of the design pattern, or how much it affects and can affect. In the case of object-oriented programming, the scope of a design pattern can extend only to a class, or to an instance of that class, called an object.
14 |
15 | - Class scope :
16 | - Focuses on the relationships between classes and their
17 | subclasses.
18 | - Reuse by inheritance
19 | - Object scope :
20 | - Focuses on the relationships between objects.
21 | - Reuse by composition
22 |
23 | ### Composition vs inheritance
24 |
25 | | | Inheritance | Composition |
26 | | ---------- | ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
27 | | Basic | Inheritance is an "is-a" relationship | Composition is a "has-a" relationship |
28 | | Code reuse | In Inheritance, a class can extend only one interface, therefore, you can reuse your code only in one class only | We can reuse code in multiple class |
29 | | Scope | Inheritance provides its features at compile time | Composition is easily achieved at runtime |
30 |
31 | ### exemple :
32 |
33 | Car has a engine and Car is a Automobile.
34 |
35 | ```Java
36 | class Engine {} // The engine class.
37 |
38 | class Automobile {} // Automobile class which is parent to Car class.
39 |
40 | class Car extends Automobile { // Car is an automobile => Car class extends Automobile
41 |
42 | private Engine engine ; // Car has an Engine => Car class has an instance of Engine (Object).
43 |
44 | }
45 |
46 | ```
47 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Singleton/README.md:
--------------------------------------------------------------------------------
1 | # ❄️ Singleton
2 |
3 | Singleton is a creational design pattern that lets you ensure that a class has only one instance, while providing a global access point to this instance.
4 |
5 | ## Applicability
6 |
7 | Use the Singleton pattern when
8 |
9 | - There must be exactly one instance of a class, and it must be accessible to
10 | clients from a well-known access point.
11 | - When the sole instance should be extensible by subclassing, and clients
12 | should be able to use an extended instance without modifying their code.
13 |
14 | ## General Structure
15 |
16 |
17 |
18 |
19 |
20 | The Singleton class declares the static method getInstance that returns the same instance of its own class.
21 |
22 | The Singleton’s constructor should be hidden from the client code. Calling the getInstance method should be the only way of getting the Singleton object.
23 |
24 | ## Example
25 |
26 | There can only be one president of a country at a time. The same president has to be brought to action, whenever duty calls. President here is singleton.
27 |
28 |
29 |
30 |
31 |
32 | Note : To create a singleton,we have to make the constructor private, disable cloning, disable extension and create a static variable to house the instance.
33 |
34 | The code source : [source folder](./src)
35 |
36 | ```Java
37 | public static void main(String []args){
38 |
39 | President presidentOne = President.getInstance();
40 | President presidentTwo = President.getInstance();
41 |
42 | System.out.println("PresidentOne hashCode:- "+ presidentOne.hashCode());
43 | System.out.println("PresidentTwo hashCode:- "+ PresidentTwo.hashCode());
44 |
45 | }
46 |
47 | ```
48 |
49 | Output :
50 |
51 | ```
52 | PresidentOne hashCode:- 1550089733
53 | PresidentTwo hashCode:- 1550089733
54 | ```
55 |
--------------------------------------------------------------------------------
/patterns/creational-patterns/Singleton/src/President.java:
--------------------------------------------------------------------------------
1 | public class President {
2 |
3 | private static President instance;
4 |
5 | private President() {
6 | // Hide constructor
7 | }
8 |
9 | public static President getInstance() {
10 | if (instance == null)
11 | instance = new President();
12 | return instance;
13 | }
14 |
15 | // Disable cloning
16 | @Override
17 | protected Object clone() {
18 | return instance;
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/patterns/images/abstract-factory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/abstract-factory.png
--------------------------------------------------------------------------------
/patterns/images/adapter-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/adapter-example.png
--------------------------------------------------------------------------------
/patterns/images/adapter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/adapter.png
--------------------------------------------------------------------------------
/patterns/images/bridge-schema.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/bridge-schema.png
--------------------------------------------------------------------------------
/patterns/images/bridge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/bridge.png
--------------------------------------------------------------------------------
/patterns/images/builder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/builder.png
--------------------------------------------------------------------------------
/patterns/images/chain-of-responsibility-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/chain-of-responsibility-example.png
--------------------------------------------------------------------------------
/patterns/images/chain-of-responsibility.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/chain-of-responsibility.png
--------------------------------------------------------------------------------
/patterns/images/command-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/command-example.png
--------------------------------------------------------------------------------
/patterns/images/command.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/command.png
--------------------------------------------------------------------------------
/patterns/images/composite-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/composite-example.png
--------------------------------------------------------------------------------
/patterns/images/composite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/composite.png
--------------------------------------------------------------------------------
/patterns/images/decorator-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/decorator-example.png
--------------------------------------------------------------------------------
/patterns/images/decorator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/decorator.png
--------------------------------------------------------------------------------
/patterns/images/facade.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/facade.png
--------------------------------------------------------------------------------
/patterns/images/factory-method-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/factory-method-example.png
--------------------------------------------------------------------------------
/patterns/images/factory-method.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/factory-method.png
--------------------------------------------------------------------------------
/patterns/images/observer-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/observer-example.png
--------------------------------------------------------------------------------
/patterns/images/observer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/observer.png
--------------------------------------------------------------------------------
/patterns/images/prototype-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/prototype-example.png
--------------------------------------------------------------------------------
/patterns/images/prototype.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/prototype.png
--------------------------------------------------------------------------------
/patterns/images/proxy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/proxy.png
--------------------------------------------------------------------------------
/patterns/images/singleton-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/singleton-example.png
--------------------------------------------------------------------------------
/patterns/images/singleton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/singleton.png
--------------------------------------------------------------------------------
/patterns/images/state-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/state-example.png
--------------------------------------------------------------------------------
/patterns/images/state.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/state.png
--------------------------------------------------------------------------------
/patterns/images/strategy-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/strategy-example.png
--------------------------------------------------------------------------------
/patterns/images/strategy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OussamaM1/Design-Pattern-Java-notes/9ef1f84dc254c8efd09dd950306ef85a9cf000eb/patterns/images/strategy.png
--------------------------------------------------------------------------------
/patterns/structural-patterns/Adapter/README.md:
--------------------------------------------------------------------------------
1 | # 🔌 Adapter
2 |
3 | Adapter is a structural design pattern that allows objects with incompatible interfaces to collaborate.
4 |
5 | ## Applicability
6 |
7 | Use the Adapter pattern when
8 |
9 | - you want to use an existing class, and its interface does not match the one
10 | you need.
11 | - you want to create a reusable class that cooperates with unrelated orunforeseen classes, that is, classes that don't necessarily have compatible interfaces.
12 | - (object adapter only) you need to use several existing subclasses, but it's unpractical to adapt their interface by subclassing every one. An object adapter
13 | can adapt the interface of its parent class.
14 |
15 | ## General structure
16 |
17 | Object Adapter :
18 | This implementation uses the object composition principle: the adapter implements the interface of one object and wraps the other one. It can be implemented in all popular programming languages.
19 |
20 |
21 |
22 |
23 |
24 | - Target : defines the domain-specific interface that Client uses.
25 | - Client : collaborateswith objects conforming to the Target interface.
26 | - Adaptee : defines an existing interface that needs adapting.
27 | - Adapter :adapts the interface of Adaptee to the Target interface
28 |
29 | ## Example
30 |
31 | Consider that we have a video game where we have a `EnemyAttacker` that can fire a weapon , drive forward and assign driver however we want to create an AI `EnemyRobot`, now a enemy robot has no need for a driver also it's not going to drive forward it's going to walk. In this situation we will need to implement an adapter `EnemyRobotAdapter` to adapt the enemyRobot with enemyAttacker.
32 |
33 |
34 |
35 |
36 |
37 | The code source : [source folder](./src)
38 |
39 | ```Java
40 | public static void main(String []args){
41 |
42 | //The adaptee
43 | EnemyRobot fredTheRobot = new EnemyRobot();
44 | //The adapter
45 | EnemyAttacker robotAdapter = new EnemyRobotAdapter(fredTheRobot);
46 |
47 | System.out.println("The robot --------------------------------");
48 | fredTheRobot.reactToHuman("paul");
49 | fredTheRobot.walksForward();
50 | fredTheRobot.smashWithHands();
51 |
52 |
53 | System.out.println("\nThe robot with Adapter -------------------");
54 | robotAdapter.assignDriver("paul");
55 | robotAdapter.driveForward();
56 | robotAdapter.fireWeapon();
57 |
58 | }
59 |
60 | ```
61 |
62 | Output :
63 |
64 | ```
65 | The robot --------------------------------
66 | Enemy robot causes 7 Damage with its hands
67 | Enemy robot walks forward 3 spaces
68 | Enemy robot Tramps on paul
69 |
70 | The robot with adapter -------------------
71 | Enemy robot causes 5 Damage with its hands
72 | Enemy robot walks forward 4 spaces
73 | Enemy robot Tramps on paul
74 | ```
75 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Adapter/src/EnemyAttacker.java:
--------------------------------------------------------------------------------
1 | public interface EnemyAttacker {
2 |
3 | public void fireWeapon();
4 |
5 | public void driveForward();
6 |
7 | public void assignDriver(String driver);
8 |
9 | }
--------------------------------------------------------------------------------
/patterns/structural-patterns/Adapter/src/EnemyRobot.java:
--------------------------------------------------------------------------------
1 | import java.util.Random;
2 |
3 | public class EnemyRobot {
4 |
5 | Random generator = new Random();
6 |
7 | public void smashWithHands() {
8 |
9 | int attackdamage = generator.nextInt(10) + 1;
10 |
11 | System.out.println("Enemy robot causes " + attackdamage + " Damage with its hands");
12 |
13 | }
14 |
15 | public void walkForward() {
16 |
17 | int mouvement = generator.nextInt(5) + 1;
18 |
19 | System.out.println("Enemy robot walks forward " + mouvement + " spaces");
20 |
21 | }
22 |
23 | public void reactToHuman(String target) {
24 |
25 | System.out.println("Enemy robot Tramps on " + target);
26 |
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Adapter/src/EnemyRobotAdapter.java:
--------------------------------------------------------------------------------
1 | public class EnemyRobotAdapter implements EnemyAttacker {
2 |
3 | private EnemyRobot enemyRobot;
4 |
5 | public EnemyRobotAdapter(EnemyRobot enemyRobot) {
6 | this.enemyRobot = enemyRobot;
7 | }
8 |
9 | @Override
10 | public void fireWeapon() {
11 | this.enemyRobot.smashWithHands();
12 | }
13 |
14 | @Override
15 | public void driveForward() {
16 | this.enemyRobot.walkForward();
17 | }
18 |
19 | @Override
20 | public void assignDriver(String driver) {
21 | this.enemyRobot.reactToHuman(driver);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Bridge/README.md:
--------------------------------------------------------------------------------
1 | # 🌉 Bridge
2 |
3 | Bridge is a structural design pattern that lets you split a large class or a set of closely related classes into two separate hierarchies—abstraction and implementation—which can be developed independently of each other.
4 |
5 | ## Applicability
6 |
7 | Use the Bridge pattern when
8 |
9 | - you want to avoid a permanent binding between an abstraction and its implementation. This might be the case,for example,when the implementation
10 | must be selected or switched at run-time.
11 | - both the abstractions and their implementations should be extensible by
12 | subclassing. In this case, the Bridge pattern lets you combine the different
13 | abstractions and implementations and extend them independently.
14 | - changes in the implementation of an abstraction should have no impact on
15 | clients; that is, their code should not have to be recompiled.
16 |
17 | ## General Structure
18 |
19 |
20 |
21 |
22 |
23 | - Abstraction :
24 | - defines the abstraction's interface.
25 | - maintains a reference to an object of type Implementor.
26 | - RefinedAbstraction : Extends the interface defined by Abstraction.
27 | - Implementor : defines the interface for implementation classes. This interface doesn't
28 | have to correspond exactly to Abstraction's interface; in fact the two interfaces can be quite different. Typically the Implementor interface provides
29 | only primitive operations, and Abstraction defines higher-level operations
30 | based on these primitives.
31 | - Concretelmplementor : implements the Implementor interface and defines its concrete implementation.
32 |
33 | ## Example
34 |
35 | Consider you have a website with different pages and you are supposed to allow the user to change the theme. What would you do? Create multiple copies of each of the pages for each of the themes or would you just create separate theme and load them based on the user's preferences? Bridge pattern allows you to do the second i.e.
36 |
37 |
38 |
39 |
40 |
41 | The code source : [source folder](./src)
42 |
43 | ```Java
44 | public static void main(String []args){
45 |
46 | LightTheme lightTheme = new LightTheme();
47 | DarkTheme darkTheme = new DarkTheme();
48 |
49 | WebPage about = new About(lightTheme);
50 | WebPage careers = new Careers(DarkTheme);
51 |
52 | about.getContent();
53 | careers.getContent();
54 |
55 | }
56 |
57 | ```
58 |
59 | Output :
60 |
61 | ```
62 | About page in Light mode
63 | Careers page in Dark mode
64 | ```
65 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Bridge/src/About.java:
--------------------------------------------------------------------------------
1 | public class About extends WebPage {
2 |
3 | public About(Theme theme) {
4 | super(theme);
5 | }
6 |
7 | @Override
8 | public void getContent() {
9 | System.out.println("About page in " + theme.getColor());
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Bridge/src/Careers.java:
--------------------------------------------------------------------------------
1 | public class Careers extends WebPage {
2 |
3 | public Careers(Theme theme) {
4 | super(theme);
5 | }
6 |
7 | @Override
8 | public void getContent() {
9 | System.out.println("Careers page in " + theme.getColor());
10 | }
11 |
12 | }
--------------------------------------------------------------------------------
/patterns/structural-patterns/Bridge/src/DarkTheme.java:
--------------------------------------------------------------------------------
1 | public class DarkTheme implements Theme {
2 |
3 | @Override
4 | public String getColor() {
5 | return "Dark mode";
6 | }
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Bridge/src/LightTheme.java:
--------------------------------------------------------------------------------
1 | public class LightTheme implements Theme {
2 |
3 | @Override
4 | public String getColor() {
5 | return "Light mode";
6 | }
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Bridge/src/Theme.java:
--------------------------------------------------------------------------------
1 | public interface Theme {
2 |
3 | public String getColor();
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Bridge/src/WebPage.java:
--------------------------------------------------------------------------------
1 | public abstract class WebPage {
2 |
3 | protected Theme theme;
4 |
5 | public WebPage(Theme theme) {
6 | this.theme = theme;
7 | }
8 |
9 | public abstract void getContent();
10 |
11 | }
--------------------------------------------------------------------------------
/patterns/structural-patterns/Composite/README.md:
--------------------------------------------------------------------------------
1 | ## 🌿 Composite
2 |
3 | Composite is a structural design pattern that lets you compose objects into tree structures and then work with these structures as if they were individual objects.
4 |
5 | ## Applicablity
6 |
7 | Use the Composite pattern when
8 |
9 | - you want to represent part-whole hierarchies ofobjects.
10 | - you want clients to be able to ignore the difference between compositionsof
11 | objects and individual objects.Clients will treat all objectsin the composite
12 | structure uniformly.
13 |
14 | ## General structure
15 |
16 |
17 |
18 |
19 |
20 | - Component :
21 | - declares the interface for objectsin the composition.
22 | - implements default behavior for the interface common to all classes, as
23 | appropriate.
24 | - declares an interface for accessing and managing its child components.
25 | - (optional) defines an interface for accessing a component's parent in the
26 | recursive structure, and implements it if that's appropriate.
27 | - Leaf :
28 | - represents leaf objects in the composition. A leaf has no children.
29 | - defines behavior for primitive objects in the composition.
30 | - Composite :
31 | - defines behavior for components having children.
32 | - stores child components.
33 | - implements child-related operations in the Component interface.
34 | - Client :
35 | - manipulates objects in the composition through the Component interface.
36 |
37 | ## Example
38 |
39 | Every organization is composed of employees. Each of the employees has the same features i.e. has a salary, has some responsibilities, may or may not report to someone, may or may not have some subordinates etc.
40 |
41 |
42 |
43 |
44 |
45 | - Component : Employee
46 | - Leaf : Developer & Designer
47 | - Composite : Organization
48 |
49 | The code source : [source folder](./src)
50 |
51 | ```Java
52 | public static void main(String []args){
53 |
54 | Employee developerOne = new Developer(100, "Developer one", "Back-end");
55 | Employee developerTwo = new Developer(101, "Developer two", "FullStack");
56 | Employee designerUI = new Designer(201, "Designer one", "UI designer");
57 | Organization organization = new Organization();
58 | organization.addEmployee(developerOne);
59 | organization.addEmployee(developerTwo);
60 | organization.addEmployee(designerUI);
61 |
62 | organization.showEmployeeDetails();
63 |
64 | // delete developer Two
65 | System.out.println("----------------------");
66 | organization.removeEmployee(developerTwo);
67 |
68 | organization.showEmployeeDetails();
69 |
70 | }
71 |
72 | ```
73 |
74 | Output :
75 |
76 | ```
77 | 100- Developer one Back-end
78 | 101- Developer two FullStack
79 | 201- Designer one UI designer
80 | ----------------------
81 | 100- Developer one Back-end
82 | 201- Designer one UI designer
83 | ```
84 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Composite/src/Designer.java:
--------------------------------------------------------------------------------
1 | public class Designer implements Employee {
2 |
3 | private long id;
4 | private String name;
5 | private String position;
6 |
7 | public Designer(long id, String name, String position) {
8 | this.id = id;
9 | this.name = name;
10 | this.position = position;
11 | }
12 |
13 | @Override
14 | public void showEmployeeDetails() {
15 | System.out.println(id + "- " + name + " " + position);
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Composite/src/Developer.java:
--------------------------------------------------------------------------------
1 | public class Developer implements Employee {
2 |
3 | private long id;
4 | private String name;
5 | private String position;
6 |
7 | public Developer(long id, String name, String position) {
8 | this.id = id;
9 | this.name = name;
10 | this.position = position;
11 | }
12 |
13 | @Override
14 | public void showEmployeeDetails() {
15 | System.out.println(id + "- " + name + " " + position);
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/patterns/structural-patterns/Composite/src/Employee.java:
--------------------------------------------------------------------------------
1 | public interface Employee {
2 |
3 | void showEmployeeDetails();
4 | }
--------------------------------------------------------------------------------
/patterns/structural-patterns/Composite/src/Organization.java:
--------------------------------------------------------------------------------
1 | import java.util.ArrayList;
2 | import java.util.List;
3 |
4 | public class Organization implements Employee {
5 |
6 | private List employeeList = new ArrayList();
7 |
8 | @Override
9 | public void showEmployeeDetails() {
10 | for (Employee employee : employeeList) {
11 | employee.showEmployeeDetails();
12 | }
13 | }
14 |
15 | public void addEmployee(Employee employee) {
16 | employeeList.add(employee);
17 | }
18 |
19 | public void removeEmployee(Employee employee) {
20 | employeeList.remove(employee);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Decorator/README.md:
--------------------------------------------------------------------------------
1 | # ☕ Decorator
2 |
3 | Decorator is a structural design pattern that lets you attach new behaviors to objects by placing these objects inside special wrapper objects that contain the behaviors.
4 |
5 | ## Applicability
6 |
7 | Use Decorator
8 |
9 | - to add responsibilities to individual objects dynamically and transparently,
10 | that is, without affecting other objects.
11 | - forresponsibilities that canbe withdrawn.
12 | - when extension by subclassing is impractical. Sometimes a large number
13 | of independent extensions are possible and would produce an explosion of
14 | subclasses to support every combination. Or a class definition maybe hidden
15 | or otherwise unavailable for subclassing.
16 |
17 | ## General Structure
18 |
19 |
20 |
21 |
22 |
23 | - Component : defines the interface for objects that can have responsibilities added to them dynamically.
24 | - ConcreteComponent : defines an object towhich additional responsibilities canbe attached.
25 | - Decorator : maintains a reference to a Component object and defines an interface that conforms to Component's interface.
26 | - ConcreteDecorator : adds responsibilities to the component.
27 |
28 | ## Example
29 |
30 | For example we have a car mangement system , suppose we want to buy a basicCar but with more features like (speed regulator , AC , Navigation system ...)
31 |
32 |
33 |
34 |
35 |
36 | The code source : [source folder](./src)
37 |
38 | ```Java
39 | public static void main(String []args){
40 |
41 | Car basicCar = new BasicCar();
42 | System.out.println("Basic car : "+ basicCar.cost());
43 |
44 | basicCar = new AirConditioner(basicCar);
45 | System.out.println("Basic Car (with AirConditioner) : "+basicCar.cost());
46 |
47 | basicCar = new SpeedRegulator(basicCar);
48 | System.out.println("Basic Car (with AC and speed regulator) : "+basicCar.cost());
49 |
50 | }
51 |
52 | ```
53 |
54 | Output :
55 |
56 | ```
57 | Basic car : 1000.0
58 | Basic Car (with AirConditioner) : 1400.0
59 | Basic Car (with AC and speed regulator) : 1600.0
60 | ```
61 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Decorator/src/AirConditioner.java:
--------------------------------------------------------------------------------
1 | public class AirConditioner extends CarDecorator {
2 |
3 | public AirConditioner(Car car) {
4 | super(car);
5 | }
6 |
7 | @Override
8 | public double cost() {
9 | return car.cost() + 400;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Decorator/src/BasicCar.java:
--------------------------------------------------------------------------------
1 | public class BasicCar extends Car {
2 |
3 | public BasicCar() {
4 | description = "BasicCar";
5 | }
6 |
7 | @Override
8 | public double cost() {
9 | return 1000;
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Decorator/src/Car.java:
--------------------------------------------------------------------------------
1 | public abstract class Car {
2 |
3 | protected String description;
4 |
5 | public String getDescription() {
6 | return this.description;
7 | }
8 |
9 | public abstract double cost();
10 | }
--------------------------------------------------------------------------------
/patterns/structural-patterns/Decorator/src/CarDecorator.java:
--------------------------------------------------------------------------------
1 | public abstract class CarDecorator extends Car {
2 |
3 | protected Car car;
4 |
5 | public CarDecorator(Car car) {
6 | super();
7 | this.car = car;
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Decorator/src/SpeedRegulator.java:
--------------------------------------------------------------------------------
1 | public class SpeedRegulator extends CarDecorator {
2 |
3 | public SpeedRegulator(Car car) {
4 | super(car);
5 | }
6 |
7 | @Override
8 | public double cost() {
9 | return car.cost() + 200;
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Facade/README.md:
--------------------------------------------------------------------------------
1 | # 📦 Facade
2 |
3 | Facade is a structural design pattern that provides a simplified interface to a library, a framework, or any other complex set of classes.
4 |
5 | ## Applicability
6 |
7 | Use the Facadepattern when
8 |
9 | - you want to provide a simple interface to a complexsubsystem. Subsystems
10 | often get more complex as they evolve. Most patterns, when applied, result
11 | in more and smaller classes. This makes the subsystem more reusable and
12 | easier to customize, but it also becomes harder to use for clients that don't
13 | need to customize it. A facade can provide a simple default view of the
14 | subsystem that is good enough for most clients. Only clients needing more
15 | customizability will need to look beyond the facade.
16 | - there aremany dependencies between clients and theimplementation classes
17 | of an abstraction.Introduce a facade to decouple the subsystem from clients
18 | and other subsystems, thereby promoting subsystem independence and
19 | portability.
20 | - you want to layer your subsystems. Use a facade to define an entry point to
21 | each subsystem level. If subsystems are dependent, then you can simplify
22 | the dependencies between them by making them communicate with each
23 | other solely through their facades.
24 |
25 | ## General structure
26 |
27 |
28 |
29 |
30 |
31 | - Facade :
32 | - knows which subsystem classes are responsible for a request.
33 | - delegates client requests to appropriate subsystem objects.
34 | - subsystem classes :
35 | - implement subsystem functionality.
36 | - handle work assigned by the Facade object.
37 | - have no knowledge of the facade; that is, they keep no references to it.
38 |
39 | ## Example
40 |
41 | How do you turn on the computer? "Hit the power button" you say! That is what you believe because you are using a simple interface that computer provides on the outside, internally it has to do a lot of stuff to make it happen. This simple interface to the complex subsystem is a facade.
42 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Flyweight/README.md:
--------------------------------------------------------------------------------
1 | ## 🍃 Flyweight
2 |
3 | Flyweight is a structural design pattern that lets you fit more objects into the available amount of RAM by sharing common parts of state between multiple objects instead of keeping all of the data in each object.
4 |
5 | ## Applicability
6 |
7 | ## General structure
8 |
9 | ## Example
10 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/Proxy/README.md:
--------------------------------------------------------------------------------
1 | ## 🎱 Proxy
2 |
3 | Proxy is a structural design pattern that lets you provide a substitute or placeholder for another object. A proxy controls access to the original object, allowing you to perform something either before or after the request gets through to the original object.
4 |
5 | ## Applicability
6 |
7 | Proxy is applicable whenever there is a need for a more versatile or sophisticated
8 | reference to an object than a simple pointer.Here are several common situations
9 | in which the Proxy pattern is applicable:
10 |
11 | - Remote proxy provides a local representive for an in a different address space.
12 | - Virtual proxy creates expensive objects on demand.
13 | - Protection proxy controls access to the original object.
14 |
15 | ## General structure
16 |
17 |
18 |
19 |
20 |
21 | - Proxy :
22 | - maintains a reference that lets the proxy access the real subject. Proxy may
23 | refer to a Subject if the RealSubject and Subjectinterfaces are the same.
24 | - provides an interface identical to Subject's so that a proxy can by substituted for the real subject.
25 | - controls access to the real subject and may be responsible for creating and
26 | deleting it.
27 | - Subject :
28 | - defines the common interface for RealSubject and Proxy so that a Proxy
29 | can be used anywhere a RealSubject is expected.
30 | - RealSubject :
31 | - defines the real object that the proxy represents.
32 |
33 | ## Example
34 |
--------------------------------------------------------------------------------
/patterns/structural-patterns/README.md:
--------------------------------------------------------------------------------
1 | # Structural patterns
2 |
3 | Structural patterns explain how to assemble objects and classes into larger structures while keeping these structures flexible and efficient.
4 |
5 | ## Table of contents :
6 |
7 | | Scope | Class | Object |
8 | | ---------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
9 | | Structural | [Adapter](./Adapter) , | [Adapter](./Adapter) , [Bridge](./Bridge) , [Decorator](./Decorator) , [Composite](./Composite) , [Facade](./Facade) , [Flyweight](./Flyweight) , [Proxy](./Proxy) |
10 |
11 | ## Note :
12 |
13 | [Some further explanation about scope](../creational-patterns/README.md#note-)
14 |
--------------------------------------------------------------------------------