Java 设计模式---装饰模式

目录

一、装饰模式

1、引子

2、装饰模式简介

3、装饰器模式原理

4、装饰模式实例

5、装饰器模式总结


一、装饰模式

1、引子

装饰模式?

    ①肯定让你想起又黑又火的家庭装修来。其实两者在道理上还是有很多相像的 地方。家庭装修无非就是要掩盖住原来实而不华的墙面,抹上一层华而不实的涂料,让生活多一点色彩。而墙还是那堵墙,他的本质一点都没有变,只是多了一层外衣而已。

    ②回想一下 Java 当中的各种输入输出流,各种功能一层嵌套一层,就好像不断得 给一个产品加功能,加完以后在消费者看来,原来是是什么产品现在还是什么产 品,只不过用的时候功能增加了。

那设计模式中的装饰模式,是什么样子呢?

2、装饰模式简介

    装饰模式(decorator pattern) 的原始定义是:动态的给一个对象添加一些额外的职责。就扩展功能而言,装饰器模式提供了一种比使用子类更加灵活的替代方案。

    装饰模式(Decorator)也叫包装器模式(Wrapper)。GOF 在《设计模式》一书中给出的定义为:动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。

    假设现在有有一块蛋糕,如果只有涂上奶油那这个蛋糕就是普通的奶油蛋糕, 这时如果我们添加上一些蓝莓,那这个蛋糕就是蓝莓蛋糕。如果我们再拿一块黑巧克力然后写上姓名、插上代表年龄的蜡烛, 这就是变成了一块生日蛋糕 

    在软件设计中,装饰器模式是一种用于替代继承的技术,它通过一种无须定义子类的方式给对象动态的增加职责,使用对象之间的关联关系取代类之间的继承关系。

3、装饰器模式原理

装饰(Decorator)模式中的角色:

    抽象构件(Component)角色 :它是具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法。它引进了可以使客户端以一致的方式处理未被装饰的对象以及装饰之后的对象,实现客户端的透明操作
    具体构件(Concrete  Component)角色 :它是抽象构件类的子类,用于定义具体的构建对象,实现了在抽象构建中声明的方法,装饰类可以给它增加额外的职责(方法)。
    抽象装饰(Decorator)角色 :它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护了一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。
    具体装饰(ConcreteDecorator)角色 : 它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用于扩充对象的行为。

装饰模式结构图

4、装饰模式实例

/**
 * 抽象构件类
 */
public abstract class Component {

    public abstract void operation();
}
/**
 * 具体构建类
 */
public class ConcreteComponent extends Component {

    @Override
    public void operation() {
        //基础功能实现(复杂功能通过装饰类进行扩展)
        System.out.println("操作ConcreteComponent");
    }
}
/**
 * 抽象装饰类-装饰者模式的核心
 */
public class Decorator extends Component{

    //维持一个对抽象构件对象的引用
    private Component component;

    //注入一个抽象构件类型的对象
    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        //调用原有业务方法(这里并没有真正实施装饰,而是提供了一个统一的接口,将装饰过程交给子类完成)
        component.operation();
    }
}
/**
 * 具体装饰类
 */
public class ConcreteDecorator extends Decorator {

    public ConcreteDecorator(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation(); //调用原有业务方法
        addedBehavior(); //调用新增业务方法
    }

    //新增业务方法
    public void addedBehavior(){
        System.out.println("新增业务方法...");
    }
}

测试

public class CliectTest {

    public static void main(String[] args) {
        Decorator decorator = new ConcreteDecorator(new ConcreteComponent());
        decorator.operation();
    }
}

5、装饰器模式总结

装饰器模式的优点:

    1. 对于扩展一个对象的功能,装饰模式比继承更加灵活,不会导致类的个数急剧增加
    2. 可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰类,从而实现不同的行为。
    3. 可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合可以创造出很多不同行为的组合,得到更加强大的对象。
    4. 具体构建类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构建类和具体装饰类,原有类库代码无序改变,符合开闭原则。

装饰器模式的缺点:

    1. 在使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值不同,大量的小对象的产生势必会占用更多的系统资源,在一定程度上影响程序的性能。
    2. 装饰器模式提供了一种比继承更加灵活、机动的解决方案,但同时也意味着比继承更加易于出错,排错也更加困难,对于多次装饰的对象,在调试寻找错误时可能需要逐级排查,较为烦琐。

装饰器模式的适用场景

    1. 快速动态扩展和撤销一个类的功能场景。 比如,有的场景下对 API 接口的安全性要求较高,那么就可以使用装饰模式对传输的字符串数据进行压缩或加密。如果安全性要求不高,则可以不使用。
    2. 不支持继承扩展类的场景。 比如,使用 final 关键字的类,或者系统中存在大量通过继承产生的子类。

Java 设计模式

有道无术,术尚可求也,有术无道,止于术。
一个程序员最重要的能力是:写出高质量的代码!!
无论你是年轻还是年长,所有程序员都需要记住:时刻努力学习新技术,否则就会被时代抛弃!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杀神lwz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值