zoukankan      html  css  js  c++  java
  • 设计模式(13)>Composite 组合模式 小强斋

    一、组合模式定义

    概述:将对象组合成树形结构以表示"部分-整体"的层次结构。"Composite"使得用户对单个对象和组合对象的使用具有一致性。

    二、适用场合:

    2.1当想表达对象的部分-整体的层次结构时(部门、菜单、树形结构)

    2.2 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象时。

    三、模式解读

    3.1类图

    3.2组合模式中的角色

    1. 组合部件(Component):它是一个抽象角色,为要组合的对象提供统一的接口。
    2. 叶子(Leaf):在组合中表示子节点对象,叶子节点不能有子节点。
    3. 合成部件(Composite):定义有枝节点的行为,用来存储部件,实现在Component接口中的有关操作,如增加(Add)和删除(Remove)。

    四、例子

    部门人员的例子(经理有下属,编程人员没有下属)

    组合部件--职员类

    import java.util.List;
    
    public abstract class Employer {
    
    	private String name;//职员姓名
    	private String positin;//职员职位
    	private int salary;//职员薪水
    
    	protected List<Employer> employers; //下属
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public String getName() {
    		return this.name;
    	}
    
    	public int getSalary() {
    		return salary;
    	}
    
    	public void setSalary(int salary) {
    		this.salary = salary;
    	}
    
    	public String getPositin() {
    		return positin;
    	}
    
    	public void setPositin(String positin) {
    		this.positin = positin;
    	}
    
    	public Employer(String name, String positin, int salary) {
    		this.name = name;
    		this.positin = positin;
    		this.salary = salary;
    	}
    
    	public abstract void add(Employer employer);//添加下属
    
    	public abstract void delete(Employer employer);//移除下属
    	
        //打印职工信息
    	public void printInfo() {
    		System.out.println(name + "\t" + positin + "    \t" + salary);
    	}
    
    	public List<Employer> getEmployers() {
    		return employers;
    	}
    }
    

    叶子类型----编程员 没有下属

    //程序员类 没有下属
    public class Programmer extends Employer {
    
    	public Programmer(String name, String positin, int salary) {
    		super(name, positin, salary);
    		employers = null;
    	}
    
    	// 程序员, 表示没有下属了
    	public void add(Employer employer) {
    
    	}
    
    	public void delete(Employer employer) {
    
    	}
    }
    

    树枝类型----项目经理 有下属

    //项目经理类 有下属
    import java.util.ArrayList;
    
    public class ProjectManager extends Employer {
    
    	public ProjectManager(String name, String positin, int salary) {
    		super(name, positin, salary);
    		employers = new ArrayList<Employer>();
    	}
    
    	public void add(Employer employer) {
    		employers.add(employer);
    	}
    
    	public void delete(Employer employer) {
    		if (employers.contains(employer)) {
    			employers.remove(employer);
    		}
    
    	}
    
    }
    

    Client

    import java.util.List;
    
    public class Client {
    
    	public static void main(String[] args) {
    		Employer pm = new ProjectManager("吴老板", "项目经理", 100000);
    
    		Employer pa = new ProjectManager("magang", "项目副经理", 3000);
    		Employer programmer1 = new Programmer("wsz", "程序员", 800);
    		Employer programmer2 = new Programmer("ss", "程序员", 800);
    		Employer programmer3 = new Programmer("xy", "程序员", 800);
    
    		pm.add(pa);// 为项目经理添加项目助理
    		pa.add(programmer1);// 项目经理加程序员
    		pa.add(programmer2);// 项目经理加程序员
    		pa.add(programmer3);// 项目经理加程序员
    
    		System.out.println("姓名\t" + "职位\t" + "         薪水\t");
    		printTreeInfo(pm);
    	}
    
    	public static void printTreeInfo(Employer root) {
    		root.printInfo();
    		if (root instanceof ProjectManager) {
    			List<Employer> list = root.getEmployers();
    			for (Employer employer : list)
    				printTreeInfo(employer);
    
    		}
    
    	}
    }

    运行结果

    姓名         职位          薪水 
    吴老板       项目经理      100000
    magang       项目副经理    3000
    wsz          程序员        800
    ss           程序员        800
    xy           程序员        800

    五. 透明方式与安全方式

    5.1透明方式:在Component中声明所有来管理子对象的方法,其中包括AddRemove等。这样实现Component接口的所有子类都具备了AddRemove方法。这样做的好处是叶节点和枝节点对于外界没有区别,它们具备完全一致的接口。

    5.2安全方式:在Component中不去声明AddRemove方法,那么子类的Leaf就不需要实现它,而是在Composit声明所有用来管理子类对象的方法。

    5.3两种方式有缺点:对于透明方式,客户端对叶节点和枝节点是一致的,但叶节点并不具备AddRemove的功能,因而对它们的实现是没有意义的;对于安全方式,叶节点无需在实现AddRemove这样的方法,但是对于客户端来说,必须对叶节点和枝节点进行判定,为客户端的使用带来不便。

    六. 模式总结

    6.1 优点

    6.1.1使客户端调用简单,它可以一致使用组合结构或是其中单个对象,简化了客户端代码。

    6.1.2容易在组合体内增加对象部件。客户端不必因加入了新的部件而更改代码。有利于功能的扩展。

    6.2 缺点

    6.2.1需要抉择使用透明方式还是安全方式。

    6.2.2透明方式违背了面向对象的单一职责原则;安全方式增加了客户需要端判定的负担。

     

  • 相关阅读:
    【LeetCode】17. Letter Combinations of a Phone Number
    【LeetCode】16. 3Sum Closest
    【LeetCode】15. 3Sum 三个数和为0
    【LeetCode】14. Longest Common Prefix 最长前缀子串
    【LeetCode】13. Roman to Integer 罗马数字转整数
    【LeetCode】12. Integer to Roman 整型数转罗马数
    【LeetCode】11. Container With Most Water
    【LeetCode】10. Regular Expression Matching
    Models of good programmer
    RSA Algorithm
  • 原文地址:https://www.cnblogs.com/xiaoqiangzhaitai/p/5429331.html
Copyright © 2011-2022 走看看