组合模式(Composite Pattern)
组合模式定义:组合模式允许你将对象组合成树形结构来表现“整体/局部”层次结构,组合能让客户以一致的方式处理个别对象以及对象组合。
当涉及到如:菜单,子菜单之类的问题时,会自然而然的想到使用树形结构
类之间的关系确如上图所示,但是这种设计复用性和扩展性都很低:
1,所有的菜单都有各自的add、remove以及getChild实现,复用性很低
2,类型转换问题,菜单完全不知道其包含的子元素的具体类型,这是个大问题(List<Object>)
针对上述2个问题:
1,抽象出共同的父类,以实现一些基本方法的复用
2,隐藏菜单与菜单项之间的差异,在这点,我们可以借鉴装饰者模式,将菜单和菜单项都当做一个菜单,如此一来,共同的父类也出现了
组合模式基本组成:
组件 - Menu、SpecificMenu
叶子节点 - MenuItem
组件可以包含其他组件以及叶子节点
- public abstract class Menu {
- public void add(){
- throw new UnsupportedOperationException();
- }
- public void remove(){
- throw new UnsupportedOperationException();
- }
- public Menu getChild(int i){
- throw new UnsupportedOperationException();
- }
- public void print(){
- throw new UnsupportedOperationException();
- }
- }
- public class MenuItem extends Menu {
- private String name;
- public MenuItem(String name){
- this.name = name;
- }
- public void print(){
- System.out.println(name);
- }
- }
- public class SpecificMenu extends Menu {
- private String name;
- private List<Menu> children = new ArrayList<Menu>();
- public SpecificMenu(String name){
- this.name = name;
- }
- public void add(Menu menu){
- children.add(menu);
- }
- public void remove(Menu menu){
- children.remove(menu);
- }
- public Menu getChild(int i){
- return children.get(i);
- }
- public void print(){
- Iterator<Menu> it = children.iterator();
- while(it.hasNext()){
- Menu tmp = it.next();
- tmp.print();
- }
- }
- }
- public class Cilent {
- public static void main(String[] args) {
- MenuItem mocha = new MenuItem("mocha");
- MenuItem espressos = new MenuItem("espressos");
- SpecificMenu coffeeMenu = new SpecificMenu("coffeeMenu");
- coffeeMenu.add(mocha);
- coffeeMenu.add(espressos);
- MenuItem rice = new MenuItem("rice");
- SpecificMenu restaurantMenu = new SpecificMenu("restaurantMenu");
- restaurantMenu.add(coffeeMenu);
- restaurantMenu.add(rice);
- SpecificMenu allMenu = new SpecificMenu("allMenu");
- allMenu.add(restaurantMenu);
- allMenu.print();
- }
- }
测试结果:
- mocha
- espressos
- rice
通常情况下,一个类具有单一的责任才是好的设计,但是这里,Menu既要扮演菜单,又需扮演菜单项
在组合模式中,通过牺牲了单一责任的设计原则,换取了透明性(对于一个节点,调用方无法确定其是组合还是节点,即组合与节点对用户来说是透明的)
为了保持透明性,组合内所有的对象都必须实现相同的接口,否则将必须考虑哪个对象使用哪个接口,这就失去了组合模式的意义
当然实现相同的接口也意味着有些对象包含一些没有意义的方法调用(如MenuItem通过继承依然拥有add、remove以及getChild方法,但是对叶子节点MenuItem来说,操作子节点的方法似乎是没有意义的,但是换个考虑方向,将MenuItem想象成没有子节点的节点,是不是感觉不一样了?)
可以看出这是一个折中的方案(折中方案很常见,比如为提高处理速度以“空间换时间”),由此也证明设计模式并不是完美无缺的,在使用前有必要仔细审视其带来的影响
PS:
1,什么时候使用组合模式:
有一些对象,它们之间具有“整体/部分”之间的关系,并且想用一致的方式对待整体与局部
组合模式(Composite Pattern)的更多相关文章
- 浅谈设计模式--组合模式(Composite Pattern)
组合模式(Composite Pattern) 组合模式,有时候又叫部分-整体结构(part-whole hierarchy),使得用户对单个对象和对一组对象的使用具有一致性.简单来说,就是可以像使用 ...
- 二十四种设计模式:组合模式(Composite Pattern)
组合模式(Composite Pattern) 介绍将对象组合成树形结构以表示"部分-整体"的层次结构.它使得客户对单个对象和复合对象的使用具有一致性.示例有一个Message实体 ...
- 乐在其中设计模式(C#) - 组合模式(Composite Pattern)
原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:weba ...
- 【设计模式】组合模式 Composite Pattern
树形结构是软件行业很常见的一种结构,几乎随处可见, 比如: HTML 页面中的DOM,产品的分类,通常一些应用或网站的菜单,Windows Form 中的控件继承关系,Android中的View继承 ...
- 设计模式 - 组合模式(composite pattern) 迭代器(iterator) 具体解释
组合模式(composite pattern) 迭代器(iterator) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考组合模式(composit ...
- 设计模式系列之组合模式(Composite Pattern)——树形结构的处理
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 组合模式Composite Pattern(转)
什么是组合模式呢?简单来说组合模式就是将对象合成树形结构以表示“部分整体”的层次结构,组合模式使用户对单个对象和组合对象使用具有一致性. 组合模式(Composite Pattern)有时候又叫部分- ...
- python 设计模式之组合模式Composite Pattern
#引入一 文件夹对我们来说很熟悉,文件夹里面可以包含文件夹,也可以包含文件. 那么文件夹是个容器,文件夹里面的文件夹也是个容器,文件夹里面的文件是对象. 这是一个树形结构 咱们生活工作中常用的一种结构 ...
- C#设计模式——组合模式(Composite Pattern)
一.概述 在软件开发中,我们往往会遇上类似树形结构的对象体系.即某一对象既可能在树形结构中作为叶节点存在,也可能作为分支节点存在.比如在文件系统中,文件是作为叶节点存在,而文件夹就是分支节点.在设计这 ...
- 设计模式 -- 组合模式 (Composite Pattern)
定义: 对象组合成部分整体结构,单个对象和组合对象具有一致性. 看了下大概结构就是集团总公司和子公司那种层级结构. 角色介绍: Component :抽象根节点:其实相当去总公司,抽象子类共有的方法: ...
随机推荐
- apache和tomcat
Apache 和 Tomcat 都是web网络服务器,两者既有联系又有区别,在进行HTML.PHP.JSP.Perl等开发过程中,需要准确掌握其各自特点,选择最佳的服务器配置. Apache是web服 ...
- openssl的CRYPTO_set_locking_callback
openssl可以在多线程环境下使用,但前提是向openssl提供线程锁设施,通过CRYPTO_set_locking_callback设置. 在一些复杂软件环境环境中,可能存在多个上层模块同时使用o ...
- 几种流行Webservice框架性能对比
1 摘要 开发webservice应用程序中离不开框架的支持,当open-open网站列举的就有30多种,这对于开发者如何选择带来一定的疑惑.性能Webservice的关键要素,不同的框架性 ...
- Oracle.ManagedDataAccessDTC.dll 使用
ODP.NET, Managed Driver Setup This section explains the setup and configuration steps required for u ...
- JavaScript下拉框去除重复内容
下拉框去除重复内容 <script type="text/javascript" src="http://www.joleye.com/libraries/java ...
- 通过DeveloperApi获取spark程序执行进度及异常
在应用spark时,经常要获取任务的执行进度,可以参照jobProgressListener的设计来完成该功能. 以下代码仅供参考,欢迎交流. 效果显示: 代码: package org.apache ...
- 韦东山yy公开课笔记(1)--各种杂的问题
1,第四期的智能猫眼会有打电话和发短信的功能吗? 答:会有打电话功能,硬件上支持打电话就会支持发短信,只是软件上是否实现发短信现在未定.因为短信延迟太严重,不是可靠的. 2,请问关于makefil ...
- bzoj 1226 [SDOI2009]学校食堂Dining(状压DP)
Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...
- 杭电HDOJ--ACM1002(JAVA解题,运用BigInteger)(自定义MBigInteger 简单实现大数处理----完善后可以实现百亿计算器)
转载声明:原文转自http://www.cnblogs.com/xiezie/p/5501901.html JAVA解题: import java.util.*; import java. ...
- win7下wubi安装Ubuntu,重装win7后找回Ubuntu启动项
怀念一下我的win7,使用了将近5年,最近终于慢慢处于崩溃且无法修复的状态. 还是重新安装了. 原本是win7下使用wubi安装Ubuntu.重装win7后,肯定没有了Ubuntu的启动项. 具体恢复 ...