为什么80%的码农都做不了架构师?>>>   

一:业务场景

奖金计算,每个部门,有不同的计算方法,且每个部门有不同类型的奖金项;而且每年或每隔几个季度奖金算法都要重新实现下。

这个应用场景应该比较合适了。

我先列出几个计算公式:

每人当月的业务奖金 = 当月销售额 * 3%;

每人累计奖金 = 总的回款额*0.1%;

团队奖金 = 团队销售总额*1%;(只有经理才有哦)

二:不用设计模式,我们程序如下实现:

这里演示代码,就不用数据库了

/*** 在内存中模拟DB,准备好测试数据* @author dy* @since 2016-08-11  & JDK 1.8.0_91*/
public class TempDB {/*** 记录每人每月销售额,这里为了演示,只有人员,没有月份* 这里演示 假设每人每月销售业务金额都是相同的哈*/public static Map<String,Double> mapMonthSaleMoney = new HashMap<>();public static Map<String,String> saleManager = new HashMap<>();static {mapMonthSaleMoney.put("杨过", 10000.00);mapMonthSaleMoney.put("令狐冲", 20000.00);mapMonthSaleMoney.put("韦小宝", 30000.00);mapMonthSaleMoney.put("dy", 10000.00);saleManager.put("经理", "dy");}
}

接下来写不同奖金计算方法

/*** 计算某人当月的业务奖金** @param user* @param month* @return*/
private double monthPrize(String user, int month) {//当月业务奖金 = 业务额*3%double prize = TempDB.mapMonthSaleMoney.get(user) * 0.03;System.out.println(user + " " + month + "月份业务奖金:" + prize);return prize;
}/*** 计算某人当月累计奖金** @param user* @param month* @return*/
private double sumPrize(String user, int month) {//这里演示 假设每人每月销售业务金额都是相同的哈//累计业务奖金 = 累计业务金额*0.1%double prize = TempDB.mapMonthSaleMoney.get(user) * 0.001;System.out.println(user + " " +month+"月份累计奖金:"+prize);return prize;
}/*** 是否是业务经理** @param user* @return*/
private boolean isManager(String user) {return TempDB.saleManager.get("经理").equals(user);
}/*** 计算当月团队奖金** @param user* @param month* @return*/
private double groupPrize(String user, int month) {if (!isManager(user)){return 0;}//团队奖金 = 团队总业务额 * 1%double prize = 0.00;for (double amount : TempDB.mapMonthSaleMoney.values()) {prize += amount;}prize = prize * 0.01;System.out.println(user + " " +month+"月份团队奖金:"+prize);return prize;
}

ok,我们开始计算奖金吧

/*** 计算奖金* @param month* @return*/
public void calcPrize(String user,int month) {double monthPrize = this.monthPrize(user, month);double sumPrize = this.sumPrize(user, month);double groupPrize =groupPrize(user, month);System.out.println(user + " " +month+"月份应得奖金:"+(monthPrize+sumPrize+groupPrize)+"==>>");}

客户端测试

public class Client {public static void main(String[] args) {Prize prize = new Prize();for (String user:TempDB.mapMonthSaleMoney.keySet()){prize.calcPrize(user,3);}}
}

测试结果:

以上代码有何问题??

如果我们计算奖金算法变了呢??如果我们要增加新的奖金项? 如果我们要移除累计奖金项呢??等等

我们是不是需要频繁改动代码呢?作为一个老鸟程序员,我们要求程序要更加灵活、支持可扩展!

如果做到呢?

我们把问题抽象下,假如有个奖金对象,可以支持灵活的增加或减少不同的奖金项,就意味着奖金对象的功能可以动态组合,这样是不是会更好些呢?

三:使用装饰模式,

动态地为一个对象增加或减少一些职责。就增加职责来说,比子类更加灵活。

如下是装饰模式结构说明:

ok,让我们利用装饰模式,重新实现计算奖金吧!

