美文网首页我爱编程
Composite组合模式

Composite组合模式

作者: 淡淡的橙子 | 来源:发表于2018-04-16 15:51 被阅读0次

    前言:

    最近在看设计模式,首先推荐个不错的与设计模式相关的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图

    组合模式的UML图

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

    例子:

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

    // 最关键的一步,自己包含自己的一个List,Composite包含一个List<Composite>的属性
    public abstract class LetterComposite {
      private List<LetterComposite> 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<Letter> letters) {
        for (Letter l : letters) {
          this.add(l);
        }
      }
      @Override
      protected void printThisBefore() {
        System.out.print(" ");
      }
    }
    // 所有的对象只要扩展自LetterComposite即可
    public class Sentence extends LetterComposite {
      public Sentence(List<Word> words) {
        for (Word w : words) {
          this.add(w);
        }
      }
      @Override
      protected void printThisAfter() {
        System.out.print(".");
      }
    }
    

    组装:

    public class Messenger {
      LetterComposite messageFromOrcs() {
        List<Word> 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<Word> 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组合模式

        本文链接:https://www.haomeiwen.com/subject/xddekftx.html