设计模式系列:组合模式

概念

组合模式是把对象堆起来形成集合的一种方式。它组织对象形成集合,结合迭代器模式,可以对客户隐藏具体对象实现。不至于暴露集合内部信息。形式上经
常将组合你模式用于对象的树形结构表示。

实现

  • 背景

村子里面养了 鸡,鸭,本地鸭,外地鸭,猪。这些家畜都会跑。现在要将他们集合起来,进行统一管理。每天数数,防止丢失。

  • 抽象
    我们可以用组合模式来进行管理这些家畜。
    首先家畜的集合进行抽象树形结构。
    第一层:普通家畜
    第二层:普通家禽下有 猪,禽类
    第三层:禽类 下面有 鸡,鸭
    第四层:鸭子下面有 本地鸭,外地鸭。

  • 类图

图片

图片

  • 对象关联图:

图片

部分代码:

AnimalType:

1
2
3
4
5
6
7
8
9
10
11
package com.littlehui.design.composite;

import com.littlehui.design.iterate.AnimalIterator;

/**
* Created by littlehui on 2018/1/18.
*/
public interface AnimalType {

public AnimalIterator createIterator();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.littlehui.design.composite;

import com.littlehui.design.iterate.AnimalIterator;

/**
* Created by littlehui on 2018/1/18.
*/
public interface Animal {

public void run();

public void each();

public AnimalIterator iterator();
}
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
package com.littlehui.design.composite;

import com.littlehui.design.iterate.AnimalIterator;
import com.littlehui.design.iterate.HomeAnimalIterator;
import com.littlehui.design.iterate.IteratorComposite;

import java.util.ArrayList;
import java.util.List;

/**
* Created by littlehui on 2018/1/18.
*/
public class Bird extends IteratorAnimal implements AnimalType {

List<Animal> birds;

public Bird() {
this.birds = new ArrayList<Animal>();
birds.add(new Chicken());
birds.add(new Duck());
}

public void run() {
System.out.println("鸟类跑");
}

public void each() {
for (Animal animal : birds) {
animal.each();
}
}

public AnimalIterator iterator() {
return new HomeAnimalIterator(birds);
}

public AnimalIterator createIterator() {
return new IteratorComposite(this.iterator());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.littlehui.design.composite;

/**
* Created by littlehui on 2018/1/18.
*/
public class Chicken extends IteratorAnimal {


public void run() {
System.out.println("小鸡跑");
}

public void each() {
System.out.println("鸡");
}
}
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
package com.littlehui.design.composite;

import com.littlehui.design.iterate.AnimalIterator;
import com.littlehui.design.iterate.HomeAnimalIterator;
import com.littlehui.design.iterate.IteratorComposite;

import java.util.ArrayList;
import java.util.List;

/**
* Created by littlehui on 2018/1/18.
*/
public class Duck extends IteratorAnimal implements AnimalType {

List<Animal> ducks;

public Duck() {
ducks = new ArrayList<Animal>();
ducks.add(new LocalDuck());
ducks.add(new ForignDuck());
}

public void run() {
System.out.println("鸭类跑");
}

public void each() {
System.out.println("鸭");
}

public AnimalIterator iterator() {
return new HomeAnimalIterator(ducks);
}

public AnimalIterator createIterator() {
return new IteratorComposite(this.iterator());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.littlehui.design.composite;

/**
* Created by littlehui on 2018/1/18.
*/
public class ForignDuck extends IteratorAnimal {
public void run() {
System.out.println("外地鸭跑");
}

public void each() {
System.out.println("外地鸭");
}
}
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
package com.littlehui.design.composite;

import com.littlehui.design.iterate.AnimalIterator;
import com.littlehui.design.iterate.HomeAnimalIterator;
import com.littlehui.design.iterate.IteratorComposite;

import java.util.ArrayList;
import java.util.List;

/**
* Created by littlehui on 2018/1/18.
*/
public class HomeAnimal extends IteratorAnimal implements AnimalType {

private List<Animal> homeAnimals = new ArrayList<Animal>();

public HomeAnimal() {
homeAnimals.add(new Pig());
homeAnimals.add(new Bird());
}

public void run() {
System.out.println("家养牲畜跑");
}

public void each() {
System.out.println("家养牲畜跑");
}

public AnimalIterator iterator() {
return new HomeAnimalIterator(homeAnimals);
}

public AnimalIterator createIterator() {
return new IteratorComposite(this.iterator());
}
}
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
package com.littlehui.design.composite;

import com.littlehui.design.iterate.AnimalIterator;

/**
* Created by littlehui on 2018/1/18.
*/
public class IteratorAnimal implements Animal {

public IteratorAnimal() {

}

public void run() {

}

public void each() {

}

public AnimalIterator iterator() {
final IteratorAnimal baseAnimal = this;
return new AnimalIterator() {
public boolean hasNext() {
if (baseAnimal != null ) {
return true;
}
return false;
}
public Animal next() {
return baseAnimal;
}
};
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.littlehui.design.composite;

/**
* Created by littlehui on 2018/1/18.
*/
public class LocalDuck extends IteratorAnimal {

public void run() {
System.out.println("本地鸭跑");
}

public void each() {
System.out.println("本地鸭");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.littlehui.design.composite;

/**
* Created by littlehui on 2018/1/18.
*/
public class Pig extends IteratorAnimal {

public void run() {
System.out.println("猪在跑");
}

public void each() {
System.out.println("猪");
}
}

Client:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.littlehui.design.composite;

import com.littlehui.design.iterate.AnimalIterator;

/**
* Created by littlehui on 2018/1/18.
*/
public class Client {

public static void main(String[] args) {
HomeAnimal homeAnimal = new HomeAnimal();

AnimalIterator homeAnimalIterator = homeAnimal.createIterator();
while (homeAnimalIterator.hasNext()) {
Animal animal = homeAnimalIterator.next();
animal.run();
}
}
}
  • 迭代器组合部分

设计模式-组合模式

  • 解析
    实际上,上面的代码分两个部分理解:
    1:家畜动物们的关联组合
    2:对动物们遍历的迭代组合(代码略)
    组合模式经常会应用到迭代模式,这里也都写上了。

场景

HtmlPaser包,解析Html页面。就是典型的组合模式。

总结

组合模式关注的重点是对对象的结合方式。结合后暴露统一的接口管理。正如上所表达的,动物们集合后通过组合迭代器的方式统一暴露了一个遍历的方法口。
屏蔽了内部实现,调用端只需调用迭代方法就可以实现遍历管理了。有了迭代组合还可以个性化的筛选,等等趋向业务逻辑的实现。