Skip to content

Commit 91b7826

Browse files
committed
Add Singleton pattern example
1 parent e5f82f8 commit 91b7826

File tree

11 files changed

+706
-23
lines changed

11 files changed

+706
-23
lines changed

localization/zh-TW/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
熟悉了這些概念,就可以透過以下任一種方式深入研究可用的設計模式:
2626

27-
- 依名稱搜尋特定模式。找不到的話?[在這裡](https://github.com/iluwatar/java-design-patterns/issues)回報新模式。
27+
- 依名稱搜尋特定模式。找不到的話?[在這裡](https://github.com/iluwatar/java-design-patterns/issues)回報新模式。
2828
- 使用難度標籤: `Performance(效能)``Gang of Four(四人幫)``Data access(資料存取)`
2929
- 使用模式分類`Creational(建立型)``Behavioral(行為型)`和其他类别。
3030

localization/zh/abstract-document/README.md renamed to localization/zh-TW/abstract-document/README.md

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,34 @@
22
title: Abstract Document
33
shortTitle: Abstract Document
44
category: Structural
5-
language: zh
5+
language: zh-TW
66
tag:
77
- Extensibility
88
---
99

1010
## 目的
1111

12-
使用动态属性,并在保持类型安全的同时实现非类型化语言的灵活性
12+
使用動態屬性,並在保持型別安全的同時實現非型別化語言的靈活性
1313

14-
## 解释
14+
## 解釋
1515

16-
抽象文档模式使您能够处理其他非静态属性。 此模式使用特征的概念来实现类型安全,并将不同类的属性分离为一组接口
16+
抽象文件模式 (Abstract Document Pattern) 使您能夠處理其他非靜態屬性。此模式使用特性 (trait) 的概念來實現型別安全,並將不同類別的屬性分離為一組介面
1717

18-
真实世界例子
18+
真實世界範例
1919

20-
> 考虑由多个部分组成的汽车。 但是,我们不知道特定汽车是否真的拥有所有零件,或者仅仅是零件中的一部分。 我们的汽车是动态而且非常灵活的
20+
> 考慮由多個部分組成的汽車。但是,我們不知道特定汽車是否真的擁有所有零件,或者僅僅是零件中的一部分。我們的汽車是動態而且非常靈活的
2121
22-
通俗的说
22+
簡單的說
2323

24-
> 抽象文档模式允许在对象不知道的情况下将属性附加到对象
24+
> 抽象文件模式允許在物件不知道的情況下將屬性附加到物件上
2525
26-
维基百科说
26+
維基百科說
2727

28-
> 面向对象的结构设计模式,用于组织松散类型的键值存储中的对象并使用类型化的视图公开数据。 该模式的目的是在强类型语言中实现组件之间的高度灵活性,在这种语言中,可以在不丢失类型安全支持的情况下,将新属性动态地添加到对象树中。 该模式利用特征将类的不同属性分成不同的接口
28+
> 物件導向的結構設計模式,用於組織鬆散型別的鍵值儲存中的物件,並使用型別化的視圖公開資料。該模式的目的是在強型別語言中實現元件之間的高度靈活性,在這種語言中,可以在不遺失型別安全支援的情況下,將新屬性動態地新增到物件樹中。該模式利用特性 (trait) 將類別的不同屬性分成不同的介面
2929
30-
**程序示例**
30+
**程式碼範例**
3131

32-
让我们首先定义基类`Document``AbstractDocument`它们基本上使对象拥有属性映射和任意数量的子对象
32+
讓我們先定義基礎類別`Document``AbstractDocument`它們基本上使物件擁有屬性對映 (map) 和任意數量的子物件
3333

3434
```java
3535
public interface Document {
@@ -74,7 +74,7 @@ public abstract class AbstractDocument implements Document {
7474
...
7575
}
7676
```
77-
接下来,我们定义一个枚举“属性”和一组类型,价格,模型和零件的接口。 这使我们能够为Car类创建静态外观的界面
77+
接下來,我們定義一個列舉 `Property` 和一組關於型別、價格、模型和零件的介面。這使我們能夠為 `Car` 類別創建靜態外觀的介面
7878

7979
```java
8080
public enum Property {
@@ -110,7 +110,7 @@ public interface HasParts extends Document {
110110
}
111111
```
112112

113-
现在我们准备介绍`Car`。
113+
現在我們準備介紹`Car`。
114114

115115
```java
116116
public class Car extends AbstractDocument implements HasModel, HasPrice, HasParts {
@@ -121,7 +121,7 @@ public class Car extends AbstractDocument implements HasModel, HasPrice, HasPart
121121
}
122122
```
123123

124-
最后是完整示例中的`Car`构造和使用方式
124+
最後是完整範例中 `Car`的建構和使用方式。
125125

126126
```java
127127
LOGGER.info("Constructing parts and car");
@@ -162,19 +162,21 @@ public class Car extends AbstractDocument implements HasModel, HasPrice, HasPart
162162
// door/Lambo/300
163163
```
164164

165-
## 类图
165+
## 類別圖
166166

167167
![alt text](./etc/abstract-document.png "Abstract Document Traits and Domain")
168168

169-
## 适用性
169+
## 適用性
170170

171-
使用抽象文档模式当
171+
在以下情況使用抽象文件模式:
172172

173-
* 需要即时添加新属性
174-
* 你想要一种灵活的方式来以树状结构组织域
175-
* 你想要更宽松的耦合系统
173+
* 需要即時新增新屬性時
176174

177-
## 鸣谢
175+
* 想要一種靈活的方式以樹狀結構組織領域 (domain) 時
176+
177+
* 想要一個更鬆散耦合的系統時
178+
179+
## 參考資料和來源
178180

179181
* [Wikipedia: Abstract Document Pattern](https://en.wikipedia.org/wiki/Abstract_Document_Pattern)
180182
* [Martin Fowler: Dealing with properties](http://martinfowler.com/apsupp/properties.pdf)
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
---
2+
title: Abstract Factory
3+
shortTitle: Abstract Factory
4+
category: Structural
5+
language: zh-TW
6+
tag:
7+
- Extensibility
8+
---
9+
10+
## 別稱
11+
12+
* Kit (套件)
13+
14+
## 抽象工廠設計模式的意圖
15+
16+
Java 中的抽象工廠模式 (Abstract Factory pattern) 提供一個介面,用於創建一系列相關或相依的物件家族,而無需指定其具體類別,從而增強了軟體設計的模組化與靈活性。
17+
18+
## 抽象工廠模式的詳細解釋與真實世界範例
19+
20+
真實世界範例
21+
22+
> 想像一家傢俱公司,它使用 Java 中的抽象工廠模式來生產多種風格的傢俱:現代風、維多利亞風和鄉村風。每種風格都包含椅子、桌子和沙發等產品。為了確保每種風格內部的一致性,該公司使用了抽象工廠模式。
23+
>
24+
> 在這個情境中,抽象工廠是一個用於創建相關傢俱物件家族(椅子、桌子、沙發)的介面。每個具體工廠(ModernFurnitureFactory、VictorianFurnitureFactory、RusticFurnitureFactory)都實作了這個抽象工廠介面,並創建一組符合特定風格的產品。如此一來,客戶端就可以創建一整套現代或維多利亞風格的傢俱,而無需擔心其實例化的細節。這不僅保持了風格的一致性,也讓更換不同風格的傢俱變得輕而易舉。
25+
26+
簡單來說
27+
28+
> 工廠中的工廠;一個將個別但相關/相依的工廠群組在一起,而無需指定其具體類別的工廠。
29+
30+
維基百科說
31+
32+
> 抽象工廠模式提供了一種方法,可以封裝一組具有共通主題的獨立工廠,而無需指定它們的具體類別。
33+
34+
類別圖
35+
36+
![Abstract Factory class diagram](./etc/abstract-factory.urm.png "Abstract Factory class diagram")
37+
38+
## Java 中的抽象工廠程式碼範例
39+
40+
為了使用抽象工廠模式來創建一個王國,我們需要具有共通主題的物件。精靈王國需要精靈國王、精靈城堡和精靈軍隊;而獸人王國則需要獸人國王、獸人城堡和獸人軍隊。王國中的這些物件之間存在著相依性。
41+
42+
將上述的王國範例轉換為程式碼。首先,我們為王國中的物件定義一些介面和實作。
43+
44+
```java
45+
public interface Castle {
46+
String getDescription();
47+
}
48+
49+
public interface King {
50+
String getDescription();
51+
}
52+
53+
public interface Army {
54+
String getDescription();
55+
}
56+
57+
// Elven implementations ->
58+
public class ElfCastle implements Castle {
59+
static final String DESCRIPTION = "This is the elven castle!";
60+
61+
@Override
62+
public String getDescription() {
63+
return DESCRIPTION;
64+
}
65+
}
66+
67+
public class ElfKing implements King {
68+
static final String DESCRIPTION = "This is the elven king!";
69+
70+
@Override
71+
public String getDescription() {
72+
return DESCRIPTION;
73+
}
74+
}
75+
76+
public class ElfArmy implements Army {
77+
static final String DESCRIPTION = "This is the elven Army!";
78+
79+
@Override
80+
public String getDescription() {
81+
return DESCRIPTION;
82+
}
83+
}
84+
85+
// Orcish implementations similarly -> ...
86+
```
87+
88+
接著,我們為王國工廠定義抽象和實作。
89+
90+
```java
91+
public interface KingdomFactory {
92+
Castle createCastle();
93+
94+
King createKing();
95+
96+
Army createArmy();
97+
}
98+
99+
public class ElfKingdomFactory implements KingdomFactory {
100+
101+
@Override
102+
public Castle createCastle() {
103+
return new ElfCastle();
104+
}
105+
106+
@Override
107+
public King createKing() {
108+
return new ElfKing();
109+
}
110+
111+
@Override
112+
public Army createArmy() {
113+
return new ElfArmy();
114+
}
115+
}
116+
117+
// 獸人 (Orcish) 的實作也類似 -> ...
118+
```
119+
現在,我們可以為我們不同的王國工廠設計一個工廠。在這個範例中,我們創建了 `FactoryMaker`,它負責返回 `ElfKingdomFactory` 或 O`OrcKingdomFactory` 的實例。客戶端可以使用 `FactoryMaker` 來創建所需的具體工廠,而該工廠又會生產出不同的具體物件(繼承自 `Army`, `King`, `Castle`)。在這個範例中,我們還使用了一個 enum 來參數化客戶端將請求哪種類型的王國工廠。
120+
121+
```java
122+
public static class FactoryMaker {
123+
124+
public enum KingdomType {
125+
ELF, ORC
126+
}
127+
128+
public static KingdomFactory makeFactory(KingdomType type) {
129+
return switch (type) {
130+
case ELF -> new ElfKingdomFactory();
131+
case ORC -> new OrcKingdomFactory();
132+
};
133+
}
134+
}
135+
```
136+
137+
這是我們範例應用程式的主函式:
138+
139+
```java
140+
LOGGER.info("elf kingdom");
141+
createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
142+
LOGGER.info(kingdom.getArmy().getDescription());
143+
LOGGER.info(kingdom.getCastle().getDescription());
144+
LOGGER.info(kingdom.getKing().getDescription());
145+
146+
LOGGER.info("orc kingdom");
147+
createKingdom(Kingdom.FactoryMaker.KingdomType.ORC);
148+
LOGGER.info(kingdom.getArmy().getDescription());
149+
LOGGER.info(kingdom.getCastle().getDescription());
150+
LOGGER.info(kingdom.getKing().getDescription());
151+
```
152+
153+
程式輸出:
154+
155+
```
156+
07:35:46.340 [main] INFO com.iluwatar.abstractfactory.App -- elf kingdom
157+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the elven army!
158+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the elven castle!
159+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the elven king!
160+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- orc kingdom
161+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the orc army!
162+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the orc castle!
163+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the orc king!
164+
```
165+
166+
## 在 Java 中何時使用抽象工廠模式
167+
在 Java 中,當您遇到以下情況時,請使用抽象工廠模式::
168+
169+
* 系統應與其產品的創建、組合和表示方式無關。
170+
171+
* 您需要用多個產品家族中的其中一個來配置系統。
172+
173+
* 必須同時使用一系列相關的產品物件,以強制保持一致性。
174+
175+
* 您希望提供一個產品的類別庫,只暴露它們的介面,而不是它們的實作。
176+
177+
* 相依物件的生命週期比消費者的生命週期短。
178+
179+
* 相依物件需要使用執行時期的值或參數來建構。
180+
181+
* 您需要在執行時期從一個家族中選擇要使用的產品。
182+
183+
* 新增新產品或家族時,不應要求修改現有程式碼。
184+
185+
## Java 抽象工廠模式教學
186+
187+
* [Abstract Factory Design Pattern in Java (DigitalOcean)](https://www.digitalocean.com/community/tutorials/abstract-factory-design-pattern-in-java)
188+
* [Abstract Factory(Refactoring Guru)](https://refactoring.guru/design-patterns/abstract-factory)
189+
190+
## 抽象工廠模式的優點與權衡
191+
192+
優點:
193+
194+
* 靈活性:無需修改程式碼即可輕鬆切換產品家族。
195+
196+
* 解耦:客戶端程式碼只與抽象介面互動,提升了可移植性和可維護性。
197+
198+
* 可重用性:抽象工廠和產品有助於跨專案的元件重用。
199+
200+
* 可維護性:對個別產品家族的變更是局部的,簡化了更新過程。
201+
202+
權衡:
203+
204+
* 複雜性:定義抽象介面和具體工廠會增加初期的開發開銷。
205+
206+
* 間接性:客戶端程式碼透過工廠間接與產品互動,可能會降低透明度。
207+
208+
## Java 中抽象工廠模式的實際應用
209+
210+
* Java Swing 的 `LookAndFeel` 類別,用於提供不同的外觀與感覺選項。
211+
212+
* Java Abstract Window Toolkit (AWT) 中的各種實作,用於創建不同的 GUI 元件。
213+
214+
* [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html)
215+
* [javax.xml.transform.TransformerFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/transform/TransformerFactory.html#newInstance--)
216+
* [javax.xml.xpath.XPathFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance--)
217+
218+
## 相關的 Java 設計模式
219+
220+
* [Factory Method](https://java-design-patterns.com/patterns/factory-method/): 抽象工廠使用工廠方法來創建產品。
221+
* [Singleton](https://java-design-patterns.com/patterns/singleton/): 抽象工廠類別通常被實作為單例
222+
* [Factory Kit](https://java-design-patterns.com/patterns/factory-kit/): 與抽象工廠類似,但更專注於以靈活的方式配置和管理一組相關物件。
223+
224+
## 參考資料與致謝
225+
226+
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI)
227+
* [Design Patterns in Java](https://amzn.to/3Syw0vC)
228+
* [Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software](https://amzn.to/49NGldq)
229+
* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3HWNf4U)
80.4 KB
Loading

0 commit comments

Comments
 (0)