Design-Patterns-2

设计模式2-结构型模式

Composite Pattern

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。

The Problem

比如说,在PPT中我创建了两个长方形,两个圆形,那么我们可以选中两个长方形将它们同时移动或者缩放;同样的,我们甚至可以选中四个物体同时移动缩放

除此之外,最经典的例子是文件夹与文件的表示,一个文件夹(容器对象)既可以存放文件夹(容器对象),也可以存放文件(叶子对象)。如果把树的每个节点摊平,那就是List。而树结构,则是更能直观的体现每个节点与整体的关系。

为什么需要这个模式呢?它的目的是什么?

可以体现出类与类之间的层级结构

主要是想要对外提供一致性的使用方式,即使容器对象与叶子对象之间属性差别可能非常大,我们希望抽象出相同的地方,一致的处理。

Solution

组合模式中一般有以下三种角色:

  • 抽象构件(Component):一般是接口或者抽象类,是叶子构件和容器构件对象声明接口,抽象出访问以及管理子构件的方法。
  • 叶子节点(Leaf):在组合中表示叶子节点对象,叶子节点没有子节点,也就没有子构件。
  • 容器构件(Composite):容器节点可以包含子节点,子节点可以是叶子节点,也可以是容器节点。

Implementation

1
2
3
4
5
6
7
8
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public interface Component { // Component接口,容器和叶子都需要实现它
void render();
}

public class Shape implements Component{ //实现component接口

//重写render方法,因为是叶子类,因此只需要实现单个逻辑即可
@Override
public void render() {
System.out.println("Render Shape");
}
}

public class Group implements Component{ // 实现接口
// Group中可以有多个component组成,这个角度看Group和Shape是相等的
private List<Component> components = new ArrayList<>();

//可以往components中添加shape/group
public void add(Component shape){
components.add(shape);
}

//重写render方法,对列表中的每一个Component都调用render
@Override
public void render() {
for(Component component:components){
component.render();
}
}
}

public class Main {
public static void main(String[] args) {
Group group1 = new Group();
group1.add(new Shape());
group1.add(new Shape());

Group group2 = new Group();
group2.add(new Shape());
group2.add(new Shape());

Group group = new Group();
group.add(group1);
group.add(group2);
//层次结构如下:
/*
- group
- - group1
- - - shape
- - - shape
- - group2
- - - shape
- - - shape
*/
group.render();//一共是四个叶子结点,执行四次render
//Render Shape
//Render Shape
//Render Shape
//Render Shape
}
}

小结

组合模式的优点:

  • 可以分层次定义复杂对象,表示局部和全部,客户端可以忽略不同的节点的差异。
  • 从高层次调用,可以很顺畅的调用到每一个局部,一致性比较强。
  • 节点自由搭配,灵活度比较高。

缺点:

  • 在使用组合模式时,其叶子和组合节点的声明都是实现类,而不是接口,违反了依赖倒置原则。

使用场景:

  • 希望忽略每个部分的差异,客户端一致使用
  • 需要表现为树形结构,以表示“整体-部分”的结构层次。

Exercise

We’re building an application for an incident management organization. When an incident (eg fire) occurs, one or more teams may be deployed to attack the incident.

A team often includes a truck and one or more human resources. It can also include a sub team. For example, for a medium-sized incident, we may need to deploy two teams and each team may contain a truck and two persons.

  • Team

    • Sub Team 1

      • Truck
      • Human Resource
      • Human Resource
    • Sub Team 2

      • Truck
      • Human Resource
      • Human Resource

Look at the current implementation of our application in the composite package.

What are the problems with this implementation? Refactor the code using the composite pattern.

Adapter Pattern

The Problem

Solution

Implementation

Exercise

Decorator Pattern

The Problem

Solution

Implementation

Exercise

Facade Pattern

The Problem

Solution

Implementation

Exercise

Flyweight Pattern

The Problem

Solution

Implementation

Exercise

Bridge Pattern

The Problem

Solution

Implementation

Proxy Pattern

The Problem

Solution

Implementation

Exercise

-------------本文结束,感谢您的阅读-------------