Skip to content

Commit 1e09e8f

Browse files
authored
Merge pull request #5 from lemanh99/develop
Creational Design Patterns
2 parents 7d58085 + e02c965 commit 1e09e8f

30 files changed

+1413
-2
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,4 @@ cython_debug/
157157
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158158
# and can be added to the global gitignore or merged into this file. For a more nuclear
159159
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
160-
#.idea/
160+
.idea/

README.md

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,68 @@
1-
# design-pattern
1+
## Design Pattern With Python
2+
3+
Source: https://refactoring.guru/
4+
5+
6+
7+
## Catalog of Design Pattern
8+
9+
1. [Creational Design Patterns](creational-design-pattern)
10+
- [Factory Method](creational-design-pattern/factory-method)
11+
- [Abstract Factory](creational-design-pattern/abstract-factory)
12+
- [Builder](creational-design-pattern/builder)
13+
- [Prototype](creational-design-pattern/prototype)
14+
- [Singleton](creational-design-pattern/singleton)
15+
2. Structural Design Patterns
16+
- Adapter
17+
- Bridge
18+
- Composite
19+
- Decorator
20+
- Facade
21+
- Flyweight
22+
- Proxy
23+
3. Behavior Design Patterns
24+
- Chain of Responsibility
25+
- Command
26+
- Iterator
27+
- Mediator
28+
- Memento
29+
- Observer
30+
- State
31+
- Strategy
32+
- Template Method
33+
- Visitor
34+
35+
## Directory
36+
37+
```
38+
$ Design Pattern
39+
.
40+
├── ceational-design-pattern
41+
│ ├── factory-method
42+
│ ├── README.md
43+
│ ├── README-VI.md
44+
│ ├── main.py
45+
│ ├── example.py
46+
│ ├── abstract-method
47+
│ ├── README.md
48+
│ ├── README-VI.md
49+
│ ├── main.py
50+
│ ├── example.py
51+
│ ├── builder
52+
│ ├── README.md
53+
│ ├── README-VI.md
54+
│ ├── main.py
55+
│ ├── example.py
56+
│ ├── prototype
57+
│ ├── README.md
58+
│ ├── README-VI.md
59+
│ ├── main.py
60+
│ ├── example.py
61+
│ ├── singleton
62+
│ ├── README.md
63+
│ ├── README-VI.md
64+
│ ├── main.py
65+
│ ├── example.py
66+
└── README.md
67+
```
68+

SOLID/__init__.py

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
| Design Pattern | Định Nghĩa | Mục Đích Sử Dụng | Cách Sử Dụng |
2+
|--------------------------------------|--------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
3+
| [Factory Method](factory-method) | Cung cấp interface để tạo đối tượng, cho phép lớp con quyết định loại đối tượng cụ thể sẽ được tạo ra. | - Độc lập với lớp con cụ thể. - Mở rộng dễ dàng bằng cách thêm lớp con mới. | Định nghĩa giao diện hoặc lớp trừu tượng chứa Factory Method, sau đó triển khai Factory Method trong các lớp con. |
4+
| [Abstract Factory](abstract-factory) | Cung cấp interface để tạo các "families(họ)" đối tượng liên quan mà không cần biết lớp cụ thể nào. | - Duy trì tính nhất quán giữa các đối tượng liên quan. | Định nghĩa giao diện hoặc lớp trừu tượng cho Abstract Factory, sau đó triển khai interface này trong các lớp con. |
5+
| [Builder](builder) | Cho phép xây dựng đối tượng phức tạp step by step. | - Xây dựng đối tượng với nhiều thuộc tính hoặc tùy chọn khác nhau. | Tạo một lớp Builder cho đối tượng cần xây dựng, định nghĩa phương thức để thiết lập thuộc tính hoặc tùy chọn, và triển khai phương thức xây dựng đối tượng. |
6+
| [Prototype](prototype) | Cho phép tạo đối tượng mới bằng cách sao chép đối tượng đã tồn tại. | - Tạo nhiều bản sao của một đối tượng mà không cần tạo lại từ đầu. | Định nghĩa phương thức sao chép đối tượng hoặc triển khai interface Cloneable (nếu có). |
7+
| [Singleton](singleton) | Đảm bảo rằng chỉ có một đối tượng duy nhất của một lớp và cung cấp điểm truy cập toàn cục đến nó. | - Đảm bảo rằng chỉ có một phiên bản duy nhất của một lớp. - Chia sẻ đối tượng trong toàn bộ ứng dụng. | Triển khai lớp Singleton bằng cách đảm bảo rằng constructor là private và cung cấp một phương thức tĩnh để truy cập đối tượng Singleton. |

