装饰器模式

概念和功能

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种还是属于结构型模式。它是作为现有的类的一个包装,这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

使用场景和方法

使用场景大抵是: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。
相较于继承子类的解决方案来说主要解决的是——由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。在不想增加很多子类的情况下扩展类的功能。
使用方法大抵是:1、让适配器类继承某个类的对象实现需要的接口,修改指定方法。2、通过在适配器类中添加某个类的对象实现需要适配的接口。
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:多层装饰比较复杂。

实例分析

简单的实例:电源适配器——现在我想在不改变电源适配器类的结构下扩展一个功能——变色。

  1. 我可以新增一个类继承这个适配器类,然后新增一个方法setColor,这样的缺点是不灵活,我想再添加一个方法setShape,这种模式下去类之间的继承关系越来越复杂,子类越来越膨胀,还会出现如果我基类的属性值更改了,我的各个子类都可能受到影响。那可能会想到我用实现接口的方式啊,可还是会出现上述问题,接口和继承本就是很相像的。
  2. 那我能实现一个功能,但是这个功能的具体实现是和原来的类“分开”(松耦合)的,这个功能实现类只是接受原来类提供的一些参数而已。

方法一:

适配器的子类:

public class PowerAdapterSubClass<T extends ElectricApp> extends PowerAdapter{
    //the Attribute(color) can be more appropriate in base struct
    private int color = 0x00000000;
    public PowerAdapterSubClass(ElectricApp app, PowerProvider provider) {
        super(app, provider);
    }

    public void setColor(int colorARGB) {
        //do something to change the color ......
        color = colorARGB;
    }
}

使用的方法很简单:

	Phone phone = new Phone();
        PowerProvider powerProvider = new PowerProvider();
        //add function :setColor(color)
        PowerAdapterSubClass powerAdapterSubClass = new PowerAdapterSubClass<Phone>(phone, powerProvider);
        powerAdapterSubClass.setColor(0x00ffffff);

这里在使用的时候直接实例化PowerAdapter的子类powerAdapterSubClass,然后调用子类中新增的setColor方法就完成新增功能的调用了。

方法二:

适配器的装饰类:


public class PowerAdapterDecorator implements Power {
    //the Attribute(color) can be more appropriate in base struct
    private int color = 0x00000000;
    private PowerAdapter powerAdapter;

    public PowerAdapterDecorator(PowerAdapter adapter) {
        this.powerAdapter = adapter;
    }

    public void setColor(int colorARGB) {
        //do something to change the color ......
        color = colorARGB;
    }

    @Override
    public int powerOut() {
        return this.powerAdapter.powerOut();
    }
}

运行的时候就是这样了:

	Phone phone = new Phone();
        PowerProvider powerProvider = new PowerProvider();
        PowerAdapter powerAdapter = new PowerAdapter<Phone>(phone, powerProvider);
        
        //add function :setColor(color)
        PowerAdapterDecorator powerAdapterDecorator = new PowerAdapterDecorator(powerAdapter);
        powerAdapterDecorator.setColor(0x00ffffff);
        
        phone.setPower(powerAdapterDecorator);
        System.out.print("phone current volume is " + phone.charging());

适配器的在不继承的情况下想添加功能,最常用关键的方法是持有想扩展方法的原始类的实例。就是上面栗子中的PowerAdapterDecorator powerAdapterDecorator = new PowerAdapterDecorator(powerAdapter);这句。拿到了实例才能很好的扩展他的功能。这样装饰类PowerAdapterDecorator和原来的PowerAdapter分工明确、独立开发和扩展不会相互耦合,这也是装饰器模式的优点了。但说是独立开发互不影响也不是那么“理想”,装饰器模式设计之初就是辅助原始类更好的实现多变的功能的,所以装饰器模式方法基本都是辅助原始类方法或者属性的。比如上面例子中的changeColor就是用来辅助原始类中color属性的,这个changeColor功能可有可没有,只是需要提供了这个方法来动态改变color,创建了装饰器类来完成这个功能。同时还会有一个缺点,我需要实现多层装饰,后面的一层就需要有前一层的实例,设计功能的时候会很复杂,多层之间的是怎么明确分工的,所以建议最多只做一两层的“装饰”。
Android中装饰器模式的经典实现就是Context、ContextWrapper和ContextThemeWrapper等,等后面看了源码再来深度理解一下他们实现的装饰器模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值