设计模式(9)--Composite(组合模式)--结构型
1.模式定义:
2.模式特点:
3.使用场景:
4.模式实现:
(1)安全式组合模式的结构

[1]抽象构件(Component)角色:
public interface Component {
/** * 输出组建自身的名称 */
public void printStruct(String preStr);
}
[2]树叶构件(Leaf)角色:
public class Composite implements Component {
/**
* 用来存储组合对象中包含的子组件对象
*/
private List<Component> childComponents = new ArrayList<Component>();
/**
* 组合对象的名字
*/
private String name;
/**
* 构造方法,传入组合对象的名字
* @param name 组合对象的名字
*/
public Composite(String name){
this.name = name;
}
/**
* 聚集管理方法,增加一个子构件对象
* @param child 子构件对象
*/
public void addChild(Component child){
childComponents.add(child);
}
/**
* 聚集管理方法,删除一个子构件对象
* @param index 子构件对象的下标
*/
public void removeChild(int index){
childComponents.remove(index);
}
/**
* 聚集管理方法,返回所有子构件对象
*/
public List<Component> getChild(){
return childComponents;
}
/**
* 输出对象的自身结构
* @param preStr 前缀,主要是按照层级拼接空格,实现向后缩进
*/
@Override
public void printStruct(String preStr) {
// 先把自己输出
System.out.println(preStr + "+" + this.name);
//如果还包含有子组件,那么就输出这些子组件对象
if(this.childComponents != null){
//添加两个空格,表示向后缩进两个空格
preStr += " ";
//输出当前对象的子对象
for(Component c : childComponents){
//递归输出每个子对象
c.printStruct(preStr);
}
}
}
}
[3]树枝构件(Composite)角色:
public class Leaf implements Component {
/**
* 叶子对象的名字
*/
private String name;
/**
* 构造方法,传入叶子对象的名称
* @param name 叶子对象的名字
*/
public Leaf(String name){
this.name = name;
}
/**
* 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字
* @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
*/
@Override
public void printStruct(String preStr) {
// TODO Auto-generated method stub
System.out.println(preStr + "-" + name);
}
}
[4]客户端类
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.addChild(c1);
root.addChild(c2);
c1.addChild(leaf1);
c1.addChild(leaf2);
c2.addChild(leaf3);
c2.addChild(leaf4);
root.printStruct("");
}
}
(2)透明式组合模式的结构

