zoukankan      html  css  js  c++  java
  • GOF设计模式——Composite模式

    一、什么是Composite模式?

            Composite模式,可以借助计算机文件夹的例子去理解,一个文件夹里面可以存放文件,也可以存放子文件夹,这样子形成一种结构,这个“文件夹”就类似于一个容器,而且还是一种具有递归结构的容器。我们可以用Composite模式创造出这样的结构,使得容器和内容具有一致性

    二、Composite模式的原理

    Client:使用Composite模式的相关类;

    Leaf类:表示内容,可以是计算机系统文件夹里面的“文件”;

    Composite类:表示容器,可以是计算机系统的文件夹,或者子文件夹;

    Compenent类:这是一个抽象类,使得Leaf和Composite具有一致性的类;

    三、Composite模式示例

    1、Entry类:表示目录条目的抽象类,File类和Directory类是它的子类。

    package com.cjs.composite;
     
    public abstract class Entry {
        //获取名字
        public abstract String getName();
        //获取大小
        public abstract int getSize();
        //加入目录条目
        public Entry add(Entry entry) throws FileTreatMentException{
            throw new FileTreatMentException();
        }
     
        public void printList() {
            printList("");
        }
     
        protected abstract void printList(String prefix);
     
        public String toString() {
            return getName() + " (" + getSize() + ")";
        }
    }

            目录条目与一个名字,可以通过getName方法获取这个名字,每一个条目都有一个大小,这个大小的值由getSize方法获取,另外还定义了一个add方法,用于添加子文件夹或者其他类型的文件。

    2、File类:表示文件的类,继承Entry类,并实现父类Entry的抽象方法;

    package com.cjs.composite;
     
    public class File extends Entry {
        private String name;
     
        private int size;
     
        public File(String name, int size) {
            this.name = name;
            this.size = size;
        }
     
        @Override
        public String getName() {
            return name;
        }
     
        @Override
        public int getSize() {
            return size;
        }
     
        @Override
        protected void printList(String prefix) {
            System.out.println(prefix+"/"+this);
        }
    }

    3、Directory类:表示文件夹类,实现了父类Entry的抽象方法。

    package com.cjs.composite;
     
    import com.cjs.Strategy.Strategy;
     
    import java.util.ArrayList;
    import java.util.Iterator;
     
    public class Directory extends Entry {
        private String name;//文件夹名字
        private ArrayList directory = new ArrayList();//文件夹中目录条目的集合
     
        public Directory(String name) {
            this.name = name;
        }
     
        @Override
        public String getName() {
            return name;
        }
     
        @Override
        public int getSize() {
            int size = 0;
            Iterator it = directory.iterator();
            while (it.hasNext()) {
                Entry entry = (Entry) it.next();
                size += entry.getSize();
            }
            return size;
        }
     
        @Override
        protected void printList(String prefix) {
            System.out.println(prefix + "/" + this);
            Iterator it = directory.iterator();
            while (it.hasNext()) {
                Entry entry = (Entry) it.next();
                entry.printList(prefix+"/"+name);
            }
        }
     
        //增加目录条目
        public Entry add(Entry entry) {
            directory.add(entry);
            return this;
        }
    }

            因为是文件夹的类,所以定义了一个ArrayList类型的字段directory,用来保存文件夹中的目录条目,getSize方法则是用递归来计算其大小。

    4、Main类

    package com.cjs.composite;
     
    import com.cjs.composite.Directory;
     
    public class Main {
        public static void main(String[] args) {
            try {
                System.out.println("Making root entries...");
                Directory rootdir = new Directory("root");
                Directory bindir = new Directory("bin");
                Directory tmpdir = new Directory("tmp");
                Directory userdir = new Directory("usr");
                rootdir.add(bindir);
                rootdir.add(tmpdir);
                rootdir.add(userdir);
                bindir.add(new File("vi", 10000));
                bindir.add(new File("latex", 20000));
                rootdir.printList();
     
                System.out.println("");
                System.out.println("Making user entries...");
                Directory yuki = new Directory("yuki");
                Directory hanako = new Directory("hanako");
                Directory tomura = new Directory("tomura");
                userdir.add(yuki);
                userdir.add(hanako);
                userdir.add(tomura);
                yuki.add(new File("diary.html", 100));
                yuki.add(new File("memo.txt", 300));
                hanako.add(new File("composite.java", 200));
                tomura.add(new File("game.doc", 400));
                tomura.add(new File("junk.mail", 500));
                rootdir.printList();
            } catch (FileTreatMentException e) {
                e.printStackTrace();
            }
        }
    }

    预期文件夹层次结构:

    输出结果:

  • 相关阅读:
    C puzzles详解【51-57题】
    C puzzles详解【46-50题】
    C puzzles详解【38-45题】
    C puzzles详解【34-37题】
    C puzzles详解【31-33题】
    C puzzles详解【26-30题】
    C puzzles详解【21-25题】
    C puzzles详解【16-20题】
    使用C++模板实现栈的求最小值功能
    模拟求幂运算,考虑的已经很周全了
  • 原文地址:https://www.cnblogs.com/SysoCjs/p/10396481.html
Copyright © 2011-2022 走看看