• 组合模式(Composite)


    @@@模式定义:
    将对象组合成树型结构以表示“部分-整体”的层次结构。
    组合模式使得用户对单个对象和组合对象的使用具有一致性。

    @@@练习示例: 
    商品类别树

    @@@示例代码:
    <不用模式>
    productLeaf.java

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package product;
    
    /**
     * 叶子对象
     */
    public class Leaf {
        /**
         * 叶子对象的名字
         */
    	private String name = "";
    	
    	/**
    	 * 构造方法,传入叶子对象的名字
    	 * @param name 叶子对象的名字
    	 */
    	public Leaf(String name) {
    		this.name = name;
    	}
    	
    	/**
    	 * 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字
    	 * @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
    	 */
    	public void printStruct(String preStr) {
    		System.out.println(preStr + "-" + name);
    	}
    }
    


    productComposite.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package product;
    
    import java.util.ArrayList;
    import java.util.Collection;
    
    /**
     * 组合对象,可以包含其他组合对象或者叶子对象
     */
    public class Composite {
        /**
         * 用来记录包含的其他组合对象
         */
    	private Collection<Composite> childComposite =
    		new ArrayList<Composite>();
    	
    	/**
    	 * 用来记录包含的其他叶子对象
    	 */
    	private Collection<Leaf> childLeaf = 
    		new ArrayList<Leaf>();
    	
    	/**
    	 * 组合对象的名字
    	 */
    	private String name = "";
    	
    	/**
    	 * 构造方法,传入组合对象的名字
    	 * @param name 组合对象的名字
    	 */
    	public Composite(String name) {
    		this.name = name;
    	}
    	
    	/**
    	 * 向组合对象加入被它包含的其他组合对象
    	 * @param c 被它包含的其他组合对象
    	 */
    	public void addComposite(Composite c) {
    		this.childComposite.add(c);
    	}
    	
    	/**
    	 * 向组合对象加入被它包含的叶子对象
    	 * @param leaf 被它包含的叶子对象
    	 */
    	public void addLeaf(Leaf leaf) {
    		this.childLeaf.add(leaf);
    	}
    	
    	/**
    	 * 输出组合对象自身的结构
    	 * @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
    	 */
    	public void printStruct(String preStr) {
    		// 先把自己输出去
    		System.out.println(preStr + "" + this.name);
    		// 然后添加一个空格,表示向后缩进一个空格,输出自己包含的叶子对象
    		preStr += " ";
    		for(Leaf leaf : childLeaf) {
    			leaf.printStruct(preStr);
    		}
    		
    		// 输出当前对象的字对象
    		for(Composite c : childComposite) {
    			// 递归输出每个子对象
    			c.printStruct(preStr);
    		}
    	}
    }


    userClient.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package user;
    
    import product.Composite;
    import product.Leaf;
    
    public class Client {
    	public static void main(String[] args) {
            // 定义所有的组合对象
    		Composite root = new Composite("服装");
    		Composite c1 = new Composite("男装");
    		Composite c2 = new Composite("女装");
    		
    		// 定义所有的叶子对象
    		Leaf leaf1 = new Leaf("衬衣");
    		Leaf leaf2 = new Leaf("夹克");
    		Leaf leaf3 = new Leaf("裙子");
    		Leaf leaf4 = new Leaf("套装");
    		
    		// 按照树的结构来组合组合对象和叶子对象
    		root.addComposite(c1);
    		root.addComposite(c2);
    		c1.addLeaf(leaf1);
    		c1.addLeaf(leaf2);
    		c2.addLeaf(leaf3);
    		c2.addLeaf(leaf4);
    		
    		// 调用根对象的输出功能来输出整棵树
    		root.printStruct("");
    	}
    }


    <问题描述>
    必须区分组合对象和叶子对象,并进行有区别的对待;

    <使用模式>
    patternComponent.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package pattern;
    
    /**
     * 抽象的组件对象
     */
    public abstract class Component {
        /**
         * 输出组件自身的名称
         */
    	public abstract void printStruct(String preStr);
    	
    	/**
    	 * 向组合对象中加入组件对象
    	 * @param child 被加入组合对象中的组件对象
    	 */
    	public void addChild(Component child) {
    		throw new UnsupportedOperationException("不支持该功能");
    	}
    	
    	/**
    	 * 从组合对象中移出某个组件对象
    	 * @param child 被移出的组件对象
    	 */
    	public void removeChild(Component child) {
    		throw new UnsupportedOperationException("不支持该功能");
    	}
    	
    	/**
    	 * 返回某个索引对应的组件对象
    	 * @param index 需要获取的组件对象的索引,索引从0开始
    	 * @return 索引对应的组件对象
    	 */
    	public Component getChildren(int index) {
    		throw new UnsupportedOperationException("不支持该功能");		
    	}
    }


    patternLeaf.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package pattern;
    
    /**
     * 叶子对象
     */
    public class Leaf extends Component {
    	/**
         * 叶子对象的名字
         */
    	private String name = "";
    	
    	/**
    	 * 构造方法,传入叶子对象的名字
    	 * @param name 叶子对象的名字
    	 */
    	public Leaf(String name) {
    		this.name = name;
    	}
    	
    	/**
    	 * 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字
    	 * @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
    	 */
    	@Override
    	public void printStruct(String preStr) {
    		System.out.println(preStr + "-" + name);
    	}
    }


    patternComposite.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package pattern;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 组合对象,可以包含其他组合对象或者叶子对象
     */
    public class Composite extends Component {
    	/**
         * 用来存储组合对象中包含的子组件对象
         */
    	private List<Component> childComonents = null;
    	
    	/**
    	 * 组合对象的名字
    	 */
    	private String name = "";
    	
    	/**
    	 * 构造方法,传入组合对象的名字
    	 * @param name 组合对象的名字
    	 */
    	public Composite(String name) {
    		this.name = name;
    	}
    	
    	@Override
    	public void addChild(Component child) {
    		// 延迟初始化
    		if (childComonents == null) {
    			childComonents = new ArrayList<Component>();	
    		}
    		
    		childComonents.add(child);
    	}
    	
    	/**
    	 * 输出组合对象自身的结构
    	 * @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
    	 */
    	@Override
    	public void printStruct(String preStr) {
    		// 先把自己输出去
    		System.out.println(preStr + "" + this.name);
    		// 如果还包含有子组件,那么就输出这些子组件对象
    		if (this.childComonents != null) {
    			// 添加一个空格,表示向后缩进一个空格
    			preStr += " ";
    			// 输出当前对象的子对象
    			for (Component c : childComonents) {
    				// 递归输出每个子对象
    				c.printStruct(preStr);
    			}
    		}
    	}
    }


    userCilentPattern.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package user;
    
    import pattern.Component;
    import pattern.Composite;
    import pattern.Leaf;
    
    public class CilentPattern {
    	public static void main(String[] args) {
            // 定义所有的组合对象
    		Component root = new Composite("服装");
    		Component c1 = new Composite("男装");
    		Component c2 = new Composite("女装");
    		
    		// 定义所有的叶子对象
    		Component leaf1 = new Leaf("衬衣");
    		Component leaf2 = new Leaf("夹克");
    		Component leaf3 = new Leaf("裙子");
    		Component leaf4 = new Leaf("套装");
    		
    		// 按照树的结构来组合组合对象和叶子对象
    		root.addChild(c1);
    		root.addChild(c2);
    		c1.addChild(leaf1);
    		c1.addChild(leaf2);
    		c2.addChild(leaf3);
    		c2.addChild(leaf4);
    		
    		// 调用根对象的输出功能来输出整棵树
    		root.printStruct("");
    	}
    }


    @@@模式的实现:
    1. 有“安全性”和“透明性”两种实现方式;

    @@@模式的优点:
    1. 定义了包含基本对象和组合对象的类层次结构;
    2. 统一了组合对象和叶子对象;
    3. 简化了客户端调用;
    4. 更容易扩展;

    @@@模式的缺点:
    1. 很难限制组合中的组件类型;

    @@@模式的本质:
    统一叶子对象和组合对象。

    @@@模式体现的设计原则:
    NA


  • 相关阅读:
    比赛分组 功能描述:两个乒乓球队进行比赛,各出三人。 甲队为A、B、C三人,乙队为X、Y、Z 三人,已经抽签决定了比赛名单。 已知A 不和X 比,C 不和X、Z 比,请问比赛名单是什么。(用到了三重循环)
    输入一个五位正整数,使用数组判断它是不是回文数(例如12321是回文)
    删除数组元素 功能描述:有一个有序整数数组,要求输入一个数字, 在数组中查找是否有这个数,如果有,将该数从数组中删除, 要求删除后的数组仍然保持有序;
    将一个给定的整型数组转置输出(二维数组)
    有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。
    使用二重循环和break语句,找出2~100内所有的质数
    使用多重循环打印6阶杨辉三角
    使用Arrays.copyOf()数组合并并排序
    设置Android Studio启动时可选最近打开过的工程
    如何将Eclipse中的项目迁移到Android Studio 中
  • 原文地址:https://www.cnblogs.com/riskyer/p/3221703.html
Copyright © 2020-2023  润新知