Skip to content

Commit 2ad340f

Browse files
authored
More patterns (#3)
* more patterns * typo
1 parent 0fbe2a2 commit 2ad340f

11 files changed

+2196
-1
lines changed

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ which it occurs is essential for choosing the most appropriate design pattern, u
5555

5656
| Pattern | Description |
5757
| ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
58+
| [Abstract Factory Pattern](docs/Abstract-Factory.md) | The abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. |
5859
| [Adapter Pattern](docs/Adapter.md) | The adapter pattern allows incompatible interfaces to work together by converting the interface of one class into another expected by the client. |
60+
| [Bridge Pattern](docs/Bridge.md) | The bridge pattern decouples an abstraction from its implementation so that the two can vary independently. |
5961
| [Builder Pattern](docs/Builder.md) | The builder pattern simplifies the construction of complex objects by separating the construction process from the final representation. |
6062
| [Chain of Responsibility Pattern](docs/Chain-of-Responsibility.md) | The chain of responsibility pattern delegates commands to a chain of processing objects, allowing multiple objects a chance to handle the request. |
6163
| [Command Pattern](docs/Command.md) | The command pattern encapsulates a request as an object, allowing for parameterization, queuing, logging, and supporting undoable operations. |
@@ -64,11 +66,18 @@ which it occurs is essential for choosing the most appropriate design pattern, u
6466
| [Facade Pattern](docs/Facade.md) | The facade pattern provides a simplified interface to a complex subsystem, making it easier for clients to interact with the system. |
6567
| [Factory Pattern](docs/Factory.md) | The factory pattern defines an interface for creating objects but allows subclasses to alter the type of objects that will be created. |
6668
| [Flyweight Pattern](docs/Flyweight.md) | The flyweight pattern reduces the cost of creating and managing a large number of similar objects by sharing as much data as possible. |
69+
| [Interpreter Pattern](docs/Interpreter.md) | The interpreter pattern defines a grammatical representation for a language and provides an interpreter to deal with this grammar. |
6770
| [Iterator Pattern](docs/Iterator.md) | The iterator pattern provides a way to access elements of an aggregate object sequentially without exposing its underlying representation. |
71+
| [Mediator Pattern](docs/Mediator.md) | The mediator pattern defines an object that encapsulates how a set of objects interact, promoting loose coupling. |
72+
| [Memento Pattern](docs/Memento.md) | The memento pattern captures and externalizes an object's internal state without violating encapsulation, so the object can be restored to this state later. |
6873
| [Observer Pattern](docs/Observer.md) | The observer pattern defines a one-to-many dependency so that when one object changes state, all its dependents are notified and updated automatically. |
74+
| [Prototype Pattern](docs/Prototype.md) | The prototype pattern creates new objects by copying an existing object, known as the prototype. |
6975
| [Proxy Pattern](docs/Proxy.md) | The proxy pattern provides a surrogate or placeholder for another object to control access to it, enhancing control over the underlying object. |
7076
| [Singleton Pattern](docs/Singleton.md) | The singleton pattern ensures a class has only one instance and provides a global point of access to it, managing shared resources efficiently. |
77+
| [State Pattern](docs/State.md) | The state pattern allows an object to alter its behaviour when its internal state changes, appearing as if the object changed its class. |
7178
| [Strategy Pattern](docs/Strategy.md) | The strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable, allowing the algorithm to vary independently from the clients that use it. |
79+
| [Template Method Pattern](docs/Template-Method.md) | The template method pattern defines the skeleton of an algorithm, deferring some steps to subclasses. |
80+
| [Visitor Pattern](docs/Visitor.md) | The visitor pattern separates an algorithm from the objects on which it operates, allowing new operations to be added without modifying the objects. |
7281

7382
<br />
7483
<p align="right"><a href="https://wolfsoftware.com/"><img src="https://img.shields.io/badge/Created%20by%20Wolf%20on%20behalf%20of%20Wolf%20Software-blue?style=for-the-badge" /></a></p>

docs/Abstract-Factory.md

+262
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
## Abstract Factory Pattern
2+
3+
The abstract factory pattern is a creational design pattern that allows the creation of objects without specifying their exact class. It
4+
provides an interface for creating families of related or dependent objects, ensuring that the created objects are compatible. This pattern
5+
promotes consistency among products and is particularly useful when the system needs to be independent of how its products are created,
6+
composed, and represented.
7+
8+
### Go Example
9+
10+
```go
11+
package main
12+
13+
import "fmt"
14+
15+
// AbstractFactory
16+
type ShoeFactory interface {
17+
MakeShoe() Shoe
18+
}
19+
20+
// ConcreteFactory1
21+
type NikeFactory struct{}
22+
23+
func (n *NikeFactory) MakeShoe() Shoe {
24+
return &NikeShoe{}
25+
}
26+
27+
// ConcreteFactory2
28+
type AdidasFactory struct{}
29+
30+
func (a *AdidasFactory) MakeShoe() Shoe {
31+
return &AdidasShoe{}
32+
}
33+
34+
// AbstractProduct
35+
type Shoe interface {
36+
GetLogo() string
37+
}
38+
39+
// ConcreteProduct1
40+
type NikeShoe struct{}
41+
42+
func (n *NikeShoe) GetLogo() string {
43+
return "Nike"
44+
}
45+
46+
// ConcreteProduct2
47+
type AdidasShoe struct{}
48+
49+
func (a *AdidasShoe) GetLogo() string {
50+
return "Adidas"
51+
}
52+
53+
func main() {
54+
nikeFactory := &NikeFactory{}
55+
adidasFactory := &AdidasFactory{}
56+
57+
nikeShoe := nikeFactory.MakeShoe()
58+
adidasShoe := adidasFactory.MakeShoe()
59+
60+
fmt.Println(nikeShoe.GetLogo()) // Output: Nike
61+
fmt.Println(adidasShoe.GetLogo()) // Output: Adidas
62+
}
63+
```
64+
65+
### Perl Example
66+
67+
```perl
68+
package ShoeFactory;
69+
70+
use strict;
71+
use warnings;
72+
73+
sub make_shoe { die "Abstract method" }
74+
75+
package NikeFactory;
76+
use parent 'ShoeFactory';
77+
78+
sub make_shoe {
79+
return NikeShoe->new();
80+
}
81+
82+
package AdidasFactory;
83+
use parent 'ShoeFactory';
84+
85+
sub make_shoe {
86+
return AdidasShoe->new();
87+
}
88+
89+
package Shoe;
90+
91+
sub get_logo { die "Abstract method" }
92+
93+
package NikeShoe;
94+
use parent 'Shoe';
95+
96+
sub new { bless {}, shift }
97+
98+
sub get_logo { return "Nike" }
99+
100+
package AdidasShoe;
101+
use parent 'Shoe';
102+
103+
sub new { bless {}, shift }
104+
105+
sub get_logo { return "Adidas" }
106+
107+
package main;
108+
109+
my $nike_factory = NikeFactory->new();
110+
my $adidas_factory = AdidasFactory->new();
111+
112+
my $nike_shoe = $nike_factory->make_shoe();
113+
my $adidas_shoe = $adidas_factory->make_shoe();
114+
115+
print $nike_shoe->get_logo(), "\n"; # Output: Nike
116+
print $adidas_shoe->get_logo(), "\n"; # Output: Adidas
117+
```
118+
119+
### Python Example
120+
121+
```python
122+
from abc import ABC, abstractmethod
123+
124+
class Shoe(ABC):
125+
@abstractmethod
126+
def get_logo(self):
127+
pass
128+
129+
class NikeShoe(Shoe):
130+
def get_logo(self):
131+
return "Nike"
132+
133+
class AdidasShoe(Shoe):
134+
def get_logo(self):
135+
return "Adidas"
136+
137+
class ShoeFactory(ABC):
138+
@abstractmethod
139+
def make_shoe(self):
140+
pass
141+
142+
class NikeFactory(ShoeFactory):
143+
def make_shoe(self):
144+
return NikeShoe()
145+
146+
class AdidasFactory(ShoeFactory):
147+
def make_shoe(self):
148+
return AdidasShoe()
149+
150+
nike_factory = NikeFactory()
151+
adidas_factory = AdidasFactory()
152+
153+
nike_shoe = nike_factory.make_shoe()
154+
adidas_shoe = adidas_factory.make_shoe()
155+
156+
print(nike_shoe.get_logo()) # Output: Nike
157+
print(adidas_shoe.get_logo()) # Output: Adidas
158+
```
159+
160+
### Ruby Example
161+
162+
```ruby
163+
class Shoe
164+
def get_logo
165+
raise 'Abstract method'
166+
end
167+
end
168+
169+
class NikeShoe < Shoe
170+
def get_logo
171+
'Nike'
172+
end
173+
end
174+
175+
class AdidasShoe < Shoe
176+
def get_logo
177+
'Adidas'
178+
end
179+
end
180+
181+
class ShoeFactory
182+
def make_shoe
183+
raise 'Abstract method'
184+
end
185+
end
186+
187+
class NikeFactory < ShoeFactory
188+
def make_shoe
189+
NikeShoe.new
190+
end
191+
end
192+
193+
class AdidasFactory < ShoeFactory
194+
def make_shoe
195+
AdidasShoe.new
196+
end
197+
end
198+
199+
nike_factory = NikeFactory.new
200+
adidas_factory = AdidasFactory.new
201+
202+
nike_shoe = nike_factory.make_shoe
203+
adidas_shoe = adidas_factory.make_shoe
204+
205+
puts nike_shoe.get_logo # Output: Nike
206+
puts adidas_shoe.get_logo # Output: Adidas
207+
```
208+
209+
### Rust Example
210+
211+
```rust
212+
trait Shoe {
213+
fn get_logo(&self) -> &str;
214+
}
215+
216+
struct NikeShoe;
217+
218+
impl Shoe for NikeShoe {
219+
fn get_logo(&self) -> &str {
220+
"Nike"
221+
}
222+
}
223+
224+
struct AdidasShoe;
225+
226+
impl Shoe for AdidasShoe {
227+
fn get_logo(&self) -> &str {
228+
"Adidas"
229+
}
230+
}
231+
232+
trait ShoeFactory {
233+
fn make_shoe(&self) -> Box<dyn Shoe>;
234+
}
235+
236+
struct NikeFactory;
237+
238+
impl ShoeFactory for NikeFactory {
239+
fn make_shoe(&self) -> Box<dyn Shoe> {
240+
Box::new(NikeShoe)
241+
}
242+
}
243+
244+
struct AdidasFactory;
245+
246+
impl ShoeFactory for AdidasFactory {
247+
fn make_shoe(&self) -> Box<dyn Shoe> {
248+
Box::new(AdidasShoe)
249+
}
250+
}
251+
252+
fn main() {
253+
let nike_factory = NikeFactory;
254+
let adidas_factory = AdidasFactory;
255+
256+
let nike_shoe = nike_factory.make_shoe();
257+
let adidas_shoe = adidas_factory.make_shoe();
258+
259+
println!("{}", nike_shoe.get_logo()); // Output: Nike
260+
println!("{}", adidas_shoe.get_logo()); // Output: Adidas
261+
}
262+
```

0 commit comments

Comments
 (0)