Design Patterns
Bilel Msekni
Who am I ?
Bilel Msekni
Tech Lead & Frontend Expert
"A general, reusable solution to a commonly occurring problem"
- Wikipedia
Singleton Pattern
(Creational)
Solution:
Create a class responsible for instanciating and returning the instance on subsequent calls.
Problem:
How can we guarantee that one and only one
instance of a class can be created?
Singleton Pattern
(Creational)
public sealed class Singleton {
private static readonly Singleton instance = new Singleton();
private Singleton() {}
public static Singleton Instance => instance
}
...
private static readonly object padlock = new object();
public static Singleton Instance {
get {
if (instance == null) {
lock(padlock) {
if (instance == null) instance = new Singleton();
}
}
return instance;
}
}
The good...
- A class has only a single instance.
- A global access point to that instance.
- Initialized only when it’s requested for the first time.
And the bad
- Violates the Single Responsibility Principle
- Special treatment in a multithreaded environment
- It may be difficult to unit test
Singleton Pattern
(Creational)
Facade Pattern
(Structural)
Problem:
How can we access a large number of classes with a complex internal interaction in a simple but safe way?
Solution:
Introduce a dedicated interface class that simplifies the view of the class collection
Facade Pattern
(Structural)
Suppliers
Payment
Delivery
...
Facade
Facade Pattern
(Structural)
public class Facade {
private Suppliers _suppliers;
private Payment _payment;
public Facade(Suppliers suppliers, Payment payment) {
this._suppliers = suppliers;
this._payment = payment;
}
public void Purchase(string id, int quantity) {
Command command = _suppliers.provision(id, quantity);
Payment payment = _payment.pay(command.Amount);
}
}
class Client {
public void Buy(Facade facade) {
string id = GetElementId();
int quantity = GetQuantity();
facade.Purchase(id, quantity);
}
}
class Client {
private Suppliers _suppliers;
private Payment _payment;
public Client(Suppliers suppliers, Payment payment) {
this._suppliers = suppliers;
this._payment = payment;
}
public void Buy(Facade facade) {
string id = GetElementId();
int quantity = GetQuantity();
Command command = _suppliers.provision(id, quantity);
Payment payment = _payment.pay(command.Amount);
}
}
The Good...
- Isolate the complexity of a subsystem
And the bad
- Over time a facade can evolve into a God Object.
Facade Pattern
(Structural)
- Use only what you need strategy
- The full capability of the underlying APIs will often not be available
Mediator Pattern
(Behavior)
Problem:
How can we deal with two or more classes which sometimes interact, but can also be used separately?
Solution:
Keep objects from referring to one another explicitly by puting each interaction between objects in a separate (Mediator) class.
Mediator Pattern
(Behavior)
Mediator Pattern
(Behavior)
Demo time
Mediator Pattern
(Behavior)
The Good...
- Single Responsibility Principle
And the bad
Over time a mediator can evolve into a God Object.
- Open/Closed Principle
- Reduce coupling between various components
To read
To watch
Thank you
Design patterns
By skible
Design patterns
- 33