Composite组合模式

前言:

最近在看设计模式,首先推荐个不错的与设计模式相关的github项目:
java-design-patterns:java设计模式很详细内容也很充实的开源项目
wiki地址:
Composite Pattern

介绍:

之前的误解一直认为Composite就是和继承相对应的组合的扩展类的方式。最近在翻看相关内容的是否才发现自己是理解岔了。

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
组合模式主要解决的是树结构的问题,能够将整体或个体同等对待。

上面的意思是当什么问题能够转换为树状结构,我们就要考虑是否能够利用组合模式来进行解决。
wiki的解释:

In software engineering, the composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.

也是大同小异。我们以树结构来进行理解,整个树或者任意子树,既可以用它所对应的根节点来表示,而具体的每个节点(叶子节点,根节点,分支等)也是个节点类型,所以这就是上面所说的对于个体和整体能够同等对待的意思。

UML图

Composite组合模式_第1张图片
组合模式的UML图

这个UML图最能体现出组合设计模式的核心思想。Leaf和Composite均继承自Component组件,而Composite中又包含了组件(多以List的形式)。

例子:

该例子选自前言中项目中的例子,地址:http://java-design-patterns.com/patterns/composite/

// 最关键的一步,自己包含自己的一个List,Composite包含一个List的属性
public abstract class LetterComposite {
  private List children = new ArrayList<>();
  public void add(LetterComposite letter) {
    children.add(letter);
  }
  public int count() {
    return children.size();
  }
  protected void printThisBefore() {}
  protected void printThisAfter() {}
  public void print() {
    printThisBefore();
    for (LetterComposite letter : children) {
      letter.print();
    }
    printThisAfter();
  }
}

// 所有的对象只要扩展自LetterComposite即可
public class Letter extends LetterComposite {
  private char c;
  public Letter(char c) {
    this.c = c;
  }
  @Override
  protected void printThisBefore() {
    System.out.print(c);
  }
}
// 所有的对象只要扩展自LetterComposite即可
public class Word extends LetterComposite {
  public Word(List letters) {
    for (Letter l : letters) {
      this.add(l);
    }
  }
  @Override
  protected void printThisBefore() {
    System.out.print(" ");
  }
}
// 所有的对象只要扩展自LetterComposite即可
public class Sentence extends LetterComposite {
  public Sentence(List words) {
    for (Word w : words) {
      this.add(w);
    }
  }
  @Override
  protected void printThisAfter() {
    System.out.print(".");
  }
}

组装:

public class Messenger {
  LetterComposite messageFromOrcs() {
    List words = new ArrayList<>();
    words.add(new Word(Arrays.asList(new Letter('W'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e'))));
    words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e'))));
    words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s'))));
    words.add(new Word(Arrays.asList(new Letter('a'))));
    words.add(new Word(Arrays.asList(new Letter('w'), new Letter('h'), new Letter('i'), new Letter('p'))));
    words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e'))));
    words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s'))));
    words.add(new Word(Arrays.asList(new Letter('a'))));
    words.add(new Word(Arrays.asList(new Letter('w'), new Letter('a'), new Letter('y'))));
    return new Sentence(words);
  }

  LetterComposite messageFromElves() {
    List words = new ArrayList<>();
    words.add(new Word(Arrays.asList(new Letter('M'), new Letter('u'), new Letter('c'), new Letter('h'))));
    words.add(new Word(Arrays.asList(new Letter('w'), new Letter('i'), new Letter('n'), new Letter('d'))));
    words.add(new Word(Arrays.asList(new Letter('p'), new Letter('o'), new Letter('u'), new Letter('r'), new Letter('s'))));
    words.add(new Word(Arrays.asList(new Letter('f'), new Letter('r'), new Letter('o'), new Letter('m'))));
    words.add(new Word(Arrays.asList(new Letter('y'), new Letter('o'), new Letter('u'), new Letter('r'))));
    words.add(new Word(Arrays.asList(new Letter('m'), new Letter('o'), new Letter('u'), new Letter('t'), new Letter('h'))));
    return new Sentence(words);
  }
}

对于组合模式来讲,我们虽然将整体和个体进行了同等的对待,但是组装却是难免的。而如何更加灵活的进行组装,便有不同的选择方式,比如通过xml来进行配置,或者通过数据库配置亦可。

总结:

对于Composite组合设计模式来讲,解决的问题是对于类树的结构,如何将整体和个体进行统一对待,而由于统一的进行了对待,所以和递归的想法又有了契合。

你可能感兴趣的:(Composite组合模式)