设计模式之Composite(组合)(转)
Composite定义:
将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性.
Composite比较容易理解,想到Composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时,Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。
所以Composite模式使用到Iterator模式,和Chain of Responsibility模式类似。
Composite好处:
1.使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关系自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。
2.更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。
如何使用Composite?
首先定义一个接口或抽象类,这是设计模式通用方式了,其他设计模式对接口内部定义限制不多,Composite却有个规定,那就是要在接口内部定义一个用于访问和管理Composite组合体的对象们(或称部件Component).
下面的代码是以抽象类定义,一般尽量用接口interface
public abstract class Equipment
{
private String name;
//网络价格
public abstract double netPrice();
//折扣价格
public abstract double discountPrice();
//增加部件方法
public boolean add(Equipment equipment) { return false; }
//删除部件方法
public boolean remove(Equipment equipment) { return false; }
//注意这里,这里就提供一种用于访问组合体类的部件方法。
public Iterator iter() { return null; }
public Equipment(final String name) { this.name=name; }
}
抽象类Equipment就是Component定义,代表着组合体类的对象们,Equipment中定义几个共同的方法。
public class Disk extends Equipment
{
public Disk(String name) { super(name); }
//定义Disk网络价格为1
public double netPrice() { return 1.; }
//定义了disk折扣价格是0.5 对折。
public double discountPrice() { return .5; }
}
Disk是组合体内的一个对象,或称一个部件,这个部件是个单独元素( Primitive)。
还有一种可能是,一个部件也是一个组合体,就是说这个部件下面还有'儿子',这是树形结构中通常的情况,应该比较容易理解。现在我们先要定义这个组合体:
abstract class CompositeEquipment extends Equipment
{
private int i=0;
//定义一个Vector 用来存放'儿子'
private Lsit equipment=new ArrayList(); public CompositeEquipment(String name) { super(name); } public boolean add(Equipment equipment) {
this.equipment.add(equipment);
return true;
} public double netPrice()
{
double netPrice=0.;
Iterator iter=equipment.iterator();
for(iter.hasNext())
netPrice+=((Equipment)iter.next()).netPrice();
return netPrice;
} public double discountPrice()
{
double discountPrice=0.;
Iterator iter=equipment.iterator();
for(iter.hasNext())
discountPrice+=((Equipment)iter.next()).discountPrice();
return discountPrice;
}
//注意这里,这里就提供用于访问自己组合体内的部件方法。
//上面dIsk 之所以没有,是因为Disk是个单独(Primitive)的元素.
public Iterator iter()
{
return equipment.iterator() ;
{
//重载Iterator方法
public boolean hasNext() { return i<equipment.size(); }
//重载Iterator方法
public Object next()
{
if(hasNext())
return equipment.elementAt(i++);
else
throw new NoSuchElementException();
}
}
上面CompositeEquipment继承了Equipment,同时为自己里面的对象们提供了外部访问的方法,重载了Iterator,Iterator是Java的Collection的一个接口,是Iterator模式的实现.
我们再看看CompositeEquipment的两个具体类:盘盒Chassis和箱子Cabinet,箱子里面可以放很多东西,如底板,电源盒,硬盘盒等;盘盒里面可以放一些小设备,如硬盘软驱等。无疑这两个都是属于组合体性质的。
public class Chassis extends CompositeEquipment
{
public Chassis(String name) { super(name); }
public double netPrice() { return 1.+super.netPrice(); }
public double discountPrice() { return .5+super.discountPrice(); }
} public class Cabinet extends CompositeEquipment
{
public Cabinet(String name) { super(name); }
public double netPrice() { return 1.+super.netPrice(); }
public double discountPrice() { return .5+super.discountPrice(); }
}
至此我们完成了整个Composite模式的架构。
我们可以看看客户端调用Composote代码:
Cabinet cabinet=new Cabinet("Tower");
Chassis chassis=new Chassis("PC Chassis");
//将PC Chassis装到Tower中 (将盘盒装到箱子里)
cabinet.add(chassis);
//将一个10GB的硬盘装到 PC Chassis (将硬盘装到盘盒里)
chassis.add(new Disk("10 GB"));
//调用 netPrice()方法;
System.out.println("netPrice="+cabinet.netPrice());
System.out.println("discountPrice="+cabinet.discountPrice());
上面调用的方法netPrice()或discountPrice(),实际上Composite使用Iterator遍历了整个树形结构,寻找同样包含这个方法的对象并实现调用执行.
Composite是个很巧妙体现智慧的模式,在实际应用中,如果碰到树形结构,我们就可以尝试是否可以使用这个模式。
以论坛为例,一个版(forum)中有很多帖子(message),这些帖子有原始贴,有对原始贴的回应贴,是个典型的树形结构,那么当然可以使用Composite模式,那么我们进入Jive中看看,是如何实现的.
Jive解剖
在Jive中 ForumThread是ForumMessages的容器container(组合体).也就是说,ForumThread类似我们上例中的 CompositeEquipment.它和messages的关系如图:
[thread]
|- [message]
|- [message]
|- [message]
|- [message]
|- [message]
我们在ForumThread看到如下代码:
public interface ForumThread {
....
public void addMessage(ForumMessage parentMessage, ForumMessage newMessage)
throws UnauthorizedException;
public void deleteMessage(ForumMessage message)
throws UnauthorizedException;
public Iterator messages();
....
}
类似CompositeEquipment, 提供用于访问自己组合体内的部件方法: 增加 删除 遍历.
结合我的其他模式中对Jive的分析,我们已经基本大体理解了Jive论坛体系的框架,如果你之前不理解设计模式,而直接去看Jive源代码,你肯定无法看懂。
转自:http://www.jdon.com 板桥里人
设计模式之Composite(组合)(转)的更多相关文章
- 设计模式(9)--Composite(组合模式)--结构型
1.模式定义: 组合模式属于对象的结构模式,有时又叫做“部分——整体”模式.组合模式将对象组织到树结构中,可以用来描述整体与部分的关系.组合模式可以使客户端将单纯元素与复合元素同等看待. 2.模式特点 ...
- 设计模式之——Composite组合模式
上周面试,面试官问桥接模式是什么,我就举了个例子:手机分为苹果,小米....,每个手机都有视频,游戏...等功能.直观上是一个树形结构.这种情况下,可以用桥接模式,把手机作为接口,苹果,小米等继承手机 ...
- 设计模式08: Composite 组合模式(结构型模式)
Composite 组合模式(结构型模式) 对象容器的问题在面向对象系统中,我们常会遇到一类具有“容器”特征的对象——即他们在充当对象的同时,又是其他对象的容器. public interface I ...
- 一天一个设计模式——Composite组合模式
一.模式说明 能够使容器与内容物具有一致性,创造出递归结构的模式就是Composite组合模式. 举个例子:计算机中的文件系统中有文件和文件夹的概念,我们知道,文件夹可以包含文件,也可以包含子文件夹, ...
- C++设计模式-Composite组合模式
Composite组合模式作用:将对象组合成树形结构以表示“部分-整体”的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. UML图如下: 在Component中声明所有用来 ...
- 十一、Composite 组合模式
原理: 代码清单 Entity public abstract class Entry { public abstract String getName(); public abstract int ...
- java23种设计模式——八、组合模式
目录 java23种设计模式-- 一.设计模式介绍 java23种设计模式-- 二.单例模式 java23种设计模式--三.工厂模式 java23种设计模式--四.原型模式 java23种设计模式-- ...
- Composite组合模式(结构型模式)
1.概述 在面向对象系统中,经常会遇到一些具有"容器性质"的对象,它们自己在充当容器的同时,也充当其他对象的容器. 2.案例 需要构建一个容器系统,需要满足以下几点要求: (1). ...
- 设计模式之——Composite模式
composite模式又叫做组合模式/复合模式. 它是一种能够使容器与内容具有一致性,创造出递归结构的模式. 示例程序是列出文件夹以及其内部文件与文件夹一览的功能: 可以由示例图看出,有一个电影文件夹 ...
- 设计模式学习之组合模式(Composite,结构型模式)(10)
转载地址:http://www.cnblogs.com/zhili/p/CompositePattern.html 一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系 ...
随机推荐
- 使用poi读写excel文件
使用poi库测试了一下读取excel文件,效果不错,跟大家分享一下. 第一列是数值型,第二列是字符型,代码如下: package poi; import java.io.FileInputStream ...
- systemctl介绍
声明:本文转载自:systemd (中文简体) systemd 是 Linux 下的一款系统和服务管理器,兼容 SysV 和 LSB 的启动脚本.systemd 的特性有:支持并行化任务:同一时候採用 ...
- C++的类大小
有以下C++类 #pragma pack(push) #pragma pack(1) class task /*:public OSThread*/{ //public: // void Entry( ...
- 记录关于vs2008 和vs2015 的报错问题
出现了 VS2008无法创建项目,无法打开项目的情况,提示这个注册表键值有问题 HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ MSBuild \ ToolsV ...
- SQL SERVER 2016研究一
一.安装SQL Server 2016 安装检查提示异常: 安装补丁: 根据系统判断补丁安装顺序,按顺序安装 Windows server 2012 R2 安装SQL补丁如下以及JDK: 安装完成 二 ...
- 火币网API文档——REST API 签名认证
安全认证 目前关于apikey申请和修改,请在“账户 - API管理”页面进行相关操作.其中AccessKey为API 访问密钥,SecretKey为用户对请求进行签名的密钥(仅申请时可见).Pro站 ...
- mysql 5.7配置项最详细的解释
配置样例 首先提供一个我使用的配置样例 [client] #password=88888888 socket=/data/var/mysql/mysql.sock [mysqld_safe] pid- ...
- SparkSql常用语句
-连接sparksql: cd /home/mr/spark/bin ./beeline !connect jdbc:hive2://hostname:port --切换数据库 use databas ...
- mosquitto SSL认证
[11]MQTT mosquitto 双向SSL认证配置方式 [12]MQTT mosquitto 单向SSL认证的配置方式 Mosquitto服务器的搭建以及SSL/TLS安全通信配置(比较可信) ...
- configure.in详解
configure.in文件里基本的内容就是一系列的m4宏,在运行时根据传递给它们的参数,定义的宏就会扩展为shell的脚本代码段.也可以手工书写shell代码.不过我们就不说这个了,要想完全的理解c ...