装饰者模式
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例子
设计模式--装饰模式 设计模式--装饰模式 设计模式--装饰模式 设计模式--装饰模式
23种设计模式--装饰模式
设计模式 - 装饰者模式
装饰者模式:动态地将责任附加到对象上,若要扩展对象,装饰者模式提供了比继承更弹性的替代方案
设计模式—装饰者模式,介绍的非常详细,讲解透彻
本章可以称为“给爱用继承的人一个全新的设计眼界”。我们即将再度探讨典型滥用问题。你将在本章学到如何使用对象组合的方式,做到在运行时装饰类。为什么呢?一旦你熟悉了装饰者的技巧...——《Head First 设计模式》
设计模式07-组合模式、装饰模式 设计模式09-外观模式、享元模式 设计模式10-代理模式、结构型模式大复习 设计模式11-行为模式-责任链、命令模式 设计模式12-解释器模式 设计模式13-迭代器模式 设计模式14-中介者模式...
设计模式专题之(七)装饰模式---设计模式装饰模式示例代码(python--c++)
JAVA设计模式例程-装饰模式-的例程,看完以后基本上能对JAVA上实现装饰模式能有所了解,个人认为常各种模式并不是为了死套各种模式,而应该是灵活的在项目中结合实际情况而用各种模式的组合应用,呵呵!但前提是得对...
设计模式 - 装饰模式(C++实例) 若有问题,请指出。
设计模式-装饰模式(讲解及其实现代码)
c++设计模式-结构型模式-装饰器模式;QT工程;c++简单源码; 装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
JAVA-设计模式-结构型模式-装饰模式
装饰工程-装饰工程系统-装饰工程系统源码-装饰工程管理系统-装饰工程管理系统java代码-装饰工程系统设计与实现-基于springboot的装饰工程系统-基于Web的装饰工程系统设计与实现-装饰工程网站-装饰工程网站代码-装饰...
使用PHP实现的设计模式之装饰者模式,希望对您的开发有所启发。
java常用设计模式-装饰器模式