上周面试,面试官问桥接模式是什么,我就举了个例子:手机分为苹果,小米....,每个手机都有视频,游戏...等功能。直观上是一个树形结构。这种情况下,可以用桥接模式,把手机作为接口,苹果,小米等继承手机接口;再用一个手机软件接口,让视频,游戏等继承手机软件接口;在手机中保留软件指针。这样可以让具体的手机和手机软件解耦。然后面试官说,这个case可以用组合模式。我就说不知道组合模式。回来看了一下组合模式。

组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。重点是理解清楚“部分/整体”还有“单个对象”和“组合对象”的含义。在树形结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样处理复杂元素,从而使得客户程序与复杂元素的内部解耦。

角色:

1:Component 是组合中的对象声明接口,在适当的情况下,实现所有类公有接口的默认行为。声明一个接口用于访问和管理Component子部件。

2:Leaf 在组合中表示叶子节点对象,叶子节点没有子节点。

3:Composite定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如add和remove等。

应用场景

1:想表示对象的部分-整体层次结构。

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

经典案例:系统目录结构,网站导航结构,文件系统。

代码示意:做一套办公管理系统,并且总公司的人力资源部、财务部等的办公挂历功能在所有的分公司都有。

 

      

//  公司的抽象类或接口(Component)

public abstract class Company {

protected String name;

public Company(String name)
{
this.name = name;
}

public abstract void add(Company company);
public abstract void remove(Company company);
public abstract void display(int depth);
public abstract void lineofDuty();

}

//  具体公司类,是树枝节点(Composite)

import java.util.ArrayList;
import java.util.List;

public class ConcreteCompany extends Company {

private List<Company> childrenCompany = new ArrayList<Company>();

public ConcreteCompany(String name) {
super(name);
// TODO Auto-generated constructor stub
}

@Override
public void add(Company company) {
childrenCompany.add(company);
}

@Override
public void remove(Company company) {
childrenCompany.remove(company);
}

@Override
public void display(int depth) {
}

@Override
public void lineofDuty() {
}
}

// 财务部和人力资源部门(leaf)

public class FinanceDepartment extends Company {

public FinanceDepartment(String name) {
super(name);
// TODO Auto-generated constructor stub
}

@Override
public void add(Company company) {
}

@Override
public void remove(Company company) {
}

@Override
public void display(int depth) {
}

@Override
public void lineofDuty() {
System.out.println(name + " 负责公司财务收支管理");
}
}

public class HRDepartment extends Company {

public HRDepartment(String name) {
super(name);
}

@Override
public void add(Company company) {
}

@Override
public void remove(Company company) {
}

@Override
public void display(int depth) {
}

@Override
public void lineofDuty() {
System.out.println(name + " 负责员工招聘管理培训");
}
}

// 测试类

public class CompositePatternDemo {
public static void main(String[] args) {
// 一个总公司,包含HR部门和财务部门
ConcreteCompany root = new ConcreteCompany("北京总公司");
root.add(new HRDepartment("总公司人力资源部"));
root.add(new FinanceDepartment("总公司财务部"));

//2个子公司,每个子公司都有HR部门和财务部门
ConcreteCompany com1 = new ConcreteCompany("广州分公司");
com1.add(new HRDepartment("广州分公司人力资源部"));
com1.add(new FinanceDepartment("广州分公司财务部"));
root.add(com1);

ConcreteCompany com2 = new ConcreteCompany("杭州分公司");
com2.add(new HRDepartment("杭州分公司人力资源部"));
com2.add(new FinanceDepartment("杭州分公司财务部"));
root.add(com2);
}
}

总结:

        优点: 节点可以自由增加。

                     客户调用简单,统一的方式调用。

        缺点: 叶子(leaf)和树枝节点(Composite)都是实现类,而不是接口,违反了依赖倒置原则。

最新文章

  1. Asp.net中实现同一用户名不能同时登录(单点登录)
  2. centos 安装haproxy 1.6.3
  3. uiwebview加载中文URL
  4. struts2结果类型
  5. a标签替代input的submit提交功能
  6. crontab 指定执行用户
  7. Script Form
  8. ASP.NET MVC3开发-数据库篇之CodeFisrt开发(一)
  9. Java基础总结--变量、运算符总结
  10. 微信app支付详细教程
  11. UVA1349:Optimal Bus Route Design
  12. (汇总)os模块以及shutil模块对文件的操作
  13. js对HTML字符转义与反转义
  14. Codeforces 346D Robot Control(01BFS)
  15. tensorflow的variable的eval()和read_eval()有什么不同
  16. EDK II之USB设备驱动程序的加载与运行
  17. [Vue warn]: Error in render: &quot;SyntaxError: Unexpected token &#39; in JSON at position 1&quot;
  18. 兵器簿之cocoaPods的安装和使用
  19. python赋值、浅拷贝、深拷贝区别
  20. sql脚本创建用户角色权限表

热门文章

  1. Spring核心思想——IOC和DI
  2. Corosync+pacemaker实现集群的高可用
  3. Laravel 文件夹结构简介
  4. CString与输入输出流对象问题。
  5. Git 之 问题集锦
  6. SAPUI5使用了哪些开源技术
  7. I.MX6 linux eGalaxTouch 自动获取设备节点
  8. 拦截器springmvc防止表单重复提交【3】3秒后自动跳回首页【重点明白如何跳转到各自需要的页面没有实现 但是有思路】
  9. 每天一个linux命令:【转载】cp命令
  10. LeetCode Word Abbreviation