[1]抽象构件角色类
public abstract class Component {
/**
* 输出组建自身的名称
*/
public abstract void printStruct(String preStr);
/**
* 聚集管理方法,增加一个子构件对象
* @param child 子构件对象
*/
public void addChild(Component child){
/**
* 缺省实现,抛出异常,因为叶子对象没有此功能
* 或者子组件没有实现这个功能
*/
throw new UnsupportedOperationException("对象不支持此功能");
}
/**
* 聚集管理方法,删除一个子构件对象
* @param index 子构件对象的下标
*/
public void removeChild(int index){
/**
* 缺省实现,抛出异常,因为叶子对象没有此功能
* 或者子组件没有实现这个功能
*/
throw new UnsupportedOperationException("对象不支持此功能");
} /**
* 聚集管理方法,返回所有子构件对象
*/
public List<Component> getChild(){
/**
* 缺省实现,抛出异常,因为叶子对象没有此功能
* 或者子组件没有实现这个功能
*/
throw new UnsupportedOperationException("对象不支持此功能");
}
}
[2]树枝构件角色类
public class Composite extends Component {
/**
* 用来存储组合对象中包含的子组件对象
*/
private List<Component> childComponents = new ArrayList<Component>();
/**
* 组合对象的名字
*/
private String name;
/**
* 构造方法,传入组合对象的名字
* @param name 组合对象的名字
*/
public Composite(String name){
this.name = name;
}
/**
* 聚集管理方法,增加一个子构件对象
* @param child 子构件对象
*/
public void addChild(Component child){
childComponents.add(child);
}
/**
* 聚集管理方法,删除一个子构件对象
* @param index 子构件对象的下标
*/
public void removeChild(int index){
childComponents.remove(index);
}
/**
* 聚集管理方法,返回所有子构件对象
*/
public List<Component> getChild(){
return childComponents;
}
/**
* 输出对象的自身结构
* @param preStr 前缀,主要是按照层级拼接空格,实现向后缩进
*/
@Override
public void printStruct(String preStr) {
// 先把自己输出
System.out.println(preStr + "+" + this.name);
//如果还包含有子组件,那么就输出这些子组件对象
if(this.childComponents != null){
//添加两个空格,表示向后缩进两个空格
preStr += " ";
//输出当前对象的子对象
for(Component c : childComponents){
//递归输出每个子对象
c.printStruct(preStr);
}
}
}
}
[3]树叶构件角色类
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) {
// TODO Auto-generated method stub
System.out.println(preStr + "-" + name);
}
}
[4]客户端类的主要变化是不再区分Composite对象和Leaf对象。
public class Client {
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("");
}
}
(3)两种实现方法的选择
5.优缺点
(1)组合模式优点:
(2)组合模式缺点:
6.注意事项
(1)组合模式不是父子关系
(2)对叶对象操作的一致性
(3)双向映射关系
(4)用职责链模式提高组合模式性能
7.实际应用
设计模式(9)--Composite(组合模式)--结构型的更多相关文章
- Composite组合模式(结构型模式)
1.概述 在面向对象系统中,经常会遇到一些具有"容器性质"的对象,它们自己在充当容器的同时,也充当其他对象的容器. 2.案例 需要构建一个容器系统,需要满足以下几点要求: (1). ...
- 设计模式(九):Composite组合模式 -- 结构型模式
1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 我们可以使用简单的对象组合成复杂的对象,而这个复杂对 ...
- 设计模式之——Composite组合模式
上周面试,面试官问桥接模式是什么,我就举了个例子:手机分为苹果,小米....,每个手机都有视频,游戏...等功能.直观上是一个树形结构.这种情况下,可以用桥接模式,把手机作为接口,苹果,小米等继承手机 ...
- 设计模式(7)--Bridge(桥接模式)--结构型
1.模式定义: 桥接模式是对象的结构模式.又称为柄体(Handle and Body)模式或接口(Interface)模式.桥接模式的用意是“将抽象化(Abstraction)与实现化(Impleme ...
- 设计模式(10)--Facade(外观模式)--结构型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使 ...
- 设计模式(12)--Proxy(代理模式)--结构型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. ...
- 设计模式08: Composite 组合模式(结构型模式)
Composite 组合模式(结构型模式) 对象容器的问题在面向对象系统中,我们常会遇到一类具有“容器”特征的对象——即他们在充当对象的同时,又是其他对象的容器. public interface I ...
- 一天一个设计模式——Composite组合模式
一.模式说明 能够使容器与内容物具有一致性,创造出递归结构的模式就是Composite组合模式. 举个例子:计算机中的文件系统中有文件和文件夹的概念,我们知道,文件夹可以包含文件,也可以包含子文件夹, ...
- C++设计模式-Composite组合模式
Composite组合模式作用:将对象组合成树形结构以表示“部分-整体”的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. UML图如下: 在Component中声明所有用来 ...
随机推荐
- tomcat 启动 证书异常java.io.IOException: Alias name [cas] does not identify a key entry
在搭建CAS server的过程中,Tomcat开启https,配置秘钥证书,证书是通过keytool生成的 <Connector port=" protocol="org. ...
- Swift5 语言指南(二十六) 内存安全
默认情况下,Swift可以防止代码中发生不安全行为.例如,Swift确保变量在使用之前进行初始化,在取消分配后不访问内存,并检查数组索引是否存在越界错误. Swift还确保对同一内存区域的多次访问不会 ...
- C# 生成月份及天选择列表,方便做下拉框联动
月份及天选择列表,很方便做下拉框联动 /// <summary> /// 获取月份选择列表(根据当前语言环境显示月份名称) /// </summary> private IEn ...
- for,while陈述
今天我们来说一下for 和while循环 Python循环语句的控制结构图如下所示: for 是Python程序员使用最多的语句,for 循环用于迭代容器对象中的元素,这些对象可以是列表.元组.字典. ...
- python--使用pickle序列化对象
pickle序列化对象 如果希望透明地存储 Python 对象,而不丢失其身份和类型等信息,则需要某种形式的对象序列化:它是一个将任意复杂的对象转成对象的文本或二进制表示的过程. 同样,必须能够将对象 ...
- odoo 开发基础 -- 视图之xpath语法
odoo 视图函数 在整个项目文件中,结构并不是十分明显,虽然它也遵循MVC设计,类比django的MTV模式,各个模块区分的十分明显,在Odoo中,视图的概念不是特别明显,很多时候,我们会将调用模型 ...
- 十分钟内在Ubuntu系统上搭建Mono开发环境(Mono软件Ubuntu系统国内镜像源、Mono国内镜像源)
Mono软件Ubuntu系统国内镜像源.Mono国内镜像源 http://download.githall.cn/repo 替换为国内源(非官方)有利于加快mono的安装速度,一般情况下,完成mono ...
- [Java初探07]__关于面向对象的简单认识
前言 类和对象,在我们学习Java语言的过程中,它们无时无刻不存在着,在我们还远未详细弄明白它们的意义之前,在我们不知不觉的下意识里,我们都会直接或间接的用到它们,这是因为Java是一门面向对象的语言 ...
- JSONPath解析
访问我的博客 前言 在工作中,经常会遇到从一串 JSON 中提取一个或多个字段的情况,常用的做法就是将其反序列化为 JSONObject 对象,然后从对象中获取,如果是 JSONArray 就进行迭代 ...
- NHibernate 有好几种数据库查询方式
NHibernate 有好几种数据库查询方式 1.原生SQL var employeeQuery = Database.Session .CreateSQLQuery("select * f ...