设计模式学习笔记--装饰者模式(Decorator Pattern)

概念

动态地将行为附加到对象上。提供了比继承更具有弹性的替代方案

所谓”动态”,是指在运行时根据具体的需求添加行为,相对的,”静态”则是在编译时就确定了具体的行为,两者的区别很明显,动态添加行为具有很好的可扩展性,不需要修改已有的代码,这对于维护更新是很有利的。

设计原则

  • 类应该对扩展开放,对修改关闭
    对原有代码修改的代价是很大的,很可能引入未知的 bug 和意外的副作用,所以要对修改关闭,而使用扩展来应对改变的需求,在不修改原有代码的情况下就能添加新行为。

  • 多用组合,少用继承
    如同策略模式,使用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为,而如果使用组合来扩展对象的行为,就可以在运行时动态的添加行为。

理解

在装饰者模式中,存在两个角色:组件(Component) 和 装饰器(Decorator),并且两者要实现相同的接口或抽象类(实现接口或继承抽象类都行),这样就可以使用装饰器来装饰组件了。现实生活中有很多这样的例子,比如购买手机时,一个裸机就算是一个组件,如果想要装饰下手机,加个手机套,贴个膜,送支手写笔等,这些就是装饰器。通过装饰,在原有对象的基础上得到了一个新的具有更多属性和行为的对象,比如加了手机套的手机比裸机耐摔,这便是装饰后得到的新属性;有了手写笔的手机可以有新的输入方式,这便是装饰后得到的新行为。

实例

现实生活中有很多事物可以描述装饰者模式,就拿上面提到的手机配件的例子来写一个模拟代码

在这个例子中,有一个抽象类 Phones,作为组件和装饰器的共同基类;有两个组件,AndroidPhone 和 iOSPhone,装饰器数量不确定,因此有个装饰器基类 PhoneAccessory,然后派生出一些可选的装饰器,比如 手机壳:PhoneCover,手机膜:PhoneMembrane,手写笔:PhonePen。他们之间的关系可以用如下类图描述

这里写图片描述

通过类图可以很清楚的看到装饰者模式的思路,下面是具体代码:

抽象基类

public abstract class Phones {
    String description="nothing";

    public String getDescription(){
        return description;
    }
}

Android 手机

public class AndroidPhone extends Phones {

    public AndroidPhone(){
        description="Android 手机";
    }
}

iOS 手机

public class iOSPhone extends Phones {

    public iOSPhone(){
        description="iOS 手机";
    }
}

装饰器基类

public abstract class PhoneAccessory extends Phones {

    public abstract String getDescription();

}

手机壳装饰器

public class PhoneCover extends PhoneAccessory{
    private Phones phone;

    public PhoneCover(Phones p){
        this.phone=p;
    }

    @Override
    public String getDescription() {
        return this.phone.getDescription()+" 加了个保护套";
    }
}

手机膜装饰器

public class PhoneMembrane extends PhoneAccessory {
    private Phones phones;

    public PhoneMembrane(Phones p){
        this.phones=p;
    }


    @Override
    public String getDescription() {
        return this.phones.getDescription()+" 贴了个膜";
    }
}

手写笔装饰器

public class PhonePen extends PhoneAccessory{
    private Phones phone;

    public PhonePen(Phones p){
        this.phone=p;
    }

    @Override
    public String getDescription() {
        return this.phone.getDescription()+" 送了支手写笔";
    }
}

测试

public class MainTest {
    public static void main(String[] args) {
        Phones phone = new AndroidPhone();
        System.out.println(phone.getDescription());

        PhoneCover coverPhone = new PhoneCover(phone);
        System.out.println(coverPhone.getDescription());

        PhoneMembrane membranePhone = new PhoneMembrane(coverPhone);
        System.out.println(membranePhone.getDescription());

        PhonePen penPhone = new PhonePen(membranePhone);
        System.out.println(penPhone.getDescription());
    }
}

运行结果:

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值