creational-design-pattern/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
| Design Pattern | Definition | Purpose of Use | How to Use |
2+
|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
3+
| [Factory Method](factory-method) | Provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created. | - Decouple from specific subclasses. - Easily extend by adding new subclasses. | Define an interface or abstract class containing the Factory Method, then implement the Factory Method in the subclasses. |
4+
| [Abstract Factory](abstract-factory) | Provides an interface for creating families of related or dependent objects without specifying their concrete classes. | - Maintain consistency among related objects. | Define an interface or abstract class for the Abstract Factory, then implement this interface in concrete classes. |
5+
| [Builder](builder) | Allows constructing a complex object step by step. | - Build objects with multiple attributes or options. | Create a Builder class for the object to be constructed, define methods for setting attributes or options, and implement a build method for constructing the object. |
6+
| [Prototype](prototype) | Allows creating new objects by copying an existing object. | - Create multiple copies of an object without recreating it from scratch. | Define a copy method for object copying or implement the Cloneable interface (if available). |
7+
| [Singleton](singleton) | Ensures that a class has only one instance and provides a global point of access to it. | - Ensure only one instance of a class. - Share the instance throughout the application. | Implement the Singleton class by ensuring the constructor is private and providing a static method to access the Singleton instance. |
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
## Source
2+
3+
https://refactoring.guru/design-patterns/abstract-method
4+
5+
## Cốt lõi:
6+
7+
> Abstract Factory là một mẫu thiết kế sáng tạo cho phép bạn tạo ra các families của các đối tượng liên quan mà không
8+
> cần chỉ định cụ thể lớp của chúng.
9+
10+
## Structure
11+
12+
![alt tag](abstract_factory.png)
13+
14+
Các bước tạo abstract method chính:
15+
16+
1. **Xác định một lớp trừu tượng (abstract class):** Đầu tiên, bạn cần tạo một lớp trừu tượng (abstract class). Lớp này
17+
sẽ chứa các abstract method mà các lớp con sau này phải triển khai.
18+
2. **Khai báo abstract method:** Trong lớp trừu tượng, bạn khai báo các abstract method bằng cách sử dụng từ khóa
19+
abstract trước phương thức mà bạn muốn là abstract. Điều này sẽ định nghĩa phương thức mà các lớp con phải triển
20+
khai. Abstract method không có thân phương thức (body) và chỉ có khai báo phương thức.
21+
3. **Triển khai abstract method trong các lớp con:** Các lớp con kế thừa từ lớp trừu tượng sẽ phải triển khai (
22+
implement) các abstract method được định nghĩa trong lớp trừu tượng. Điều này bắt buộc các lớp con phải cung cấp một
23+
triển khai cụ thể cho mỗi abstract method.
24+
25+
## Description
26+
27+
### Mục đích
28+
29+
Mục đích của abstract method trong design pattern là tạo ra một interface chung cho các lớp con để chúng có thể triển
30+
khai theo cách riêng biệt, tùy chỉnh cho nhu cầu cụ thể của từng lớp con. Abstract method là một phần quan trọng của các
31+
mẫu thiết kế (design patterns) như Factory Method Pattern, Template Method Pattern và Strategy Pattern.
32+
33+
Các lợi ích chính của việc sử dụng abstract method trong design pattern bao gồm:
34+
35+
1. **Tách rời các phần của hệ thống:** Abstract method cho phép bạn xác định các phần của hệ thống mà các lớp con cần
36+
triển khai. Điều này giúp tách rời các phần của hệ thống, giúp dễ dàng thay đổi hoặc mở rộng chúng mà không làm ảnh
37+
hưởng đến các phần khác.
38+
2. **Tích hợp linh hoạt:** Các lớp con có thể triển khai abstract method theo cách riêng biệt, cho phép tích hợp các
39+
phần mềm dễ dàng theo nhiều cách khác nhau mà không cần thay đổi mã nguồn của các lớp cha.
40+
3. **Tạo ra các mẫu chung:** Abstract method giúp xác định các mẫu chung trong các hệ thống phức tạp. Chúng là một phần
41+
quan trọng của các mẫu thiết kế, giúp tạo ra cách tiếp cận chung cho việc giải quyết các vấn đề cụ thể.
42+
4. **Mở rộng và bảo trì dễ dàng:** Abstract method cho phép bạn thêm mới các lớp con mà không cần thay đổi mã nguồn của
43+
các lớp cha, giúp dễ dàng mở rộng và bảo trì hệ thống.
44+
45+
Tóm lại, abstract method là một cơ chế quan trọng trong design pattern để giúp tạo ra các hệ thống linh hoạt, dễ bảo trì
46+
và mở rộng.
47+
48+
## Khi nào thì sử dụng abstract method
49+
50+
1. **Khi bạn muốn định nghĩa một interface chung:** Khi có một nhóm lớp có cùng một interface chung, nhưng mỗi lớp con
51+
có cách triển khai riêng biệt, bạn có thể sử dụng abstract methods để định nghĩa interface và yêu cầu các lớp con
52+
triển khai các phương thức cụ thể.
53+
2. **Khi bạn muốn áp dụng mẫu thiết kế Factory Method:** Factory Method Pattern sử dụng abstract methods để tạo đối
54+
tượng mà lớp cha không thể biết trước cụ thể lớp con nào cần được tạo.
55+
3. **Khi bạn muốn sử dụng Template Method Pattern:** Template Method Pattern sử dụng abstract method để xác định các
56+
bước cơ bản trong một thuật toán và để các lớp con triển khai các phần cụ thể của thuật toán.
57+
4. **Khi bạn muốn sử dụng Strategy Pattern:** Strategy Pattern sử dụng abstract method để định nghĩa một loạt các thuật
58+
toán và cho phép lựa chọn thuật toán cụ thể trong runtime.
59+
5. **Khi bạn muốn tạo các lớp cơ sở (base classes) không hoàn chỉnh:** Abstract methods cho phép bạn tạo các lớp cơ sở
60+
mà không cung cấp triển khai cụ thể cho một số phương thức, để bắt buộc các lớp con triển khai chúng.
61+
6. **Khi bạn muốn đảm bảo tính đồng nhất và tuân thủ trong hệ thống:** Abstract methods giúp đảm bảo rằng các lớp con
62+
phải triển khai các phương thức cụ thể, từ đó đảm bảo tính đồng nhất và tuân thủ trong hệ thống.
63+
64+
Tóm lại, bạn nên sử dụng Factory Method khi cần tạo đối tượng một cách linh hoạt, duy trì tính linh hoạt trong ứng dụng
65+
và giảm sự phụ thuộc vào lớp cụ thể.
66+
67+
## Running
68+
69+
```
70+
python main.py
71+
python example.py
72+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
## Source
2+
3+
https://refactoring.guru/design-patterns/abstract-factory
4+
5+
### Important:
6+
7+
> 1. Abstract Factory is a creational design pattern that lets you produce families of related objects without
8+
specifying their concrete classes.
9+
>
10+
> 2. Creates an instance of several families of classes
11+
12+
## Description
13+
14+
## Structure
15+
16+
![alt tag](abstract_factory.png)
17+
18+
## How to use
19+
20+
1. Use the Abstract Factory when your code needs to work with various families of related products, but you don’t want
21+
it to depend on the concrete classes of those products—they might be unknown beforehand or you simply want to allow
22+
for future extensibility.
23+
2. Consider implementing the Abstract Factory when you have a class with a set of Factory Methods that blur its primary
24+
responsibility.
25+
26+
## How to implement
27+
https://refactoring.guru/design-patterns/abstract-factory#checklist
28+
## Running
29+
30+
```
31+
python main.py
32+
python example.py
33+
```
Loading
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from abc import ABC, abstractmethod
2+
3+
4+
class Button(ABC):
5+
@abstractmethod
6+
def render(self):
7+
pass
8+
9+
10+
class WinButton(Button):
11+
def render(self):
12+
print("WinButton: Render a button in a Windows style.")
13+
14+
15+
class MacButton(Button):
16+
def render(self):
17+
print("MacButton: Render a button in a Mac style.")
18+
19+
20+
class Checkbox(ABC):
21+
@abstractmethod
22+
def render(self):
23+
pass
24+
25+
26+
class WinCheckbox(Checkbox):
27+
def render(self):
28+
print("WinCheckbox: Render a checkbox in a Windows style.")
29+
30+
31+
class MacCheckbox(Checkbox):
32+
def render(self):
33+
print("MacCheckbox: Render a checkbox in a Mac style.")
34+
35+
36+
class GUIFactory(ABC):
37+
@abstractmethod
38+
def create_button(self):
39+
pass
40+
41+
@abstractmethod
42+
def create_checkbox(self):
43+
pass
44+
45+
46+
class WinFactory(GUIFactory):
47+
def create_button(self):
48+
return WinButton()
49+
50+
def create_checkbox(self):
51+
return WinCheckbox()
52+
53+
54+
class MacFactory(GUIFactory):
55+
def create_button(self):
56+
return MacButton()
57+
58+
def create_checkbox(self):
59+
return MacCheckbox()
60+
61+
62+
class Application(ABC):
63+
def __init__(self, factory: GUIFactory):
64+
self._factory = factory
65+
self.button = None
66+
self.checkbox = None
67+
68+
def create_ui(self):
69+
self.button = self._factory.create_button()
70+
self.checkbox = self._factory.create_checkbox()
71+
72+
def paint(self):
73+
self.button.render()
74+
self.checkbox.render()
75+
76+
77+
if __name__ == "__main__":
78+
print("Configuring Windows application...")
79+
application = Application(WinFactory())
80+
application.create_ui()
81+
application.paint()
82+
83+
print("Configuring Mac application...")
84+
application = Application(MacFactory())
85+
application.create_ui()
86+
application.paint()
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from abc import ABC, abstractmethod
2+
3+
4+
class AbstractProductA(ABC):
5+
@abstractmethod
6+
def useful_func_a(self) -> str:
7+
pass
8+
9+
10+
class ConcreteProductA1(AbstractProductA):
11+
def useful_func_a(self) -> str:
12+
return "ConcreteProductA1: The result of the product A1."
13+
14+
15+
class ConcreteProductA2(AbstractProductA):
16+
17+
def useful_func_a(self) -> str:
18+
return "ConcreteProductA2: The result of the product A2."
19+
20+
21+
class AbstractProductB(ABC):
22+
@abstractmethod
23+
def useful_func_b(self) -> str:
24+
pass
25+
26+
@abstractmethod
27+
def another_useful_func_b(self, collaborator: AbstractProductA) -> None:
28+
pass
29+
30+
31+
class ConcreteProductB1(AbstractProductB):
32+
def useful_func_b(self) -> str:
33+
return "ConcreteProductB1: The result of the product B1."
34+
35+
def another_useful_func_b(self, collaborator: AbstractProductA) -> str:
36+
result = collaborator.useful_func_a()
37+
return f"The result of the B1 collaborating with: ({result})"
38+
39+
40+
class ConcreteProductB2(AbstractProductB):
41+
def useful_func_b(self) -> str:
42+
return "ConcreteProductB2: The result of the product B2."
43+
44+
def another_useful_func_b(self, collaborator: AbstractProductA) -> str:
45+
result = collaborator.useful_func_a()
46+
return f"The result of the B2 collaborating with: ({result})"
47+
48+
49+
class AbstractFactory(ABC):
50+
@abstractmethod
51+
def create_product_a(self) -> AbstractProductA:
52+
pass
53+
54+
@abstractmethod
55+
def create_product_b(self) -> AbstractProductB:
56+
pass
57+
58+
59+
class ConcreteFactory1(AbstractFactory):
60+
def create_product_a(self) -> AbstractProductA:
61+
return ConcreteProductA1()
62+
63+
def create_product_b(self) -> AbstractProductB:
64+
return ConcreteProductB1()
65+
66+
67+
class ConcreteFactory2(AbstractFactory):
68+
def create_product_a(self) -> AbstractProductA:
69+
return ConcreteProductA2()
70+
71+
def create_product_b(self) -> AbstractProductB:
72+
return ConcreteProductB2()
73+
74+
75+
class ClientCode:
76+
def __init__(self, factory: AbstractFactory) -> None:
77+
self._factory = factory
78+
79+
def some_operation(self) -> None:
80+
product_a = self._factory.create_product_a()
81+
product_b = self._factory.create_product_b()
82+
83+
print(f"{product_b.useful_func_b()}")
84+
print(f"{product_b.another_useful_func_b(product_a)}", end="")
85+
86+
87+
if __name__ == "__main__":
88+
print("Client: Testing client code with the first factory type:")
89+
ClientCode(ConcreteFactory1()).some_operation()
90+
print("\n")
91+
92+
print("Client: Testing the same client code with the second factory type:")
93+
ClientCode(ConcreteFactory2()).some_operation()

0 commit comments

Comments
 (0)