java_composite

来源:互联网 发布:传媒大数据 编辑:程序博客网 时间:2024/06/05 10:40

introduction:

组合模式:
允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
组合模式让我们能用树形方式创建对象的结构,树里面包含了组合及个别的对象。
使用组合结构,我们能把相同的操作运用在组合和个别对象上。换句话说,在大多数情况下,我们可以忽略对象组合和个别对象之间的差别。
为了保证透明性,组合内所有的对象都必须实现相同的接口,这意味着对象具备一些没有意义的方法调用。
对于没哟意义的方法我们可以返回null或false,甚至可以抛出一个异常

demo: 以迭代器模式一样,模拟一天三餐,现在的情况与迭代器不同的是:我们现在可以组合菜单,顾名思义,我们现在一个菜单项可以出现在不同的菜单中,同样,一个菜单也可能出现在另一个菜单中,总而言之,现在的菜单结构变成了一个树形结构。树形结构的叶子节点相当于一个个菜单项,每一个中间节点相当于一个菜单。

description:

在组合模式中,所有的对象都继承于一个公共接口,公共接口中提供所有整体和部分分别需要实现的方法。

Component.java

public abstract class Component {        public void add(Component component){        throw new UnsupportedOperationException();    }        public void remove(Component component){        throw new UnsupportedOperationException();    }        public void print(){        throw new UnsupportedOperationException();    }        public void getName(String name){        throw new UnsupportedOperationException();    }    public void getPrice(Double price){        throw new UnsupportedOperationException();    }        public Component getChild(int i){        throw new UnsupportedOperationException();    }        public Iterator<Component> createIterator(){        throw new UnsupportedOperationException();    }}
对于叶子节点只需要实现公共接口中有用的方法

Leaf.java

/** * 该类为一个个别对象,也就是组合模式中所说的部分 * 该类只需要重写公共接口中的一部分方法(因为有些方法在这个类中不适用) */public class Leaf extends Component{    private String name;        private Double price;            /**     * @param name     * @param price     */    public Leaf(String name, Double price) {        this.name = name;        this.price = price;    }    @Override    public void getName(String name) {        this.name = name;    }    @Override    public void getPrice(Double price) {        this.price = price;    }        @Override    public void print() {        System.out.println("--- leaf ---");        System.out.print(name+"---");        System.out.println(price);    }    @Override    public Iterator<Component> createIterator() {        return new NullIterator();    }    }

空迭代器:实际上什么也没有做,可是这样做不会返回null

NullIterator.java

public class NullIterator implements Iterator<Component>{    @Override    public boolean hasNext() {        return false;    }    @Override    public Component next() {        return null;    }    @Override    public void remove() {        throw new UnsupportedOperationException();    }}

对于组合节点同样只需要实现公共接口中有用的接口就可以了

Composite.java

/** * 该类为一个组合对象,也就是我们所说的整体 * 同样该类只需要重写公共接口中一部分方法 */public class Composite extends Component{    private ArrayList<Component> components = new ArrayList<Component>();        private String name;        private Double price;            /**     * @param name     * @param price     */    public Composite(String name, Double price) {        this.name = name;        this.price = price;    }    @Override    public void add(Component component) {        components.add(component);    }    @Override    public void remove(Component component) {        components.remove(component);    }    @Override    public void print() {        System.out.println("--- Composite ---");        System.out.print(name+" --- ");        System.out.println(price+" --- ");                Iterator<Component> componentIterator = components.iterator();        while(componentIterator.hasNext()){            componentIterator.next().print();        }    }    @Override    public Iterator<Component> createIterator() {        return new CompositeIterator(components.iterator());    }    }
下面这段代码是难点,下面实现的是一个外部迭代器,所以必须维护它在遍历中的位置,以便外部客户可以通过hasNext()和next()来驱动遍历。

CompositeIterator.java

public class CompositeIterator implements Iterator<Component>{    /**     * 将所有的迭代器都存储在栈中     */    private Stack<Iterator<Component>> stack = new Stack<Iterator<Component>>();        public CompositeIterator(Iterator<Component> componentIterator){        stack.push(componentIterator);    }        /**     *      */    @Override    public boolean hasNext() {        if(stack.isEmpty()){            return false;        }else{            Iterator<Component> iterator = stack.peek();            if(!iterator.hasNext()){                stack.pop();                return hasNext();            }else{                return true;            }        }    }    @Override    public Component next() {        if(hasNext()){            Iterator<Component> iterator = stack.peek();            Component component = iterator.next();            if(component instanceof Composite){                stack.push(component.createIterator());            }            return component;        }        return null;    }    @Override    public void remove() {        throw new UnsupportedOperationException();    }}

最后,测试以上代码:

Test.java

public class Test {    public static void main(String[] args) {        Component breakfast = new Composite("早餐",5.00);        Component lunch = new Composite("午餐",15.00);        Component diner = new Composite("晚餐",10.00);                Component drink = new Composite("饮料",3.00);                breakfast.add(new Leaf("面包",2.00));        breakfast.add(new Leaf("牛奶",3.00));                lunch.add(new Leaf("带鱼",5.00));        lunch.add(new Leaf("臭豆腐",3.00));        lunch.add(new Leaf("茄子烧肉",4.00));        lunch.add(drink);                diner.add(new Leaf("红烧鳊鱼",5.00));        diner.add(new Leaf("鸡蛋菜汤",3.00));        diner.add(new Leaf("青菜",2.00));        diner.add(lunch);                drink.add(new Leaf("冰红茶",3.00));                Component components = new Composite("一天三餐",30.00);        components.add(breakfast);        components.add(lunch);        components.add(diner);        Client c = new Client(components);        c.printComponent();    }}

输出结果:

--- Composite ---
一天三餐 --- 30.0 --- 
--- Composite ---
早餐 --- 5.0 --- 
--- leaf ---
面包---2.0
--- leaf ---
牛奶---3.0
--- Composite ---
午餐 --- 15.0 --- 
--- leaf ---
带鱼---5.0
--- leaf ---
臭豆腐---3.0
--- leaf ---
茄子烧肉---4.0
--- Composite ---
饮料 --- 3.0 --- 
--- leaf ---
冰红茶---3.0
--- Composite ---
晚餐 --- 10.0 --- 
--- leaf ---
红烧鳊鱼---5.0
--- leaf ---
鸡蛋菜汤---3.0
--- leaf ---
青菜---2.0
--- Composite ---
午餐 --- 15.0 --- 
--- leaf ---
带鱼---5.0
--- leaf ---
臭豆腐---3.0
--- leaf ---
茄子烧肉---4.0
--- Composite ---
饮料 --- 3.0 --- 
--- leaf ---
冰红茶---3.0



原创粉丝点击