- This project was created to learn and reaffirm knowledge related to design pattern. Was used java to create some examples and this file to try gather all definitions related to the several existent design patterns
Design patterns are generics projects solutions to solve recurring problems in object orient development
The basic idea of this pattern is to be a behavioral design patter that you to select easily a concrete algorithm in your application from a previously set of algorithms used on that specific process.
Another good and straight definition is from the ‘Gang of Four’ book: “The Strategy Pattern is used to create an interchangeable family of algorithms from which the required process is chosen at run-time”.
So this pattern approach is used when you have many possible algorithms for one action, like when you are calculating taxes or different types of fees you can separate each one possible algorithm in a different class.
Basic structure example of this pattern
- First will make your code more clean because you will avoid using to many conditional statements;
- And even more clean code as you will separate the concerns into different classes.
- Will be more easy to switch between the different strategies/algorithms because you will be implementing polymorphism in the interfaces.
- You can apply the Open/Closed Principle, because you will be able to implement new strategies without having to change the context
Also known as: CoR, Chain of Command
Chain of Responsibility is a behavioral design pattern that allows you to route requests to a series of handlers. After receiving a request, each handler decides whether to process the request or forward it to the next handler in the chain.
So this pattern relies on transforming specific behaviors into stand-alone objects called handlers. And this pattern also suggest that you link those handles into a chain. Each chained handler has a field that stores a reference to the next handler in the chain. The request travels down the chain until all handlers have had a chance to process it. But the "best part" is that each handler can decide not to pass the request further down the chain and effectively stop any further processing.
Example from the Refactoring Guru using a process of a request to a ordering system
- You can control the order in which requests are processed
- This pattern will lead you to implement two SOLID principles as well more easily
- One of than will be the Single Responsibility Principle. This principle will be achieved as you decouple classes that are invoked from classes that are performing your operations.
- Another principle is the Open/Closed Principle, as you will be able to implement more handlers and into your application without breaking existing code/process.
Basic structure example of this pattern
- The Handler will declare the interface common for all concrete handlers, he can have a method for setting the next handler of the chain but in many cases he will only have a single method for handling the request.
- The Base Handler is not implemented always but all the boilerplate code that are used in all classes can be stored here.
- The Concrete Handlers will be the response for the actual code for processing requests. Each of then must decide whether to finish the process of it or pass it for the next knot of the chain.
- The Client will be responsible to compose the chain, he will be able to choose witch part of the chain will be iterated, and note that after ours previous steps we can initiate the chain from any point.
This design pattern is used to define a skeleton of an algorithm in a superclass but let her subclasses overwrite those methods for specifics steps os algorithms that will be need to implement all the business logic.
- So this pattern is mostly used when we have an abstract class where all its subclasses have a lot of implementations in common, so we can break down an algorithm into a series of steps, turn these steps into methods, and put the call to these methods inside a single template method.
Basic structure example of this pattern
- The Abstract Class will declare all the steps used in to complete algorithm/business rules as abstract to the subclasses can implement they, and will have the templateMethod() that will call all the abstract steps implemented in the subclasses;
- The Concrete Classes are the subclasses that will be overriding the steps used in the templateMethod.
- You will be able to override only certain parts of a large algorithm, so will be less affected by changes in other parts of the system.
- You can pull the duplicate code into a superclass.
State is a pattern that lets an object alter his behavior when its internal state changes. It appears almost like an object changed his class. A real world example of this pattern is like the buttons of a smartphone, they can change their behavior depending on the state of the phone
- So the main idea is that on a system with a finite numbers of a state in a program, you will be able to work around with those states without having to write many IFs to do that.
Basic structure example of this pattern
- Context will reference to one concrete state object and delegates to state-explicit work. this class speaks with the state object through the state interface. He will be able to set another state of the object.
- The State interface proclaims the state-explicit techniques. These techniques should appear to be legit for all substantial states since you don't want to have useless code in your abstract/interface class that will be implemented by all of his children classes
- Concrete states provide their own implementations for state-specific methods. To avoid repeating similar code across states, you can provide abstract intermediate classes that encapsulate some common behavior.
- Both the context and the concrete state can set the next state of the context and perform the actual state transition by replacing the state object associated with the context.
- Will let you organize code related to specific states of the object in different classes, so will be applying the Single Responsibility Principle.
- Let you add new states without changing an existing state or class so will be applying the Open/Closed Principle.
- Simplify your code by eliminating a bunch of state conditionals that would have to be implemented.
Also known as: Action, Transaction
Command is a behavior design pattern that transform a request in a stand-alone object with all the data that will let the programmer use those arguments to pass requests as a method arguments, to queue or delay a request’s execution, and support reversible operations
A good way to use this pattern is in systems with different entry points like a system interface or API's, and you can implement the command pattern to let all this entry points get in a common class to process that data "equally".
Basic structure example of this pattern
- The Invoker/Sender class will be responsible for the start of the request, he must have as well a field referencing to a command object. So the sender will call this class instead the receiver. And usually he will already have the command object, so he will not create him here.
- The Command interface will usually just declare a single method for executing. that will be handled by his "child classes".
- Those classes who implemented the command interface will implement various kinds of requests. They normally will not perform the work on its own, instead they will use for example Injected classes to do the "hard work", in the example above they are using a receiver.
- The Receiver class contains some business logic. Almost any object can act as a receiver. Most commands only handle the details of how to route requests to receivers, while the receivers do the actual work themselves.
- Clients create and configure concrete command objects. The client must pass all request parameters, including the receiver instance, to the command's constructor. Afterwards, the generated commands can be distributed to one or more senders.
- Will be applying the Single Responsibility Principle of the SOLID principals, because will in be able to decouple classes that invoke operations from classes that perform these operations, and even decouple the classes that will have the proprieties of the object.
- Another SOLID principle that will be achieved by this pattern is the Open/Closed Principle. because will let you introduce new process into the app without breaking any existing feature.
- Let you implement undo/redo, and assemble a set of simple commands into a complex one.
Also known as: Event-Subscriber, Listener
Observer is a behavioral design pattern that will let the programmer define a subscription mechanism that will notify those subscribed objects about changes that happened on the object that they’re observing.
A simple example of a problem where the observer can be used are on the wait list of a product, lets imagine that you want to buy the Steam deck but the store don't have one yet, they can "add" you in their list of observers of that product and when he came back to stock the store can email you warning that, without having to email every customer of the store, they will be able to only notify those who are interested by using a structure very similar to an observer.
Basic structure example of this pattern
- The Publisher call the events of interest to other objects that are subscribed. These events are triggered when the publisher changes its state or executes some behaviors. Publishers let new subscribers join and current subscribers leave the list.
- When a new event is raised, the publisher iterates over the subscription list and calls the notification method declared in the subscriber interface for each subscriber object.
- The subscriber interface declares the notification interface. In most cases it consists of an update method. The method can have several parameters, allowing the publisher to pass some event details along with the update.
- A specific subscriber performs some action in response to a notification from a publisher. All these classes must implement the same interface so that the publisher does not depend on the concrete class.
- will most likely need some contextual information to handle updates properly. Therefore, publishers often pass some data as parameters. The publisher can pass itself as a parameter, so the subscriber can get all the data it needs directly.
- The client creates publisher and subscriber objects separately, then registers subscribers for publisher updates
- Let introduce new subscriber classes without breaking any existing feature.
- Let establish relations between objects at runtime.
Also known as: Wrapper
"Observer is a structural design pattern that allows objects with incompatible interfaces to collaborate". REFECTORING GURU
The Adapter pattern can be used literary like power adapter, imagine that you have a market monitoring app. Your app uses multiples sources to get prices since stocks to bitcoin prices, and each api export their data in different formats, so to use those different data you can implement an adapter interface to handle casting of that external data.
Basic structure example of this pattern
- A client is a class that contains the existing business logic of the program.
- The client interface describes the protocol that other classes must follow in order to interact with client code.
- The service is usually third-party or legacy. Clients will not be able to use this class directly because it has an incompatible interface. Here we would have for example a class for an HTTP call.
- An adapter is a class connect the clients and services.He will implement the client interface while handling the service object. The adapter receives calls from clients through the adapter interface and translates them into calls to packaged service objects in a format it understands.
- This can be useful when you want or have to change the interface of the service, because you can just add a new adapter class without changing the client code.
- Single Responsibility Principle. You can divide the data conversion code and interface from the main business logic code of the system.
- Open/Closed Principle. You can just add a new adapter class without changing the client code. .
Decorator is a structural design pattern, he let you add new behaviors to objects, to do that you basically will have to place these objects in a special kind of wrapper objects that will have the extras behaviors.
Basic structure example of this pattern
- The Component will be the interface used in both the wrappers and wrapped objects
- Concrete Component will be the classes that are being wrapped. So they will have the basic behavior that can/will latter be altered by decorators
- The Base Decorator will be responsible to have a reference to the wrapped object. The reference will be typed as the component interface, so it will be able to contain both concrete components and decorators.
- Concrete Decorators defines extra behaviors that can be added to components dynamically. They override methods from the base decorator and execute their behavior either before or after calling the parent method.
- Client will wrap components in multiple layers of decorators.
- As you can divide a class that implements some behavior into several smaller classes you will be applying the Single Responsibility Principle
- Allows you to combine many behaviors by wrapping an object into multiple decorators.
- Allows you to add or remove responsibilities from an object at runtime.
- Allows you to extend an object’s behavior without making a new subclass.
Also known as: Object Tree
Composite is a structural design pattern that allows you to create a tree of structures combining objects together and then use these structures as if they were individual objects.
Basic structure example of this pattern
- The Component interface will have the common operations in both simplex and complex elements of the three.
- Leaf is a basic element of the tree that doesn’t have sub-elements, and because of that he usually end up doing most of the work, because he doesn't have anyone to delegate that work.
- The Container/Composite is the element with sub-elements. He doesn't know the concrete classes of his sub-elements, but he works with all of than thanks to the component interface
- The Client will all interact with all elements through the component interface
- Allow the programmer to work with complex tree structures more easily, using polymorphism and recursion.
- Let you introduce new element types into the app without breaking the existing code, os is applying the Open/Closed Principle
Facade is a structural design pattern that provides a simple interface for a project. Is used in cases when you have many subprocess and will not be good if you had to declare all then to complete your desired action, so you can create a simple interface to all your complex subsystem/subclasses execute all of your desired process more easily.
Another good and simple example of how can you implement this patter is in a bank system where you have the transference process, so you will have to do several validations and after that you will make the effective transference, to do that you can use facade, you can implement a simple interface that will be used for all parts of the validation and transference process, than you just have to provide all data needed and send to execute.
Basic structure example of this pattern
- Facades provide easy access to specific subsystem functionality. It knows where to direct the customer's requirements and how to handle all the moving parts.
- The Additional Facade class can be created to prevent a single appearance from being polluted by unrelated features, which could make it another complex structure. Other facades can be used by clients and other façades.
- Complex subsystems consist in many of different classes, all then will probably to do something useful, you need to dig into the implementation details of the subsystem in order to initialize the correct objects in the correct order, and provide all the data in the correct format to everything work almost like an orchestra.
- After all the Client will be able to call only the Facade instead of having to call all the subsystems directly
- Allow you to isolate your code from the complexity of your subprocess.
A proxy is a structural design patter that let you provide placeholders or replacements for another objects. The proxy will also allow you to access the original object and perform certain process after or before the request come back to the original object
Basic structure example of this pattern
- The service interface declares the interface of the service. A proxy must conform to this interface in order to pretend to be a service object.
- The service is a class that provides useful business logic.
- The proxy class has a reference field that points to the service object. After the proxy completes its processing (such as lazy initialization, logging, access control, caching, etc.), it forwards the request to the service object. Typically, a proxy manages the entire lifecycle of its service objects.
- Clients should use both the service and the proxy on the same interface. This allows you to pass proxies to any code that needs a service object.
- Allow you to isolate your code from the complexity of your subprocess.
Strategy - https://refactoring.guru/design-patterns/strategy
Chain of Responsibility - https://refactoring.guru/design-patterns/chain-of-responsibility
Template Method - https://refactoring.guru/design-patterns/template-method \
Command - https://refactoring.guru/design-patterns/command
Observer - https://refactoring.guru/design-patterns/observer
Adapter - https://refactoring.guru/design-patterns/adapter
Composite - https://refactoring.guru/design-patterns/composite
Facade - https://refactoring.guru/design-patterns/facade
Proxy - https://refactoring.guru/design-patterns/proxy