《设计模式》-- 装饰模式

来源:互联网 发布:师洋淘宝店截图 编辑:程序博客网 时间:2024/05/17 02:11

装饰模式

  • 装饰模式
    • 认识
    • 思考
    • 使用场景
    • 优缺点
    • UML图
    • 代码实现
    • 源码分析

认识

动态地给一个对象添加一系列额外的职责,比子类继承更加灵活可配。

透明式装饰模式:装饰对象和被装饰对象实现完全相同的接口,或者装饰对象完全继承被装饰对象,装饰对象没有定义额外的方法实现。

半透明装饰模式:装饰对象在实现被装饰对象的接口或者继承被装饰对象之外,还有单独额外的自定义方法。这时装饰角色实际上已经成为一个适配器角色。适配器类的接口会比被装饰的目标类接口宽。

思考

灵活的为对象添加额外的功能,实现数量、顺序的可动态配置,搭配工厂模式、策略模式,实现灵活组合实现复杂功能。

按照流程拆分功能,将功能面向对象设计,垂直、可选、有序的组合功能,最先执行的最先被包装

AOP的实现

本质:对象动态组合

使用场景

  • 在不影响其他对象的情况下,以动态、透明的方式给对象添加职责
  • 如果不适合使用子类进行扩展功能的时候,使用装饰模式,装饰模式使用对象组合方式,避免由于功能复杂需要创建太多子类的问题

优缺点

  • 优点

    1. 装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。
    2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
  • 缺点

    1. 由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。

UML图

装饰对象和被装饰对象实现同一个接口(或装饰对象继承被装饰对象),装饰接口中持有一个被装饰对象进行操作

image

抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。

具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。

装饰(Decorator)角色:持有一个构件(Component)对象的实例,实现Component接口

具体装饰(ConcreteDecorator)角色: 对持有的Component对象实例进行进一步操作

代码实现

装饰对象通过构造函数持有一个被装饰对象,装饰对象和被装饰对象实现同一个接口,或者装饰对象继承被装饰对象,在装饰对象中调用方法时先调用被装饰对象中的方法,然后在执行装饰对象的相关业务代码,相当于对被装饰对象进行一次包装。

由于被装饰对象和装饰对象实现同一个接口,所以在装饰对象的实现类中可以对被装饰对象再次进行包装。这样层级调用,先调用被装饰对象中的方法,然后一层层往上调用。

//接口public interface Component {        public void sampleOperation();}//被装饰对象public class ConcreteComponent implements Component {    @Override    public void sampleOperation() {        // 写相关的业务代码    }}//装饰对象 实现被装饰对象实现的接口public class Decorator implements Component{    // 持有一个被装饰对象    private Component component;    //通过构造传入    public Decorator(Component component){        this.component = component;    }    @Override    public void sampleOperation() {        // 委派给构件        component.sampleOperation();    }   }//装饰对象实现类public class ConcreteDecoratorA extends Decorator {    public ConcreteDecoratorA(Component component) {        super(component);    }    @Override    public void sampleOperation() {     super.sampleOperation();        // 写相关的业务代码    }}//装饰对象实现类public class ConcreteDecoratorB extends Decorator {    public ConcreteDecoratorB(Component component) {        super(component);    }    @Override    public void sampleOperation() {      super.sampleOperation();        // 写相关的业务代码    }}

源码分析

image

●  抽象构件(Component)角色:由InputStream扮演。这是一个抽象类,为各种子类型提供统一的接口。

●  **具体构件(ConcreteComponent)角色:**ByteArrayInputStream、FileInputStream、PipedInputStream、StringBufferInputStream直接继承了InputStream,扮演具体构件。它们实现了抽象构件角色所规定的接口。

●  抽象装饰(Decorator)角色:由FilterInputStream扮演。它实现了InputStream所规定的接口。

●  具体装饰(ConcreteDecorator)角色:由几个类扮演,分别是BufferedInputStream、DataInputStream以及两个不常用到的类LineNumberInputStream、PushbackInputStream。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 月季花叶孑轰发黄怎么办? 新种的月季苗弱怎么办? 月季换盆后浇透水叶子黄了怎么办 肉肉移栽后浇透水怎么办 月季花扦插的没长根发芽了怎么办 君子兰发的小苗怎么办 蔷薇光长枝条不开花怎么办 牡丹发芽又干了怎么办 擦皮炎平后皮肤变黑怎么办 误喝发霉的咖啡渣怎么办 狗吃了速溶咖啡怎么办 咖啡机放豆的地方进水怎么办 干吃咖啡粉上瘾怎么办 去良友花艺住宿怎么办 充气娃娃放了气怎么办 煮杜鹃根没有锅怎么办 淘宝店卖鲜花被买家拒收货怎么办 执业医师电子注册忘记密码怎么办 怀孕吃了油炸的怎么办 百合长得太高怎么办 百合的杆没了怎么办 百合花长得太细怎么办 沙漠玫瑰的花苞打不开怎么办 鲜切花 较小的花苞怎么办 大棚玫瑰苗水大涝的不长怎么办 鲜花买回来蔫了怎么办 喝玫瑰醋上火了怎么办 插在花泥上的花怎么办 插的花蔫了怎么办 紫睡莲的茎软了怎么办 家养的荷花烂叶怎么办 家养的荷花叶老是枯萎怎么办 新买的绣球蔫了怎么办 绣球花被太阳晒阉了怎么办 羊肉香精放多了怎么办 被飞机防腐剂弄到皮肤怎么办 狗吃了脱氧保鲜剂呕吐怎么办 小孩误吃试纸了保鲜剂怎么办 狗狗把保鲜剂吃了怎么办 小孩吃了防潮珠怎么办 狗吃了防潮剂怎么办