23设计模式——组合模式

目录

组合(Composite)模式

适用场景

UML图

安全模式和透明模式

透明方式

安全方式

真实的组合模式

优缺点

实例——公司人员


组合(Composite)模式

本质:统一叶子对象和组合对象

组合模式也叫部分-整体模式。组合模式将对象组织到结构中,可以用来描述整体与部分的关系,可以使客户端将单纯元素与复合元素同等看待。

适用场景

  • 树形结构。
  • 需求中是体现部分与整体的结构。

让客户端统一操作组合对象和叶子对象,不再区分二者。如树形菜单、文件和文件夹管理,读XML文件等。

UML图(透明方式)

抽象构件(Component)角色:
给参与组合的对象规定共有方法和属性
树叶构件(Leaf)角色:
树叶对象,没有下级子对象。
树枝构件(Composite)角色:
树枝对象,有下级子对象,并实现Component类中规定的方法。

public abstract class Component {protected String name;public Component(String name) {super();this.name = name;}public abstract void add(Component c);public abstract void remove(Component c);public abstract void display(int depth);}
import java.util.ArrayList;public class Composite extends Component{private ArrayList children=new ArrayList();public Composite(String name) {super(name);}@Overridepublic void add(Component c) {children.add(c);}@Overridepublic void remove(Component c) {children.remove(c);}@Overridepublic void display(int depth) {System.out.println(depth+name);for(Component component :children){component.display(depth+1);}}
}
public class Leaf extends Component{public Leaf(String name) {super(name);}@Overridepublic void add(Component c) {//空实现,抛出一个"不支持请求"异常throw new UnsupportedOperationException();}@Overridepublic void remove(Component c) {throw new UnsupportedOperationException();}@Overridepublic void display(int depth) {System.out.println(depth+name);}}
public class Main {public static void main(String[] args) {//根节点Composite root=new Composite("root");//树枝Composite b1=new Composite("branch1");Leaf y1=new Leaf("leaf1");Leaf y2=new Leaf("leaf2");root.add(b1);b1.add(y1);b1.add(y2);root.display(0);}}

安全模式和透明模式

组合模式的实现根据所实现接口的区别分为两种形式:安全模式和透明模式。

组合模式必须在合适的地方提供子对象的管理方法,如:add、remove、display等。

透明方式

抽象类Component声明所有用来管理子类对象的方法,包括add,emove,display等,通过getChildren的返回值确认是叶子节点还是树枝节点

优点:树叶和树枝类有相同的接口。

树叶对象与树枝对象的区别起码在接口层次上消失了,客户端可以同等的对待所有的对象。

缺点:不够安全。

但树枝对象和叶子对象本质上是有区别的,叶子没有子对象,因此add,remove,display等方法没有意义,如果叶子生成子对象在编译时期不会出错,而会在运行时出错。

安全方式

Composite类里面声明所有的用来管理子类对象的方法

优点:安全。把树枝节点和树叶节点彻底分开,叶子没有管理子类对象的方法。

缺点:不够透明,树叶类和树枝类将具有不同的接口。

真实的组合模式

在项目中使用关系型数据库来存储这些信息。要求从数据库中直接提取出哪些人要分配到树枝,哪些人要分配到树叶,树枝与树枝、树叶的关系等。

 这张表定义了一个树形结构,我们要做的就是从数据库中把它读取出来,然后展现到前台上,用for循环加上递归就可以完成这个读取。用了数据库后,数据和逻辑已经在表中定义好了,我们直接读取放到树上就可以了。

优缺点

优点:

  • 简化了客户端调用。一棵树形机构中的所有节点都是Component,统一了组合对象和叶子对象。
  • 容易扩展。如果想增加一个树枝节点、树叶节点,只要找到它的父节点就成。

缺点:

  • 需要检测组件类型的时候,不能依靠编译期完成,必须在运行期间检测
  • 直接使用了实现类,与依赖倒置原则冲突

实例——公司人员

public abstract class Company {protected String name;protected String pos;public Company(String name, String pos) {super();this.name = name;this.pos = pos;}	public abstract void add(Company c);public abstract void remove(Company c);public abstract void display(int depth);
}
package com.oa;import java.util.ArrayList;
import java.util.List;import com.test.Component;public class ConcreteCompany extends Company{public ConcreteCompany(String name, String pos) {super(name, pos);}private List children=new ArrayList();@Overridepublic void add(Company c) {children.add(c);}@Overridepublic void remove(Company c) {children.remove(c);}@Overridepublic void display(int depth) {System.out.println(depth+":"+name+","+pos);for(Company company :children) {company.display(depth+1);}}}
package com.oa;public class Leaf extends Company{public Leaf(String name, String pos) {super(name, pos);}@Overridepublic void add(Company c) {throw new UnsupportedOperationException();}@Overridepublic void remove(Company c) {throw new UnsupportedOperationException();}@Overridepublic void display(int depth) {System.out.println(depth+":"+name+","+pos);}}
package com.oa;public class Main {public static void main(String[] args) {ConcreteCompany root=new ConcreteCompany("李华","CEO");ConcreteCompany b1=new ConcreteCompany("张三","经理");ConcreteCompany b2=new ConcreteCompany("小红","经理");Leaf y1=new Leaf("李四","员工");Leaf y2=new Leaf("王五","员工");Leaf y3=new Leaf("王明","员工");root.add(b1);b1.add(y1);b1.add(y2);root.add(b2);b2.add(y3);root.display(0);}}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部