迭代器模式

迭代器模式提供了遍历容器的方便性,容器只要管理增减元素即可,需要遍历的时候交由迭代器进行。

比如Set、Map、List等容器的iterator。

定义

迭代器是为容器服务的,它提供一种方法访问一个容器对象中的各个元素,而又不需要暴露该对象的内部细节。

迭代器模式通用类图

实现

Iterator

抽象迭代器负责定义访问和遍历元素的接口。
first() 获取第一个元素;
next() 访问下一个元素;
hasNext() 是否还有下一个;

1
2
3
4
5
public interface Iterator<E>{
E next();
boolean hasNext();
boolean remove();
}

ConcreteIterator

具体迭代器要实现迭代器接口,完成容器元素的遍历。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ConcreteIterator implements Iterator<E>{
private Vector<E> v = new Vector<>();
public int cursor = 0;
public ConcreteIterator(Vector _vector){
this.v = _vector;
}
public boolean hasNext(){
return this.cursor != this.v.size();
}

public E next(){
return this.hasNext() ? this.v.get(this.cursor++) : null;
}

public boolean remove(){
this.v.remove(this.cursor);
return true;
}
}

Aggregate

抽象容器角色负责提供创建具体迭代器角色的接口, 必然提供一个类似于createIterator()的方法。

1
2
3
4
5
public interface Aggregate<E>{
void add(E e);
void remove(E e);
Iterator iterator();
}

Concrete Aggregate

具体容器实现容器接口定义的方法,创建出容纳迭代器的对象。

1
2
3
4
5
6
7
8
9
10
11
12
public class ConcreteAggrate implements Aggregate<E>{
Vector v = new Vector();
public void add(E e){
this.add(e);
}
public Iterator<E> iterator(){
return new ConcreteIterator<>(this.v);
}
public void remove(E e){
this.remove(e);
}
}

组合模式

也叫合成模式或者部分整体模式,主要用来描述部分与整体的关系。

定义

将对象组合成树形结构以表示部分整体的层次结构,使得用于对单个对象和组合对象的使用具有一致性。

组合模式的通用类图

Component

定义参加组合对象的共有方法和属性,可以定义一些默认的行为或者属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public abstract class Component{
private Component parent = null;
private ArrayList<Component> list = new ArrayList<>();
public void add(Component c){
c.parent = this;
this.list.add(c);
}

public void remove(Component c){
this.list.remove(c);
}

public List<Component> getChildren(){
return this.list;
}

public Component getParent(){
return this.parent;
}
}

Composite

树枝对象,作用是组合树枝节点和叶子结点形成一个树形结构。

1
2
3
public class Composite extends Component{

}

Leaf

叶子对象,下面没有分支,最小的遍历单位。

1
2
3
public class Leaf extends Component{

}

应用

优点

  • 高层模块调用简单
    一颗属性结构中的所有节点都是Component,局部和整体对调用者来说没有任何区别,也就是说高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。
  • 节点自由度增加
    使用组合模式后,如果想增加一个树枝节点、树叶节点都非常容易。
    如何开闭原则,利于维护。

缺点

(安全模式)直接使用了实现类(可以扩展)。与依赖倒置原则冲突,限制了接口的影响范围。

扩展

透明的组合模式

以上的例子就是透明的组合模式,吧用来组合使用的方法放到抽象类中,无论叶子对象还是树枝对象都有相同的结构,通过getChildren();判断当前节点是否为叶子节点还是根节点。

透明模式的好处是遵循了依赖倒置原则

安全的组合模式

安全模式是将叶子节点和树枝节点彻底分开,树枝节点单独拥有用来组合的方法。

Component

定义参加组合对象的共有方法和属性,可以定义一些默认的行为或者属性。

1
2
3
4
5
6
public abstract class Component{
private Component parent = null;
public Component getParent(){
return this.parent;
}
}
Composite

树枝对象,作用是组合树枝节点和叶子结点形成一个树形结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Composite extends Component{
private ArrayList<Component> list = new ArrayList<>();
public void add(Component c){
c.parent = this;
this.list.add(c);
}

public void remove(Component c){
this.list.remove(c);
}

public List<Component> getChildren(){
return this.list;
}
}
Leaf

叶子对象,下面没有分支,最小的遍历单位。

1
2
3
public class Leaf extends Component{

}