【设计模式-9】装饰模式的代码实现及使用场景

 装饰器模式类比生活中房屋装修的场景,可以在毛坯房的基础上加以各种装饰,使得房屋的居住属性增强。装饰器模式能够在运行期间,动态地为原始对象增加一些额外的功能,使其功能更为丰富。

1. 概述

装饰模式 可以动态的为某些对象增加一些额外的职责,在某些程度上,装饰器模式类似于继承,但是比继承更加灵活,可以在不改变一个对象本身功能的基础上额外增加新行为。装饰模式是一种对象结构性的模式。

 在定义中,我们提到了继承,通过继承的方式,子类可以在父类的功能上做增加,但这是在编译期间,需要修改子类来完成的。装饰模式可以在运行期间动态的包装原始对象,实现“装饰”的效果。

 装饰模式的实现需要以下4个角色。

  • 组件接口:组件接口是所有被装饰的类和装饰器抽象类共同要实现的接口标准,接口中会定义装饰的行为方法。
  • 组件实现:这里是指被装饰的组件,只需实现组件接口,并且在接口行为方法中实现未被装饰的原始特性就可以。
  • 装饰器:是装饰器的高层抽象类,同样实现了组件接口,同时会声明一个组件接口类型的被装饰对象,一般是抽象类。
  • 装饰器实现:是装饰器抽象类的子类,可以有多种实现,在被装饰对象的基础上添加新的特性,真正实现功能增强的装饰器组件。

2. 代码实现

 在下面的代码案例中,我们假设装修公司提供给客户两种装修方案,分别是中式装修和欧式装修,对于装饰器模式需要的4个角色,我们实现如下:

  • 组件接口
// 组件接口
public interface Component {
    // 表示装饰的行为接口方法
    void fitment();
}

  • 组件实现
// 毛坯房屋 - 被装饰的对象
public class RoughHouse implements Component {
    // 组件接口的实现方法
    @Override
    public void fitment() {
        System.out.print("【原始的毛坯房屋】");
    }
}
  • 装饰器
// 抽象的装饰器
public abstract class AbstractDecorator implements Component {

    // 声明的被装饰的对象属性
    protected Component component;

    // 构造方法中注入被装饰对象的属性
    public AbstractDecorator(Component component) {
        this.component = component;
    }

    // 装修的方法
    @Override
    public void fitment() {
        component.fitment();
    }
}
  • 装饰器实现
// 具体的装饰实现类 - 中式装修风格
public class ChineseStyle extends AbstractDecorator {
    // 构造方法的注入
    public ChineseStyle(Component component) {
        super(component);
    }
    // 功能增强的方法

    @Override
    public void fitment() {
        System.out.print("【中式装修的吊顶");
        super.fitment();
        System.out.print("】");
    }
}

// 具体的装饰实现类 - 欧式装修风格
public class EuropeanStyle extends AbstractDecorator {
    // 构造器 - 装饰对象的注入
    public EuropeanStyle(Component component) {
        super(component);
    }
    // 具体的装修风格
    @Override
    public void fitment() {
        System.out.print("【欧式装修的家电家具");
        super.fitment();
        System.out.print("】");
    }
}

  • 客户端
// 客户端
public class Client {
    public static void main(String[] args) {
        // 只是中式装修
        Component chineseStyle = new ChineseStyle(new RoughHouse());
        chineseStyle.fitment();
        System.out.println("");
        // 只是欧式装修
        Component europeanStyle = new EuropeanStyle(new RoughHouse());
        europeanStyle.fitment();
        System.out.println("");
        // 中式装修+欧式装修
        Component component = new EuropeanStyle(new ChineseStyle(new RoughHouse()));
        component.fitment();
        System.out.println("");
    }
}

3. UML类图

 根据上述房屋装修的代码示例,我们来画一下UML类图,如下所示:
在这里插入图片描述

4. 使用场景

 装饰器模式在某些场景下,如果只有一个具体的被装饰对象,那么抽象的装饰类可以直接作为该具体构件类的子类。

在这里插入图片描述

 在Java类库中,最典型的装饰器模式使用就是Java IO中的输入流和输出流的设计,总体来说,装饰器模式的使用场景还是比较多的。

5. 总结

 最后,我们来总结一下装饰模式的优点:

  1. 相对于继承,装饰器模式更灵活,也不会导致类的数量急剧增加;
  2. 通过装饰实现类的自由组合,可以扩展对象的不同的能力,从而实现不同的行为;
  3. 不同的被装饰类和装饰器实现类,都可以在不改变原有类结构的基础上,直接增加新的类型,符合开闭原则。
  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值