Skip to content

Commit 2fce2e4

Browse files
sudowandererMikeohbusiluwatar
authored
docs: Chinese translations updates (iluwatar#1706)
* add state and callback pattern * add command and template-method pattern * add iterator pattern * add bridege and DI pattern * fix issue iluwatar#1600 * add converter,proxy,visitor pattern * add caching,composite,delegation,dirty-flag,interpreter patterns * add dao and producer-consumer * add dto and provate class data pattern * fix iluwatar#1646 png path problems * fix iluwatar#1646 composite png path case problem * add abstract document pattern and version-number pattern * add ambassador pattern * add acyclic-visitor and api-gateway pattern * add abstract-factory pattern * add active-object pattern * add aggregator-microservices and arrange-act-assert pattern Co-authored-by: Mike <admin@xiaod.info> Co-authored-by: Subhrodip Mohanta <hello@subho.xyz> Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
1 parent b3a1749 commit 2fce2e4

File tree

9 files changed

+1428
-0
lines changed

9 files changed

+1428
-0
lines changed

zh/abstract-document/README.md

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
---
2+
layout: pattern
3+
title: Abstract Document
4+
folder: abstract-document
5+
permalink: /patterns/abstract-document/
6+
categories: Structural
7+
tags:
8+
- Extensibility
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+
让我们首先定义基类`Document``AbstractDocument`。 它们基本上使对象拥有属性映射和任意数量的子对象。
34+
35+
```java
36+
public interface Document {
37+
38+
Void put(String key, Object value);
39+
40+
Object get(String key);
41+
42+
<T> Stream<T> children(String key, Function<Map<String, Object>, T> constructor);
43+
}
44+
45+
public abstract class AbstractDocument implements Document {
46+
47+
private final Map<String, Object> properties;
48+
49+
protected AbstractDocument(Map<String, Object> properties) {
50+
Objects.requireNonNull(properties, "properties map is required");
51+
this.properties = properties;
52+
}
53+
54+
@Override
55+
public Void put(String key, Object value) {
56+
properties.put(key, value);
57+
return null;
58+
}
59+
60+
@Override
61+
public Object get(String key) {
62+
return properties.get(key);
63+
}
64+
65+
@Override
66+
public <T> Stream<T> children(String key, Function<Map<String, Object>, T> constructor) {
67+
return Stream.ofNullable(get(key))
68+
.filter(Objects::nonNull)
69+
.map(el -> (List<Map<String, Object>>) el)
70+
.findAny()
71+
.stream()
72+
.flatMap(Collection::stream)
73+
.map(constructor);
74+
}
75+
...
76+
}
77+
```
78+
接下来,我们定义一个枚举“属性”和一组类型,价格,模型和零件的接口。 这使我们能够为Car类创建静态外观的界面。
79+
80+
```java
81+
public enum Property {
82+
83+
PARTS, TYPE, PRICE, MODEL
84+
}
85+
86+
public interface HasType extends Document {
87+
88+
default Optional<String> getType() {
89+
return Optional.ofNullable((String) get(Property.TYPE.toString()));
90+
}
91+
}
92+
93+
public interface HasPrice extends Document {
94+
95+
default Optional<Number> getPrice() {
96+
return Optional.ofNullable((Number) get(Property.PRICE.toString()));
97+
}
98+
}
99+
public interface HasModel extends Document {
100+
101+
default Optional<String> getModel() {
102+
return Optional.ofNullable((String) get(Property.MODEL.toString()));
103+
}
104+
}
105+
106+
public interface HasParts extends Document {
107+
108+
default Stream<Part> getParts() {
109+
return children(Property.PARTS.toString(), Part::new);
110+
}
111+
}
112+
```
113+
114+
现在我们准备介绍`Car`。
115+
116+
```java
117+
public class Car extends AbstractDocument implements HasModel, HasPrice, HasParts {
118+
119+
public Car(Map<String, Object> properties) {
120+
super(properties);
121+
}
122+
}
123+
```
124+
125+
最后是完整示例中的`Car`构造和使用方式。
126+
127+
```java
128+
LOGGER.info("Constructing parts and car");
129+
130+
var wheelProperties = Map.of(
131+
Property.TYPE.toString(), "wheel",
132+
Property.MODEL.toString(), "15C",
133+
Property.PRICE.toString(), 100L);
134+
135+
var doorProperties = Map.of(
136+
Property.TYPE.toString(), "door",
137+
Property.MODEL.toString(), "Lambo",
138+
Property.PRICE.toString(), 300L);
139+
140+
var carProperties = Map.of(
141+
Property.MODEL.toString(), "300SL",
142+
Property.PRICE.toString(), 10000L,
143+
Property.PARTS.toString(), List.of(wheelProperties, doorProperties));
144+
145+
var car = new Car(carProperties);
146+
147+
LOGGER.info("Here is our car:");
148+
LOGGER.info("-> model: {}", car.getModel().orElseThrow());
149+
LOGGER.info("-> price: {}", car.getPrice().orElseThrow());
150+
LOGGER.info("-> parts: ");
151+
car.getParts().forEach(p -> LOGGER.info("\t{}/{}/{}",
152+
p.getType().orElse(null),
153+
p.getModel().orElse(null),
154+
p.getPrice().orElse(null))
155+
);
156+
157+
// Constructing parts and car
158+
// Here is our car:
159+
// model: 300SL
160+
// price: 10000
161+
// parts:
162+
// wheel/15C/100
163+
// door/Lambo/300
164+
```
165+
166+
## 类图
167+
168+
![alt text](../../abstract-document/etc/abstract-document.png "Abstract Document Traits and Domain")
169+
170+
## 适用性
171+
172+
使用抽象文档模式当
173+
174+
* 需要即时添加新属性
175+
* 你想要一种灵活的方式来以树状结构组织域
176+
* 你想要更宽松的耦合系统
177+
178+
## 鸣谢
179+
180+
* [Wikipedia: Abstract Document Pattern](https://en.wikipedia.org/wiki/Abstract_Document_Pattern)
181+
* [Martin Fowler: Dealing with properties](http://martinfowler.com/apsupp/properties.pdf)
182+
* [Pattern-Oriented Software Architecture Volume 4: A Pattern Language for Distributed Computing (v. 4)](https://www.amazon.com/gp/product/0470059028/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0470059028&linkId=e3aacaea7017258acf184f9f3283b492)

0 commit comments

Comments
 (0)