/*** 计算金额的组件接口* @author dy* @since 2016-08-11  & JDK 1.8.0_91*/
public abstract class Component {/*** 计算奖金* @param month*/public abstract double calcPrize(String user,int month);
}
/*** 基本的实现类,默认实现,也是被装饰的对象* @author dy* @since 2016-08-11  & JDK 1.8.0_91*/
public class ConcreteComponent extends Component {@Overridepublic double calcPrize(String user,int month) {System.out.println("默认没有奖金!");return 0;}
}
/*** 装饰器* 需要和被装饰的对象实现同样的接口* @author dy* @since 2016-08-11  & JDK 1.8.0_91*/
public abstract class Decorator extends Component {/*** 持有被装饰的对象*/protected  Component component;public Decorator(Component component) {this.component = component;}@Overridepublic double calcPrize(String user,int month) {double prize =  component.calcPrize(user,month);//转调组件对象的方法return prize;}
}
/*** 装饰器对象 ,计算当月业务奖金** @author dy* @since 2016-08-11  & JDK 1.8.0_91*/
public class MonthPrizeDecorator extends Decorator {public MonthPrizeDecorator(Component component) {super(component);}@Overridepublic double calcPrize(String user, int month) {double money = super.calcPrize(user, month);double monthPrize = TempDB.mapMonthSaleMoney.get(user) * 0.03;System.out.println(user + " " + month + "月份业务奖金:" + (monthPrize) + "==>>");return monthPrize + money;}
}
/*** 装饰器对象 ,计算累计奖金** @author dy* @since 2016-08-11  & JDK 1.8.0_91*/
public class SumPrizeDecorator extends Decorator {public SumPrizeDecorator(Component component) {super(component);}@Overridepublic double calcPrize(String user, int month) {double money = super.calcPrize(user, month);double sumPrize = TempDB.mapMonthSaleMoney.get(user) * 0.001;System.out.println(user + " " + month + "月份累计奖金:" + (sumPrize) + "==>>");return sumPrize + money;}
}
/*** 装饰器对象 ,计算累计奖金* @author dy* @since 2016-08-11  & JDK 1.8.0_91*/
public class GroupPrizeDecorator extends Decorator {public GroupPrizeDecorator(Component component) {super(component);}@Overridepublic double calcPrize(String user,int month) {double money = super.calcPrize(user,month);if (!isManager(user)){return money;}double totalPrize = 0.00;//团队奖金 = 团队总业务额 * 1%double prize = 0.00;for (double amount : TempDB.mapMonthSaleMoney.values()) {prize += amount;}prize = prize*0.01;System.out.println(user + " " +month+"月份团队奖金:"+(prize)+"==>>");return  money + prize;}private boolean isManager(String user) {return TempDB.saleManager.get("经理").equals(user);}
}

以上将不同计算奖金方式拆解成不同组件,需要哪些奖金计算,自动装置就可以了,让我们来试试吧!

public class Client {public static void main(String[] args) {for (String user : TempDB.mapMonthSaleMoney.keySet()) {//创建基本奖金对象Component component = new ConcreteComponent();/*** 对基本奖金进行装饰,这里要组合各个装饰*/Decorator decorator1 = new MonthPrizeDecorator(component);Decorator decorator2 = new SumPrizeDecorator(decorator1);Decorator decorator3 = new GroupPrizeDecorator(decorator1);//这里只需要用最后组合好的对象调用业务方法即可double prize = decorator3.calcPrize(user, 3);System.out.println(user + " " +3+"月份应得奖金:"+prize+"==>>");}}
}

运行结果,和我们原始代码结果一模一样,但本质上却更加灵活了

以上代码调用示例

转载于:https://my.oschina.net/dyyweb/blog/731318

Decorator 装饰器模式 -动态组合相关推荐

  1. Java —— Decorator 装饰器模式

    文章目录 Java -- Decorator 装饰器模式 简介 用处 简单例子 结构 代码 涉及角色 相关的设计模式 应用实例 优点 缺点 使用场景 注意事项 代码 Java -- Decorator ...

