Skip to content

Commit 9c0c17b

Browse files
authored
Merge pull request iluwatar#1512 from xiaod-dev/translation-zh
Translation zh
2 parents 82842d6 + 20fac32 commit 9c0c17b

File tree

3 files changed

+433
-0
lines changed

3 files changed

+433
-0
lines changed

zh/adapter/README.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
layout: pattern
3+
title: Adapter
4+
folder: adapter
5+
permalink: /patterns/adapter/
6+
categories: Structural
7+
tags:
8+
- Gang of Four
9+
---
10+
11+
## 又被称为
12+
包装器
13+
14+
## 目的
15+
将一个接口转换成另一个客户所期望的接口。适配器让那些本来因为接口不兼容的类可以合作无间。
16+
17+
## 解释
18+
19+
现实世界例子
20+
21+
> 考虑有这么一种情况,在你的存储卡中有一些照片,你想将其传到你的电脑中。为了传送数据,你需要某种能够兼容你电脑接口的适配器以便你的储存卡能连上你的电脑。在这种情况下,读卡器就是一个适配器。
22+
> 另一个例子就是注明的电源适配器;三脚插头不能插在两脚插座上,需要一个电源适配器来使其能够插在两脚插座上。
23+
> 还有一个例子就是翻译官,他翻译一个人对另一个人说的话。
24+
25+
用直白的话来说
26+
27+
> 适配器模式让你可以把不兼容的对象包在适配器中,以让其兼容其他类。
28+
29+
维基百科中说
30+
31+
> 在软件工程中,适配器模式是一种可以让现有类的接口把其作为其他接口来使用的设计模式。它经常用来使现有的类和其他类能够工作并且不用修改其他类的源代码。
32+
33+
**编程样例(对象适配器)**
34+
35+
假如有一个船长他只会划船,但不会航行。
36+
37+
首先我们有接口`RowingBoat``FishingBoat`
38+
39+
```java
40+
public interface RowingBoat {
41+
void row();
42+
}
43+
44+
public class FishingBoat {
45+
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class);
46+
public void sail() {
47+
LOGGER.info("The fishing boat is sailing");
48+
}
49+
}
50+
```
51+
船长希望有一个`RowingBoat`接口的实现,这样就可以移动
52+
53+
```java
54+
public class Captain {
55+
56+
private final RowingBoat rowingBoat;
57+
// default constructor and setter for rowingBoat
58+
public Captain(RowingBoat rowingBoat) {
59+
this.rowingBoat = rowingBoat;
60+
}
61+
62+
public void row() {
63+
rowingBoat.row();
64+
}
65+
}
66+
```
67+
68+
现在海盗来了,我们的船长需要逃跑但是只有一个渔船可用。我们需要创建一个可以让船长使用其划船技能来操作渔船的适配器。
69+
70+
```java
71+
public class FishingBoatAdapter implements RowingBoat {
72+
73+
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class);
74+
75+
private final FishingBoat boat;
76+
77+
public FishingBoatAdapter() {
78+
boat = new FishingBoat();
79+
}
80+
81+
@Override
82+
public void row() {
83+
boat.sail();
84+
}
85+
}
86+
87+
```
88+
89+
现在 `船长` 可以使用`FishingBoat`接口来逃离海盗了。
90+
91+
```java
92+
var captain = new Captain(new FishingBoatAdapter());
93+
captain.row();
94+
```
95+
96+
## 类图
97+
![alt text](../../adapter/etc/adapter.urm.png "Adapter class diagram")
98+
99+
100+
## 应用
101+
使用适配器模式当
102+
103+
* 你想使用一个已有类,但是它的接口不能和你需要的所匹配
104+
* 你需要创建一个可重用类,该类与不相关或不可预见的类进行协作,即不一定具有兼容接口的类
105+
* 你需要使用一些现有的子类,但是子类化他们每一个的子类来进行接口的适配是不现实的。一个对象适配器可以适配他们父类的接口。
106+
* 大多数使用第三方类库的应用使用适配器作为一个在应用和第三方类库间的中间层来使应用和类库解耦。如果必须使用另一个库,则只需使用一个新库的适配器而无需改变应用程序的代码。
107+
108+
## 后果:
109+
类和对象适配器有不同的权衡取舍。一个类适配器
110+
111+
* 适配被适配者到目标接口,需要保证只有一个具体的被适配者类。作为结果,当我们想适配一个类和它所有的子类时,类适配器将不会起作用。
112+
* 可以让适配器重写一些被适配者的行为,因为适配器是被适配者的子类。
113+
* 只引入了一个对象,并且不需要其他指针间接访问被适配者。
114+
115+
对象适配器
116+
117+
* 一个适配器可以和许多被适配者工作,也就是被适配者自己和所有它的子类。适配器同时可以为所有被适配者添加功能。
118+
* 覆盖被适配者的行为变得更难。需要子类化被适配者然后让适配器引用这个子类不是被适配者。
119+
120+
121+
## 现实世界的案例
122+
123+
* [java.util.Arrays#asList()](http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#asList%28T...%29)
124+
* [java.util.Collections#list()](https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#list-java.util.Enumeration-)
125+
* [java.util.Collections#enumeration()](https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#enumeration-java.util.Collection-)
126+
* [javax.xml.bind.annotation.adapters.XMLAdapter](http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html#marshal-BoundType-)
127+
128+
129+
## 鸣谢
130+
131+
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
132+
* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31)
133+
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)
134+
* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7)
135+
136+
```
137+
138+
```

zh/observer/README.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
---
2+
layout: pattern
3+
title: Observer
4+
folder: observer
5+
permalink: /patterns/observer/
6+
categories: Behavioral
7+
tags:
8+
- Gang Of Four
9+
- Reactive
10+
---
11+
12+
## Also known as
13+
## 又被称为
14+
15+
家属,发布订阅模式
16+
17+
## 目的
18+
19+
定义一种一对多的对象依赖关系这样当一个对象改变状态时,所有依赖它的对象都将自动通知或更新。
20+
21+
## 解释
22+
23+
真实世界例子
24+
25+
> 在遥远的土地上生活着霍比特人和兽人的种族。他们都是户外生活的人所以他们密切关注天气的变化。可以说他们不断地关注着天气。
26+
27+
通俗的说
28+
29+
> 注册成为一个观察者以接收对象状态的改变。
30+
31+
维基百科说
32+
33+
> 观察者模式是这样的一种软件设计模式:它有一个被称为主题的对象,维护着一个所有依赖于它的依赖者清单,也就是观察者清单,当主题的状态发生改变时,主题通常会调用观察者的方法来自动通知观察者们。
34+
35+
**编程示例**
36+
37+
让我们先来介绍天气观察者的接口以及我们的种族,兽人和霍比特人。
38+
39+
```java
40+
public interface WeatherObserver {
41+
42+
void update(WeatherType currentWeather);
43+
}
44+
45+
public class Orcs implements WeatherObserver {
46+
47+
private static final Logger LOGGER = LoggerFactory.getLogger(Orcs.class);
48+
49+
@Override
50+
public void update(WeatherType currentWeather) {
51+
LOGGER.info("The orcs are facing " + currentWeather.getDescription() + " weather now");
52+
}
53+
}
54+
55+
public class Hobbits implements WeatherObserver {
56+
57+
private static final Logger LOGGER = LoggerFactory.getLogger(Hobbits.class);
58+
59+
@Override
60+
public void update(WeatherType currentWeather) {
61+
switch (currentWeather) {
62+
LOGGER.info("The hobbits are facing " + currentWeather.getDescription() + " weather now");
63+
}
64+
}
65+
```
66+
67+
然后这里是不断变化的天气。
68+
69+
```java
70+
public class Weather {
71+
72+
private static final Logger LOGGER = LoggerFactory.getLogger(Weather.class);
73+
74+
private WeatherType currentWeather;
75+
private final List<WeatherObserver> observers;
76+
77+
public Weather() {
78+
observers = new ArrayList<>();
79+
currentWeather = WeatherType.SUNNY;
80+
}
81+
82+
public void addObserver(WeatherObserver obs) {
83+
observers.add(obs);
84+
}
85+
86+
public void removeObserver(WeatherObserver obs) {
87+
observers.remove(obs);
88+
}
89+
90+
/**
91+
* Makes time pass for weather.
92+
*/
93+
public void timePasses() {
94+
var enumValues = WeatherType.values();
95+
currentWeather = enumValues[(currentWeather.ordinal() + 1) % enumValues.length];
96+
LOGGER.info("The weather changed to {}.", currentWeather);
97+
notifyObservers();
98+
}
99+
100+
private void notifyObservers() {
101+
for (var obs : observers) {
102+
obs.update(currentWeather);
103+
}
104+
}
105+
}
106+
```
107+
108+
这是完整的示例。
109+
110+
```java
111+
var weather = new Weather();
112+
weather.addObserver(new Orcs());
113+
weather.addObserver(new Hobbits());
114+
115+
weather.timePasses();
116+
// The weather changed to rainy.
117+
// The orcs are facing rainy weather now
118+
// The hobbits are facing rainy weather now
119+
weather.timePasses();
120+
// The weather changed to windy.
121+
// The orcs are facing windy weather now
122+
// The hobbits are facing windy weather now
123+
weather.timePasses();
124+
// The weather changed to cold.
125+
// The orcs are facing cold weather now
126+
// The hobbits are facing cold weather now
127+
weather.timePasses();
128+
// The weather changed to sunny.
129+
// The orcs are facing sunny weather now
130+
// The hobbits are facing sunny weather now
131+
```
132+
133+
## Class diagram
134+
![alt text](../../observer/etc/observer.png "Observer")
135+
136+
## 应用
137+
在下面任何一种情况下都可以使用观察者模式
138+
139+
* 当抽象具有两个方面时,一个方面依赖于另一个方面。将这些方面封装在单独的对象中,可以使你分别进行更改和重用
140+
* 当一个对象的改变的同时需要改变其他对象,同时你又不知道有多少对象需要改变时
141+
* 当一个对象可以通知其他对象而无需假设这些对象是谁时。换句话说,你不想让这些对象紧耦合。
142+
143+
## 典型用例
144+
145+
* 一个对象的改变导致其他对象的改变
146+
147+
## Java中的例子
148+
149+
* [java.util.Observer](http://docs.oracle.com/javase/8/docs/api/java/util/Observer.html)
150+
* [java.util.EventListener](http://docs.oracle.com/javase/8/docs/api/java/util/EventListener.html)
151+
* [javax.servlet.http.HttpSessionBindingListener](http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSessionBindingListener.html)
152+
* [RxJava](https://github.com/ReactiveX/RxJava)
153+
154+
## 鸣谢
155+
156+
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
157+
* [Java Generics and Collections](https://www.amazon.com/gp/product/0596527756/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596527756&linkCode=as2&tag=javadesignpat-20&linkId=246e5e2c26fe1c3ada6a70b15afcb195)
158+
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)
159+
* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7)

0 commit comments

Comments
 (0)