`

设计模式(21)- 装饰者模式

阅读更多

装饰者模式

1.定义

      动态的给一个对象添加一些额外的职责。就增加功能来说,装饰者模式比生成子类更为灵活。

2.示例代码

     以计算奖金为例,说明装饰者模式设计思路。

   

/** 在内存中模拟数据库,准备点测试数据,好计算奖金*/
public class TempDB {
    private TempDB(){ 	
    }
    /* 记录每个人的月度销售额,只用了人员,月份没有用*/
    public static Map<String,Double> mapMonthSaleMoney = new HashMap<String,Double>();
    static{
       //填充测试数据
       mapMonthSaleMoney.put("张三",10000.0);
       mapMonthSaleMoney.put("李四",20000.0);
       mapMonthSaleMoney.put("王五",30000.0);
    }
}

 

 

/*组件对象的接口,可以给这些对象动态的添加职责*/
public abstract class Component {
    /**
     * 计算某人在某段时间内的奖金,有些参数在演示中并不会使用,
     * 但是在实际业务实现上是会用的,为了表示这是个具体的业务方法,
     * 因此这些参数被保留了
     * @param user 被计算奖金的人员
     * @param begin 计算奖金的开始时间
     * @param end 计算奖金的结束时间
     * @return 某人在某段时间内的奖金
     */
    public abstract double calcPrize(String user,Date begin,Date end);
}

/* 基本的实现计算奖金的类,也是被装饰器装饰的对象*/
public class ConcreteComponent extends Component{
    public double calcPrize(String user, Date begin, Date end) {
       //只是一个默认的实现,默认没有奖金
       return 0;
    }
}

/* 装饰器的接口,需要跟被装饰的对象实现同样的接口*/
public abstract class Decorator extends Component{
    /* 持有被装饰的组件对象*/
    protected Component c;
    /*通过构造方法传入被装饰的对象*/
    public Decorator(Component c){
       this.c = c;
    }
    public double calcPrize(String user, Date begin, Date end) {
       //转调组件对象的方法
       return c.calcPrize(user, begin, end);
    }
}

/*装饰器对象,计算当月业务奖金*/
public class MonthPrizeDecorator extends Decorator{
    public MonthPrizeDecorator(Component c){
       super(c);
    }  
    public double calcPrize(String user, Date begin, Date end) {
       //1:先获取前面运算出来的奖金
       double money = super.calcPrize(user, begin, end);
       //2:然后计算当月业务奖金,按人员和时间去获取当月业务额,然后再乘以3%
       double prize = TempDB.mapMonthSaleMoney.get(user) * 0.03;
       System.out.println(user+"当月业务奖金"+prize);
       return money + prize;
    }
}

/*装饰器对象,计算累计奖金*/
public class SumPrizeDecorator extends Decorator{
    public SumPrizeDecorator(Component c){
       super(c);
    }  
    public double calcPrize(String user, Date begin, Date end) {
       //1:先获取前面运算出来的奖金
       double money = super.calcPrize(user, begin, end);
       //2:然后计算累计奖金,其实应按人员去获取累计的业务额,然后再乘以0.1%
       //简单演示一下,假定大家的累计业务额都是1000000元
       double prize = 1000000 * 0.001;
       System.out.println(user+"累计奖金"+prize);
       return money + prize;
    }
}

/* 装饰器对象,计算当月团队业务奖金*/
public class GroupPrizeDecorator extends Decorator{
    public GroupPrizeDecorator(Component c){
       super(c);
    }
    public double calcPrize(String user, Date begin, Date end) {
       //1:先获取前面运算出来的奖金
       double money = super.calcPrize(user, begin, end);
       //2:然后计算当月团队业务奖金,先计算出团队总的业务额,然后再乘以1%
       //假设都是一个团队的
       double group = 0.0;
       for(double d : TempDB.mapMonthSaleMoney.values()){
           group += d;
       }
       double prize = group * 0.01;
       System.out.println(user+"当月团队业务奖金"+prize);
       return money + prize;
    }
}

  

/* 使用装饰模式的客户端*/
public class Client {
    public static void main(String[] args) {
       //先创建计算基本奖金的类,这也是被装饰的对象
       Component c1 = new ConcreteComponent();      
       //然后对计算的基本奖金进行装饰,这里要组合各个装饰
       //说明,各个装饰者之间最好是不要有先后顺序的限制,
       //也就是先装饰谁和后装饰谁都应该是一样的    
       //先组合普通业务人员的奖金计算
       Decorator d1 = new MonthPrizeDecorator(c1);
       Decorator d2 = new SumPrizeDecorator(d1);
       //注意:这里只需使用最后组合好的对象调用业务方法即可,会依次调用回去
       //日期对象都没有用上,所以传null就可以了
       double zs = d2.calcPrize("张三",null,null);      
       System.out.println("==========张三应得奖金:"+zs);
       double ls = d2.calcPrize("李四",null,null);
       System.out.println("==========李四应得奖金:"+ls);      
       //如果是业务经理,还需要一个计算团队的奖金计算
       Decorator d3 = new GroupPrizeDecorator(d2);
       double ww = d3.calcPrize("王五",null,null);
       System.out.println("==========王经理应得奖金:"+ww);
    }
}

 

3.实际应用

       装饰器模式实现了对被装饰对象的某些装饰功能,比对象继承有更好的灵活性,可以在装饰器中调用被装饰对象的功能,获取相应的值,这其实是一种递归调用。各个装饰器之间最好是完全独立的功能,不要有依赖,这样在进行装饰组合的时候,才没有先后顺序的限制,java中最典型的应用就是I/O流。

装饰者模式的本质:动态组合
分享到:
评论

相关推荐

    设计模式--装饰者模式java例子

    装饰者模式是软件设计模式中的一种结构型模式,它的主要目的是动态地给对象添加新的功能,而无需修改原有代码。在Java中,装饰者模式通常通过继承和组合来实现,它提供了一种比继承更灵活的方式来扩展对象的功能。...

    设计模式精解-GoF-23种设计模式解析--附C++源代码

    - 装饰模式(Decorator):动态地给一个对象添加一些额外的职责。 - 享元模式(Flyweight):使用共享对象,有效地支持大量细粒度的对象。 3. **行为型模式**:这类模式关注对象之间的责任分配。 - 责任链模式...

    设计模式---装饰者模式

    装饰者模式是一种结构型设计模式,它允许在运行时向对象添加新的行为或职责,而无需修改对象的源代码或创建子类。这种模式的核心思想是通过将对象封装在一个装饰器对象内,来扩展对象的功能,同时保持原有接口的不变...

    设计模式 - 装饰者模式.rar

    装饰者模式是一种结构型设计模式,它允许在运行时向对象添加新的行为或职责,而无需修改对象本身。这种模式的核心思想是通过将对象包装在一个装饰类中来扩展功能,而不是通过继承。以下是对装饰者模式的详细阐述: ...

    设计模式-装饰者模式

    在“设计模式—装饰者模式”中,我们将深入探讨这个模式的概念、实现方式以及实际应用。 装饰者模式的核心概念在于“装饰”(Decorator)和“组件”(Component)。组件是被装饰的基本对象,它可以是接口或者抽象类...

    C++设计模式--基于Qt4开源跨平台开发框架

    《C++设计模式--基于Qt4开源跨平台开发框架》一书主要探讨了如何在C++编程中利用设计模式,并结合Qt4框架进行高效的跨平台应用开发。设计模式是软件工程中的重要概念,它们是经过时间和实践验证的解决特定问题的模板...

    23种设计模式--装饰模式

    装饰模式是一种结构型设计模式,它是面向对象设计中用来动态添加或修改对象功能的一种方法。在软件工程中,装饰模式允许我们向一个现有的对象添加新的行为或职责,同时又不改变其原有的结构,从而实现对类的功能扩展...

    Java设计模式-装饰者模式

    本章可以称为“给爱用继承的人一个全新的设计眼界”。我们即将再度探讨典型滥用问题。你将在本章学到如何使用对象组合的方式,做到在运行时装饰类。为什么呢?一旦你熟悉了装饰者的技巧...——《Head First 设计模式》

    设计模式课件大全

    设计模式07-组合模式、装饰模式 设计模式09-外观模式、享元模式 设计模式10-代理模式、结构型模式大复习 设计模式11-行为模式-责任链、命令模式 设计模式12-解释器模式 设计模式13-迭代器模式 设计模式14-中介者模式...

    JAVA设计模式例程-装饰模式

    JAVA设计模式例程-装饰模式-的例程,看完以后基本上能对JAVA上实现装饰模式能有所了解,个人认为常各种模式并不是为了死套各种模式,而应该是灵活的在项目中结合实际情况而用各种模式的组合应用,呵呵!但前提是得对...

    游戏设计3-装饰者模式-装备

    装饰者模式是面向对象设计中的一种行为设计模式,它允许在运行时动态地给对象添加新的职责或行为,而无需改变对象本身。在游戏设计中,装饰者模式常常被用来扩展角色、装备等对象的功能,使得游戏内容更加丰富且易于...

    设计模式-装饰者

    装饰者设计模式是一种结构型设计模式,它允许在运行时向对象添加新的行为或属性,而无需修改对象的源代码。这种模式的核心在于装饰者和组件接口是相同的,因此装饰者可以完全替代原对象,同时还能增加额外的功能,...

    c++设计模式-结构型模式-装饰器模式

    c++设计模式-结构型模式-装饰器模式;QT工程;c++简单源码; 装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

    JAVA-设计模式-结构型模式-装饰模式

    JAVA-设计模式-结构型模式-装饰模式

    设计模式精解-GoF23种设计模式解析附C++实现源码

    设计模式是软件工程中的一种重要思想,它是在特定情境下,为解决常见问题而形成的一套最佳实践。GoF(Gang of Four)23种设计模式是软件开发中的经典,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides...

    java设计模式---诙谐易懂版

    代理模式(Proxy Pattern)、单例模式(Singleton Pattern)、工厂方法模式(...者模式(Builder Pattern)、桥梁模式(Bridge Pattern)、命令模式(Command Pattern)、装饰模式(Decorator Pattern)、迭代器模式...

    Java设计模式----通俗易懂版

    这个资源"Java设计模式----通俗易懂版"显然是一个专门针对初学者或需要深入理解设计模式的开发者编写的指南。作者以形象生动的例子解释了23种经典的Java设计模式,使得复杂的概念变得更加易于理解。 首先,我们要...

    设计模式精解-GoF 23种设计模式解析附C++实现源码.pdf

    ### 设计模式精解——GoF 23种设计模式解析及C++实现源码 #### 0. 引言 设计模式是软件工程领域的一个重要概念,它提供了一种解决常见问题的方法论。GoF(Gang of Four)所提出的23种设计模式被视为面向对象设计的...

Global site tag (gtag.js) - Google Analytics