`
leoyu
  • 浏览: 12391 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

第五个设计模式:合成模式

阅读更多
 第五个设计模式:合成模式
合成模式把部分和整体关系用树结构表示,是属于对象的结构模式。合成模式要对组合的对象进行管理,所以在一定位置给予对象的相关管理方法,如:add(),remove()等.合成模式中对象的管理有两种方案。
1.安全方式:此方式只允许树枝构件有对象的管理方法。
2.透明方式:此方式只允许树枝和树叶都有对象的管理方法,但树叶对象中的管理方法无实际意义。
一.UML示意图
二.组成部分
抽象构件:抽象组合对象的公共行为接口
树叶构件:树叶对象,没有下级子对象
树枝构件:树枝对象,树枝对象可以包含一个或多个其他树枝或树叶对象
三.代码例子:我以一个超市购物为例
(一)、安全方式
1.抽象物品(抽象构件)
package com.eekq.structure.composite.security;
/*
 * 抽象构件,物品
 * */
public interface IRes {
    /**购物买单,示意性的商业方法*/
    public void pay();
}
2.单一物品(树叶构件)
package com.eekq.structure.composite.security;
public class SingleResImpl implements IRes {
    /**物品名称*/
    private String name;
    /**价钱*/
    private float money;
    public SingleResImpl(String name, float money) {
        this.name = name;
        this.money = money;
    }
    public void pay() {
        System.out.println("购买了一件物品["+getName()+"],价钱是[" + getMoney()+"]元");
    }
    public float getMoney() {
        // TODO 自动生成方法存根
        returnthis.money;
    }
    public String getName() {
        // TODO 自动生成方法存根
        return this.name;
    }  
    /**重写equals*/
    public boolean equals(Object obj){
        SingleResImpl res = (SingleResImpl)obj;    
        return res.getName().equals(getName()) && res.getMoney()==getMoney();
    }
}
3.多个物品(树枝构件)
package com.eekq.structure.composite.security;
import java.util.Iterator;
import java.util.Vector;
/*
 * 对多个物品的管理
 * */
public class MultiResImpl implements IRes {
    /**购物车*/
    private Vector car = new Vector();
    private static float totle = 0.0f;
     
public void pay() {
        if(!car.isEmpty()){
        System.out.println("名称        价格\n");
        shopping();
        System.out.println("\n总价:" + totle + "元");
        }else{
            System.out.println("您好,你没有购买任何物品,不用买单!");       
        }
    }
    public void shopping() {      
        if (car != null || !car.isEmpty()) {
            Iterator it = car.iterator();
            SingleResImpl res = null;
            Object temp = null;// 临时对象
            while (it.hasNext()) {
                temp = it.next();
                if (temp instanceof MultiResImpl) {
                    ((MultiResImpl) temp).shopping();
                } else {
                    res = (SingleResImpl) temp;
                    synchronized (this) {
                        totle += res.getMoney();
                    }
                    System.out.println(res.getName() + "            " + res.getMoney()
                            + "元");
                }
            }
        }
    }
    /**加入新的物品*/
    public void addRes(IRes res) {
        car.add(res);
    }
 
    /**放回物品*/
    public void removeRes(IRes res) {
        car.remove(res);
    }
 
}
 
4.收银台买单
package com.eekq.structure.composite.security;
public class Main {
    /**
     *@paramargs
     */
    public static void main(String[] args) {
        /**买支雪糕*/
        IRes singleRes = new SingleResImpl("雪糕", 1.5f);
        /**买单*/
        singleRes.pay();
 
        /**快过年了,我推了个购物车,多买点东西*/
        IRes allRes = new MultiResImpl();              
        /**在一楼买的食物*/
        IRes one = new MultiResImpl();
        ((MultiResImpl) allRes).addRes(one);//把一楼的东西装在购物车里
        /**因为是安全方式的组合模式,因此不够透明,只能明确的向下转型,然后再加入购物车了*/
        ((MultiResImpl) one).addRes(new SingleResImpl("旺旺", 28.5f));
        ((MultiResImpl) one).addRes(new SingleResImpl("糖果", 38.0f));
        ((MultiResImpl) one).addRes(new SingleResImpl("可乐", 8.5f));
 
        /**二楼去买的衣服和袜子*/
        IRes two = new MultiResImpl();
        ((MultiResImpl) allRes).addRes(two);// 把二楼的东西装也装在购物车里
        ((MultiResImpl) two).addRes(new SingleResImpl("衣服", 130.5f));
        ((MultiResImpl) two).addRes(new SingleResImpl("袜子", 10f));       
        /**二楼再买了个手表,我放在bao里*/
        IRes bao = new MultiResImpl();
        ((MultiResImpl) two).addRes(bao);//把购物小包装在二楼购物车里
        ((MultiResImpl) bao).addRes(new SingleResImpl("手表", 100f));
       
        /**回到一楼,又买了苹果和梨*/
        ((MultiResImpl) one).addRes(new SingleResImpl("苹果", 10.0f));
        ((MultiResImpl) one).addRes(new SingleResImpl("梨", 3.0f));
/**在买单之前我把可乐退了,因为家里还有的嘛*/
        ((MultiResImpl) one).removeRes(new SingleResImpl("可乐", 8.5f));
        /**在收银台一次性对购物车所有物品买单*/
        allRes.pay();
    }
}
 
5.运行结果
购买了一件物品[雪糕],价钱是[1.5]元
名称        价格
 
旺旺        28.5元
糖果        38.0元
苹果        10.0元
          3.0元
衣服        130.5元
袜子        10.0元
手表        100.0元
 
总价:320.0元
 
(二)、透明方式
透明方式与安全方式的不同点在于抽象构件,透明方式使用的是统一接口。
1. 抽象构件
package com.eekq.structure.composite.clarity;
 
/*
 * 抽象构件,物品
 * */
public interface IRes {
    /**购物买单,示意性的商业方法*/
    public void pay();
 
    /**加入新的物品*/
    public void addRes(IRes res);
 
    /**放回物品*/
    public void removeRes(IRes res);
}
2. 单一物品(树叶构件)
package com.eekq.structure.composite.security;
 
public class SingleResImpl implements IRes {
 
    /**物品名称*/
    private String name;
 
    /**价钱*/
    private float money;
 
    public SingleResImpl(String name, float money) {
        this.name = name;
        this.money = money;
    }
 
    public void pay() {
        System.out.println("购买了一件物品["+getName()+"],价钱是[" + getMoney()+"]元");
    }
 
    public float getMoney() {
        // TODO 自动生成方法存根
        return this.money;
    }
 
    public String getName() {
        // TODO 自动生成方法存根
        return this.name;
    }
   
    /**重写equals*/
    public boolean equals(Object obj){
        SingleResImpl res = (SingleResImpl)obj;    
        return res.getName().equals(getName()) && res.getMoney()==getMoney();
    }
 
}
3.多个物品(树枝构件)
同安全模式代码一样!
4.收银台买单
 
package com.eekq.structure.composite.clarity;
public class Main {
    /**
     *@paramargs
     */
    public static void main(String[] args) {
        /**买支雪糕*/
        IRes singleRes = new SingleResImpl("雪糕", 1.5f);
        /**买单*/
        singleRes.pay();
        /**快过年了,我推了个购物车,多买点东西*/
        IRes allRes = new MultiResImpl();
 
        /**在一楼买的食物*/
        IRes one = new MultiResImpl();
        allRes.addRes(one);// 把一楼的东西装在购物车里
        /**因为是透明方式的组合模式,因此直接调用就是了*/
        one.addRes(new SingleResImpl("旺旺", 28.5f));
        one.addRes(new SingleResImpl("糖果", 38.0f));
        one.addRes(new SingleResImpl("可乐", 8.5f));
 
        /**二楼去买的衣服和袜子*/
        IRes two = new MultiResImpl();
        allRes.addRes(two);// 把二楼的东西装也装在购物车里
        two.addRes(new SingleResImpl("衣服", 130.5f));
        two.addRes(new SingleResImpl("袜子", 10f));
        /**二楼再买了个手表,我放在bao里*/
        IRes bao = new MultiResImpl();
        two.addRes(bao);// 把购物小包装在二楼购物车里
        bao.addRes(new SingleResImpl("手表", 100f));
        /**回到一楼,又买了苹果和梨*/
        one.addRes(new SingleResImpl("苹果", 10.0f));
        one.addRes(new SingleResImpl("梨", 3.0f));
        /**在买单之前我把可乐退了,因为家里还有的嘛*/
        one.removeRes(new SingleResImpl("可乐", 8.5f));
        /**在收银台一次性对购物车所有物品买单*/
        allRes.pay();
    }
}
5.运行结果
同安全模式一样的结果!
四.总结
合成模式是对象的结构模式,以上演示合成模式。在以后的项目中,如果遇到对象组合的情况,即也符合树结构的。可以考虑下此模式。此模式中讲述了安全方式和透明方式。
安全方式:抽象构件上只提供树叶和树枝公共的方法,没提供树枝独有的管理等方法(add(),remove())。这样的好处是安全,用户不会在树叶上使用add()等管理方法,缺点是不够透明,用户必须知识当前对象为树叶还是树枝(向下转型)。
透明方式:抽象构件上提供了满足树枝的所有方法(包括add(),remove()),这样做的好处是,用户可以任意执行对象的add()和remove()管理对象。缺点是如果用户在树叶上执行管理方式(add(),remove())时,在编译期不会有错,但在执行期会报错,这样不容易被发觉错误出在哪.
作者:飞行鱼 QQ:6868861 推荐J2EE群:7715552


 

分享到:
评论

相关推荐

    软件设计模式(java版)习题答案.pdf

    设计模式一般有如下几个基本要素:模式名称、问题、目的、解决方案、效果、实例代码和相关设计模式,其中的关键元素包括模式名称、问题、解决方案和效果。 设计模式的优点 正确使用设计模式具有以下优点: 1. ...

    C#设计模式.PDF

    根据提供的文档概览,我们可以对每个章节所涉及的设计模式进行详细的阐述和解释。下面将针对文档中提及的设计模式逐一展开,以便更好地理解这些模式的概念、结构、应用场景以及优缺点。 ### 1. 面向对象程序设计...

    java设计模式(刘伟)

    ### Java设计模式(刘伟) #### 一、引言 在《Java设计模式》这本书中,作者刘伟全面地介绍了24种经典的设计模式,并通过丰富的案例和代码示例进行了详细的解析。本书不仅适合初学者作为入门教材,也适合有一定...

    java 设计模式试题

    题目中的第一个选项“同一问题的不同表现形式”(A) 描述了设计模式的主要应用场景之一。设计模式帮助开发者处理常见的软件设计难题,确保代码的可读性、可维护性和可扩展性。 ### 2. 面向对象的基本原则 面向对象...

    C#23种设计模式_示例源代码及PDF

    合成模式:合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式就 合成模式 是一个处理对象的树结构的模式。 合成模式把部分与整体的关系用树结构表示出来。 合成模 式使得客户端把一个个单独的...

    和 lvgo 一起学习设计模式.pdf

    设计模式的基本原则包括开闭原则、单一职责原则、依赖倒置原则、接口隔离原则、迪米特法则、合成复用原则等。这些原则的作用是提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性。 在学习设计模式时,...

    [Java设计模式(第2版)(Design.Patterns.in.Java).John.Metsker

    第5章 合成(composite)模式 39 第6章 桥接(bridge)模式 52 第7章 职责型模式介绍 62 第8章 单例(singleton)模式 67 第9章 观察者(observer)模式 72 第10章 调停者(mediator)模式 85 第11章 代理(proxy)模式 97 第12...

    java23种设计模式总结.pdf

    5. 责任链模式:将请求的发送者和接收者解耦,通过将处理者链接在一起形成一个链,请求沿着链传递,直到被某个处理者处理。 6. 命令模式:将请求封装为一个对象,以便使用不同的请求、队列请求、或者支持可撤销的...

    《设计模式实训教程》【PPT+类图与代码+样章】

    3.1.1设计模式 3.1.2创建型模式概述 3.1.3简单工厂模式 3.1.4工厂方法模式 3.1.5抽象工厂模式 3.1.6建造者模式 3.1.7原型模式 3.1.8单例模式 3.2实训实例 3.2.1简单工厂模式实例之图形工厂 3.2.2工厂方法...

    Java中的23种设计模式

    1. **工厂模式**:它是一种创建型设计模式,通过提供一个创建对象的接口,让子类决定实例化哪个类。这样,工厂方法将类的实例化延迟到了子类,使得系统更加灵活,易于扩展。 2. **建造者模式**:建造者模式是另一种...

    Java设计模式笔记

    **设计模式(第一部分)**: 1. **简单工厂模式**: - 简单工厂模式提供一个静态方法来创建对象,根据传入的参数或条件决定创建哪种具体的产品。它简化了客户端代码,隐藏了对象的创建过程。 以上只是Java设计...

    完整版 Java高级教程 Java语言程序设计 第6章 常用设计模式(共25页).ppt

    Java高级教程中的第六章主要讲解了五个常用的设计模式:单态模式、MVC模式、简单工厂模式、门面模式和适配器模式。设计模式是软件工程中经过实践验证的解决常见问题的有效策略,旨在提高代码的可复用性和可维护性。 ...

    吉林大学软件学院卓班设计模式第二次作业

    c) 合成一个新的字符图像后,新图像不会含有关于”合成过程”的信息,即新图像不知道是通过水平连接得到的,还是垂直连接得到的,也不会知道“左子图”是什么等。 为此,重新设计了CharPic(为方便对比,类名改为Pic)...

    设计模式第一天学习内容

    在IT行业中,设计模式是软件开发中的一种标准解决方案,它基于面向对象的设计原则,用于解决常见问题并提高代码的可重用性、可维护性和可扩展性。在本课程中,我们将深入探讨OOP(面向对象编程)、OOA(面向对象分析...

    java 设计模式

    本文将深入探讨Java设计模式中的四大接口型模式——适配器模式(Adapter)、外观模式(Facade)、合成模式(Composite)以及桥接模式(Bridge),并分析它们的应用场景。 #### 二、适配器模式 适配器模式是一种结构型设计...

    Java与模式(清晰书签版) 设计模式 part3

    第5章 专题 JAVA语言的接口 第6章 专题 抽象类 第7章 里氏代换原则 第8章 依赖倒转原则 第9章 接口隔离原则 第10章 合成、聚合复用原则 第11章 迪米特法则 第12章 简单工厂模式 第13章 工厂方法模式 第14章 抽象工厂...

    PNG图片合成例程.rar

    4. 图像混合模式:合成操作涉及到多个图像的叠加,这就需要用到图像混合模式。不同的混合模式会根据源图像和目标图像的像素值计算出新的像素值,产生不同的视觉效果。 5. 透明度处理:PNG图像支持alpha通道,即透明...

    Java与模式

    ### 第5章:Java语言的接口 接口是Java中实现多态和抽象的关键概念。本章详细介绍了接口的定义、用途和常见应用场景,通过实例讲解了如何使用接口进行面向接口编程,以及接口在Java中的重要性。 ### 第6章:抽象类...

    Delphi模式编程第一分卷

    第5章 抽象工厂模式(Abstract Factory) 5.1 模式解说 5.2 结构和用法 5.2.1 模式结构 5.2.2 代码模板 5.3 范例与实践 5.3.1 用抽象工厂模式动态构造界面风格 5.3.2 WebSnap的Web Module架构与抽象工厂模式 ...

Global site tag (gtag.js) - Google Analytics