设计模式入门之装饰器模式Decorator
//装饰模式定义:动态地给一个对象加入一些额外的职责。
//就添加功能来说。装饰模式比生成子类更为灵活
//这也提现了面向对象设计中的一条基本原则,即:尽量使用对象组合,而不是对象继承
//Component:组件对象的接口。能够给这些对象动态加入职责
//ConcreateComponet:详细的组件对象。实现组件对象接口。通常就是被装饰器装饰的对象。也就是能够给这个对象加入职责
//Decorator:全部装饰器的抽象父类,须要定义一个与组件接口一致的接口,并持有一个Component对象,即被装饰的对象
//在Java中比較常见的一种装饰器模式体现例如以下:
//new DataInputStream(new BufferedInputStream(new FileInputStream("IOtest.txt")));
//FileInputStream完毕他自己的功能。然后由装饰器完毕须要添加的功能
//实例:设计一个奖金系统,奖金有月奖金,累计奖金和团队奖金,依据不同的人发不同的奖金
//不使用装饰模式的实现中,各个奖金模块的耦合非常严重,当有新的奖励方法时修改非常多,扩展不方便
//以下是使用了装饰模式的实现方式:
//数据库模拟类。存储人员销售额,模拟。仅仅给了一个月的销售额
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 PrizeCalculor {
public abstract double calcPrize(String user, Date begin, Date end);
}
//须要被装饰的对象类,比方每一个人每一个月都会有500块的基本奖金
public class NormalPrizeCalc extends PrizeCalculor {
public double calcPrize(String user, Date begin, Date end) {
return 500;
}
}
//以下是装饰器的父类
public abstract class Decorator extends PrizeCalculor{
protected PrizeCalculor c;//被装饰的对象
public Decorator(PrizeCalculor c) {
this.c = c;
}
public double calcPrize(String user, Date begin, Date end) {
//前后可添加功能
return this.c.calcPrize(user, begin, end);//默认直接转调被装饰对象的方法
}
}
//月奖金装饰器类
public class MonthPrizeDecorator extends Decorator{
public MonthPrizeDecorator(PrizeCalculor c) {
super(c);
}
public double calcPrize(String user, Date begin, Date end) {
double money = super.calcPrize(user, begin, end);//先获得被装饰对象的奖金
double prize = TempDB.mapMonthSaleMoney.get(user)*0.03;//计算月奖金
System.out.println(user+"当月业务奖金"+prize);
return money+prize;//返回被装饰对象的总奖金
}
}
//累计奖金装饰器类。作用同上
public class SumPrizeDecorator extends Decorator{
public SumPrizeDecorator(PrizeCalculor c) {
super(c);
}
public double calcPrize(String user, Date begin, Date end) {
double money = super.calcPrize(user, begin, end);
double prize = 100000*0.001;//如果全部人的累计销售额都是100000
System.out.println(user+"累计奖金"+prize);
return money+prize;
}
}
//团队奖金装饰器类,仅仅有项目经理才有
public class GroupPrizeDecorator extends Decorator{
public GroupPrizeDecorator(PrizeCalculor c) {
super(c);
}
public double calcPrize(String user, Date begin, Date end) {
double money = super.calcPrize(user, begin, end);
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;
}
}
//client測试类
public class Client {
public static void main(String[] args) {
PrizeCalculor calc = new NormalPrizeCalc();
Decorator d1 = new MonthPrizeDecorator(calc);
Decorator d2 = new SumPrizeDecorator(d1);
//把被装饰对象进行组合,calc对象经d1装饰。然后d1对象经d2装饰
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);
//项目经理。d2对象再经d3对象装饰
double ww = d3.calcPrize("王五", null, null);
System.out.println(ww);
}
}
//装饰模式的本质:动态组合
//装饰器模式长处:比继承更加灵活,更容复用功能,简化高层定义
//装饰器模式缺点:会产生非常多细粒度对象
//注意:各个装饰器之间最好是全然独立的功能,不要有依赖,这样在进行装饰组合的时候。才没有先后顺序的限制。也就是先装饰谁和后装饰谁都是一样的。否则会大大减少装饰漆组合的灵活性
设计模式入门之装饰器模式Decorator的更多相关文章
- 设计模式学习心得<装饰器模式 Decorator>
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...
- 设计模式(八)装饰器模式Decorator(结构型)
设计模式(八)装饰器模式Decorator(结构型) 1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法 ...
- 【PHP设计模式 09_ZhuangShiQi.php】装饰器模式 (decorator)
<?php /** * [装饰器模式 (decorator)] * 有时候发布一篇文章需要经过很多人手,层层处理 */ header("Content-type: text/html; ...
- 装饰器模式-Decorator(Java实现)
装饰器模式-Decorator(Java实现) 装饰器模式允许向一个现有的对象添加新的功能, 同时又不改变其结构. 其中 "现有对象"在本文中是StringDisplay类. 添加 ...
- 装饰器模式 Decorator 结构型 设计模式 (十)
引子 现实世界的装饰器模式 大家应该都吃过手抓饼,本文装饰器模式以手抓饼为模型展开简介 "老板,来一个手抓饼, 加个培根, 加个鸡蛋,多少钱?" 这句话会不 ...
- 23种设计模式之装饰器模式(Decorator Pattern)
装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...
- python 设计模式之装饰器模式 Decorator Pattern
#写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...
- 说说设计模式~装饰器模式(Decorator)~多功能消息组件的实现
返回目录 为何要设计多功能消息组件 之前写过一篇装饰器模式的文章,感觉不够深入,这次的例子是实现项目中遇到的,所以把它拿出来,再写写,之前也写过消息组件的文章,主要采用了策略模式实现的,即每个项目可以 ...
- c#设计模式之装饰器模式(Decorator Pattern)
引子 在面向对象语言中,我们常常会听到这样一句话:组合优于继承.那么该如何去理解这句话呢? 下面我将以游戏装备为模型用简单的代码去展示它 先创建一个装备的抽象类,然后创建刀枪2个具体的业务子类 pub ...
随机推荐
- python学习笔记之五:抽象
本文会介绍如何将语句组织成函数,还会详细介绍参数和作用域的概念,以及递归的概念及其在程序中的用途. 一. 创建函数 函数是可以调用,它执行某种行为并且返回一个值.用def语句即可定义一个函数:(并非所 ...
- 详细分析Java中断机制(转)
1. 引言 当我们点击某个杀毒软件的取消按钮来停止查杀病毒时,当我们在控制台敲入quit命令以结束某个后台服务时……都需要通过一个线程去取消另一个线程正在执行的任务.Java没有提供一种安全直接的方法 ...
- swift学习笔记(六)析关闭过程和使用分配给属性的默认值
一.通过关闭和功能的默认实现财产值 当存储属性默认值需要定制,能为客户提供通过关闭或全局函数的自定义默认值. 注意:全局函数的结构,和枚举使用keywordstatic大喊 用classkeyw ...
- Android DrawerLayout 抽屉
Android DrawerLayout 抽屉 DrawerLayout 在supportV4 Lib在.类似的开源slidemenu如,DrawerLayout父类ViewGroup,自定义组件基本 ...
- 将jar要么aar公布到到网mvn 在(使用github作为仓库), 通过gradle dependency 信息集成
使用Android Studio用户开发,都希望通过maven该方式整合远程仓库jar.aar文件.但如何将这些文件发布它? 发人员都会将jar文件公布到sonatype上,以提供给其它开发人员集成, ...
- 重新想象 Windows 8 Store Apps (5) - 控件之集合控件: ComboBox, ListBox, FlipView, ItemsControl, ItemsPresenter
原文:重新想象 Windows 8 Store Apps (5) - 控件之集合控件: ComboBox, ListBox, FlipView, ItemsControl, ItemsPresente ...
- 重新想象 Windows 8 Store Apps (4) - 控件之提示控件: ProgressRing; 范围控件: ProgressBar, Slider
原文:重新想象 Windows 8 Store Apps (4) - 控件之提示控件: ProgressRing; 范围控件: ProgressBar, Slider [源码下载] 重新想象 Wind ...
- 【转】Android Web Server
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://vaero.blog.51cto.com/4350852/1188602 Andr ...
- 移动web:Tips消息弹出框
在web开发中经常会用到像alert这样的弹出消息,每个浏览器自带的消息弹出框都不相同.为了统一外观,实现自定义的功能,动手写一个弹出框插件. 对弹出框的实现要求如下: 1. 仿照IOS系统弹出外观 ...
- c++11多线程简介
C++11开始支持多线程编程,之前多线程编程都需要系统的支持,在不同的系统下创建线程需要不同的API如pthread_create(),Createthread(),beginthread()等,使用 ...