java设计模式-装饰模式
来源:互联网 发布:淘宝交易快照怎么看 编辑:程序博客网 时间:2024/06/07 02:45
定义:装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
1,不改变原类文件。
2,不使用继承。
3,动态扩展。
装饰者模式中的4个角色
(1)被装饰者抽象Component:是一个接口或者抽象类,定义最核心的对象,这个类是装饰者的基类,例如Tea接口(2)被装饰者具体实现ConcreteComponent:这是Component接口或抽象类的实现,例如本例中的SuperTea
(3)装饰者Decorator:一般是抽象类,实现Component,它里面必然有一个指向Component的引用,例如本例中AbstractTea
(4)装饰者实现ConcreteDecorator1和ConcreteDecorator2:用来装饰最基本的类,如本例中的RedTea
example
被装饰抽象:
/** * Description:茶的基类(组件) * User: lc * Date: 2017/9/29 0029 * Time: 下午 1:28 */public interface Tea { /** * 成分 */ String hasMaterial(); /** * 价格 * * @return */ BigDecimal cost();}
被装饰者具体实现:
/** * Description:茶的鼻祖实现(主实现) * User: lc * Date: 2017/9/30 0030 * Time: 下午 1:07 */public class SuperTea implements Tea { @Override public String hasMaterial() { return "白开水"; } @Override public BigDecimal cost() { return BigDecimal.ONE; }}
装饰者:
/** * Description:抽象组件 * User: lc * Date: 2017/9/30 0030 * Time: 下午 1:10 */public abstract class AbstractTea implements Tea { private Tea tea; public AbstractTea(Tea tea) { this.tea = tea; } public String hasMaterial() { return this.tea.hasMaterial(); } ; public BigDecimal cost() { return this.tea.cost(); }}
装饰者实现:
/** * Description:红茶 * User: lc * Date: 2017/9/30 0030 * Time: 下午 1:14 */public class ReadTea extends AbstractTea { public ReadTea(Tea tea) { super(tea); } /** * 返回红茶组成成分 * * @return */ @Override public String hasMaterial() { return "red茶叶、" + super.hasMaterial(); } /** * 返回红茶的价格 * * @return */ @Override public BigDecimal cost() { return new BigDecimal(3.0).add(super.cost()); }
}
/** * Description:绿茶 * User: lc * Date: 2017/9/30 0030 * Time: 下午 1:28 */public class GreenTea extends AbstractTea { public GreenTea(Tea tea) { super(tea); } /** * 返回绿茶组成成分 * * @return */ @Override public String hasMaterial() { return "green茶叶、" + super.hasMaterial(); } /** * 返回绿茶的价格 * * @return */ @Override public BigDecimal cost() { return new BigDecimal(4.0).add(super.cost()); }}
测试:
/** * Description: * User: lc * Date: 2017/9/30 0030 * Time: 下午 1:30 */public class Test { public static void main(String[] args) { System.out.println("客官:老板来一杯茶。。。。。。"); Tea superTea=new SuperTea(); System.out.println("老板:好嘞,客官。茶成分:"+superTea.hasMaterial()+"--价格:"+superTea.cost()+"元"); System.out.println("客官:老板茶没味道。来杯红茶"); AbstractTea abstractTea=null; abstractTea=new ReadTea(superTea); System.out.println("老板:好嘞,客官。红茶成分:"+abstractTea.hasMaterial()+"--价格:"+abstractTea.cost()+"元"); System.out.println("客官:老板有么有别的茶?"); System.out.println("老板:还有绿茶?"); abstractTea=new GreenTea(superTea); System.out.println("老板:好嘞,客官。绿茶成分:"+abstractTea.hasMaterial()+"--价格:"+abstractTea.cost()+"元"); System.out.println("客官:老板有没有绿红茶?"); System.out.println("老板:你确定要?"); abstractTea=new ReadTea(abstractTea); System.out.println("老板:好嘞,客官。绿红茶成分:"+abstractTea.hasMaterial()+"--价格:"+abstractTea.cost()+"元"); }}
结果:
客官:老板来一杯茶。。。。。。
老板:好嘞,客官。茶成分:白开水--价格:1元
客官:老板茶没味道。来杯红茶
老板:好嘞,客官。红茶成分:red茶叶、白开水--价格:4元
客官:老板有么有别的茶?
老板:还有绿茶?
老板:好嘞,客官。绿茶成分:green茶叶、白开水--价格:5元
客官:老板有没有绿红茶?
老板:你确定要?
老板:好嘞,客官。绿红茶成分:red茶叶、green茶叶、白开水--价格:8元
总结:
聪明的你,可能已经发现 就2个装饰者实现类,但是老板可以制定出3种茶。就我自己的理解 装饰者模式:就是修饰某个组件。比如本文章的例子Tea/superTea 是主题,而abstractTea以及具体的实现都是,封装了一些的装饰物品。比如随着老板生意越做越好,可能会添加很多种茶,甚至在原有的茶基础上添加一些配料。比如说红茶 (以后可能会出大杯、中杯、小杯等)。
结论:
1.装饰者类要实现真实类同样的接口(abstractTea实现Tea)
2.装饰者类内有一个真实对象的引用(可以通过装饰者类的构造器传入)(abstractTea引用了Tea)
3.装饰类对象在主类中接受请求,将请求发送给真实的对象(相当于已经将引用传递到了装饰类的真实对象)
4.装饰者可以在传入真实对象后,增加一些附加功能(因为装饰对象和真实对象都有同样的方法,装饰对象可以添加一定操作在调用真实对象的方法,或者先调用真实对象的方法,再
添加自己的方法)
5.不用继承,
优点:
复用现有的代码(红绿茶就复用了绿茶以及红茶的代码),增强原有的组件的功能
缺点:
1.衍生出一些列的小对象,导致错中复杂
现成例子:JDK中的装饰者模式
java.io中很多使用了装饰者模式
举个例子:FilterInputStream继承(实现)了InputStream,同时,BufferedInputStream继承了FilterInputStream,
1,被装饰者抽象组件:即最顶层的基类InputStream
2.被装饰者具体实现ConcreteComponent:FileInputStream和FileOutputStream就是它的实现
3.装饰者Decorator:FilterInputStream中有一个InputStream的实例和构造方法传入InputStream对象
protected volatile InputStream in;
protected FilterInputStream(InputStream in) {
this.in = in;
}
4.装饰者实现:在 BufferedInputStream 中有构造方法传入InputStream对象,实现了装饰
public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
- Java装饰设计模式
- Java 装饰设计模式
- Java 装饰设计模式
- java 装饰设计模式
- Java 装饰设计模式
- java 装饰设计模式
- Java装饰设计模式
- Java 装饰设计模式
- Java装饰设计模式
- Java 设计模式 --装饰模式
- Java 设计模式-----装饰模式
- java设计模式-装饰模式
- java设计模式---装饰模式
- java设计模式-装饰模式
- 【Java设计模式】装饰模式
- java设计模式-装饰模式
- java设计模式--装饰模式
- java设计模式---装饰模式
- 隐藏入口文件
- mac 设置adb 和 command not found解决方法
- shell 异常退出循环
- InstallShield 2015 Limited Edition 打包程序详解
- 初识mvp
- java设计模式-装饰模式
- 在Java中对Redis的缓存操作
- WPF学习——转换器
- web项目:漏洞修复(1)
- gradle android的task任务配置
- 【FFMPEG】谈谈RTP传输中的负载类型和时间戳
- 第二章 身份验证——《跟我学Shiro》
- 在线工具地址搜集(三)
- 百度SEO一本通