设计模式之装饰器模式

727 阅读3分钟

「这是我参与11月更文挑战的第29天,活动详情查看:2021最后一次更文挑战

本篇文章是设计模式专题的第七篇文章,我会将遇到的设计模式都一一总结在该专题下,我会把自己对每一种设计模式的感悟写下来,以及在实际工作中我们该如何去灵活应用这些设计模式,欢迎大家关注。本篇文章我们就来讲一讲,以更加优雅的方式扩展类的装饰器模式。

装饰器模式的简单介绍

装饰器模式就是在不改变类原有结构的情况下,动态的对类进行扩展的一种设计模式。

这里我们就可以把原有类看做是毛坯房,装饰过的类是商品房。

装饰器模式的类图:

image.png

装饰器模式的各个角色:

  • 抽象构件(Component):这里我们可以将其看做是毛坯房。
  • 具体构件(ConcreteComponent):这里我们可以将其看做是具体的一个毛坯房。
  • 抽象装饰者(Decorator):这里我们可以将其看做是商品房。
  • 具体的装饰者(ConcreteDecorator):这里我们可以将其看做是采用了某种具体设计的商品房。

装饰器模式的具体实现思路

  • 创建抽象构件。
  • 创建抽象构件的具体实现。
  • 创建抽象的装饰者。
  • 创建具体的装饰者。

装饰器模式的具体实现方案

// 抽象构件
public abstract class Component{
    
    public abstract void operation();
}
// 具体构件
public class ConcreteComponent extends Component{
    
    @Override
    public void operation(){
        // do something ...
    }
}
// 抽象的装饰者
public abstract class Decorator extends Component{
    
    protected Component component;
    
    public Decorator(Component component){
        this.component = component;
    }
    @Override
    public void operation(){
        this.component.operation();
    }
}
// 具体的装饰者
public class ConcreteDecorator extends Decorator{
    
    // 扩展的属性
    private Object addField;
    
    public ConcreteDecorator(Component component){
        super(component);
    }
​
    // 扩展的方法
    private void addMethod(){
        // do somethind ... 
    }
​
    // 定义自己的修饰逻辑
    private void decorateMethod(){
        // do somethind ... 
    }
    
    // 重写父类的方法
    public void operation(){
        this.decorateMethod();
        super.operation();
    }
}

装饰器模式的优缺点

优点

  • 通过装饰器对类进行扩展,比通过继承对类进行扩展更加的灵活;
  • 装饰类和被装饰类相互独立,耦合度较低;

缺点

  • 没有继承结构清晰;
  • 包裹层数较多时,难以理解和排查问题;

装饰器模式的适用场景

  1. 需要动态的对对象的功能进行扩展;
  2. 不能或者不便以子类的方式扩展功能,可以代替继承;
  3. 可以用来限制对象的执行条件,也可以进行参数控制和检查等;

装饰器模式总结

学完装饰器模式,想必最让大家困惑的就是装饰器模式与代理模式的区别,他们都是让我可以对类的功能进行增强,扩展。那么我们如何很好的去区分代理模式与装饰器模式呢?代理模式是创建型模式,本质上是在创建类的时候就创建的是代理类,在类创建时就对方法进行了增强;装饰器模式是结构型模式,我们创建对象创建的还是原始对象,就比如我们买房买到的是毛坯房,当我们需要入住,就需要对其进行装饰,将毛坯房传入装饰者模式就能获取到装修过的房子。