  2. 6中结构型设计模式的对比理解(Composite组合模式,Proxy代理模式,Flyweight享元模式,Facade门面模式,Bridge桥接模式,Decorator装饰器模式)

    结构型模式 结构型模式用来组装 类和对象,以获得更大的结构. 结构型类模式,通过继承机制来组合接口或类.简单的例子就是多重继承,最后一个类拥有所有父类的性质.这个模式有助于独立开发一个协同类.另一个例 ...

  3. 装饰器模式与java.io包

    为什么80%的码农都做不了架构师?>>>    Decorator设计模式是典型的结构型模式(在GOF的那本模式的Bible中将模式分为:1.创建型模式:2.结构型模式:3.行为模式 ...

  4. C++设计模式----装饰器模式

    文章目录 装饰器模式使用场景 引入装饰器模式 另一个装饰器模式的例子---计算水果饮料的价格 装饰器模式的定义 装饰器模式使用场景 我们的游戏中一般都会有UI(用户接口)界面,比如背包中的格子: 或者 ...

  5. 装饰器模式和适配器模式

    装饰器模式 装饰器模式(Decorator )允许向一个现有的对象添加新的增强功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 一般的,我们为了扩展一个类经常使 ...

  6. 聊聊在Vue项目中使用Decorator装饰器

    戳蓝字" Web前端严选 " 关注我们哦 ! 前言 初衷: 前几天我在公司其它Vue项目中,发现了是用Decorator装饰器模式开发的,看起来整体代码还不错,于是就做了一下笔记分 ...

  7. 单一职责模式之装饰器模式

    装饰器模式 动态地给一个对象添加一些额外的职责.就增加功能来说,装饰器模式比生成子类更为灵活. 装饰器的优点 装饰类和被装饰类可以独立发展,而不会相互耦合. 装饰器模式是继承关系的一个替代方案. 装饰 ...

  8. python中的装饰器、装饰器模式_python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

  9. 装饰器模式(Decorator Pattern)

    23种设计模式完整教程 介绍 装饰者模式(Decorator Pattern)是指在不改变原有对象的基础之上,将功能附加到对 象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式 ...

最新文章

  1. #1413 : Rikka with String 后缀自动机 + 二级差分
  2. TCP协议的3次握手和4次挥手
  3. 多功能节点连线绘图控件Nevron Diagram for .NET使用方法及下载地址
  4. 很遗憾,总对工作挑挑拣拣的家伙,一般结局都不会太好
  5. 属性面板 脚本_3.1 创建和使用脚本
  6. 利用fiddler给android模拟器抓包
  7. java实现文件压缩与解压
  8. python和java哪个好-Python和Java哪个薪资更高、远景更好?
  9. 计算机组成原理第五版第四章课后答案,计算机组成原理第4章习题参考答案
  10. 【数据分析软件】【Weka】第一课:超easy安装教程
  11. 使用电脑小技巧70个
  12. 五脏六腑在脸上的反射区图片_人体五大反射区的有图详解。
  13. 移动NB的APN知识汇总(及时补充)
  14. C# 模拟PCM数据并创建WAV文件
  15. MySQL学习宝典之最全的常用语法语句
  16. python class调用_python class中的方法调用
  17. bzoj1022 约翰的游戏 反SG-博弈
  18. 2017届南京富士通南大软件校招软件工程师面经
  19. 老铁们来来来,实战STM32
  20. dhcp服务器响应慢,开机显示DHCP,速度很慢,为什么

热门文章

  1. 越阳刚的男人越容易生女孩
  2. 手机群发短信脚本python
  3. 【UML】状态图Statechart diagram(转)
  4. 解决403跨域问题之——————JSONP
  5. 原生JS实现$.ajax
  6. str_repeat() 函数
  7. java输出数组中出现的次数最多的那个及次数
  8. 日本社交巨头Line推出BCH交易服务,助力比特币现金蓬勃发展
  9. python类方法以及类调用实例方法的理解
  10. es6之扩展运算符...