软件设计模式第五篇(装饰器模式)

前言

其实,在学习装饰者模式之前,我们也学了代理模式,下面看装饰器模式的类图
在这里插入图片描述是不是跟代理模式的类图特像呢。。不过他们各有侧重点。

  • 代理模式,专注于被代理对象的访问
  • 装饰器模式,则专注于被装饰对象的附加额外功能

装饰器实现修饰对象(Component)的接口,所有请求都转发给它处理,在转发请求之前/之后增加额外功能。使用步骤是:

  1. 用一个Decorator实现/继承需要修饰的对象Component;
  2. 在Decorator中增加一个Component的引用;
  3. 在Decorator的构造器中,增加一个Component参数来初始化Component;
  4. 在Decorator类中,使用Component的引用,将所有请求转发至Component的相应方法;
  5. ConcreteDecorator中所有Override自Component的方法做相应调整

适用场景

运行时,你需要动态地为对象增加额外职责时;
当你需要一个能够代替子类的类,借助它提供额外方法时

代码实现

比如,我现在买一部比亚迪唐的丐版汽车,标准的价格是20W RMB,现在我要加360全景影像,需要1WRMB, 再加一套真皮座椅需要0.5WRMB,这就可以通过装饰器模式实现

首先,我们定义一个汽车接口

/**
 * Author dengcs
 * date 2020-06-26
 * comment 汽车接口
 */
public interface Car {
    //获取价格
    public double getPrice();
    //获取配置
    public String getConfigure();
}

写一个装饰器类,同样实现汽车Car的接口,并引用Car,通过构造函数进行初始化。并将getPrice()和getConfigure()方法转发给被装饰对象。

/**
 * Author dengcs
 * date 2020-06-26
 * comment 汽车的装饰类,可以对被装饰器类添加各种配置
 */
public class CarDecorator implements Car {
    protected final Car decoratorCar;

    //构造函数进行初始化
    public CarDecorator(Car car) {
        this.decoratorCar = car;
    }

   
    @Override
    public double getPrice() {
        return decoratorCar.getPrice();
    }

    @Override
    public String getConfigure() {
        return decoratorCar.getConfigure();
    }
}

现在实现一个唐的丐版类,价格20W,配置只有标准的配置,如下

/**
 * Author dengcs
 * date 2020-06-26
 * comment 唐的标准版
 */
public class TangCar implements Car {

    @Override
    public double getPrice() {
        return 200000d;
    }

    @Override
    public String getConfigure() {
        return "标准配置";
    }
}

具体加360全景影像类,如下

/**
 * Author dengcs
 * date 2020-06-26
 * comment 360全景影像类
 */
public class RoundCar extends CarDecorator{

    public RoundCar(Car car) {
        super(car);
    }

    @Override
    public double getPrice() {
        double addPrice = 10000d;
        return super.getPrice()+addPrice;
    }

    @Override
    public String getConfigure() {
        return super.getConfigure()+";360全景影像";
    }
}

最后,添加真皮座椅的装饰器类,原理一样

/**
 * Author dengcs
 * date 2020-06-26
 * comment 真皮座椅装饰器类
 */
public class ZhenpiCar extends CarDecorator{

    public ZhenpiCar(Car car) {
        super(car);
    }

    @Override
    public double getPrice() {
        double addPrice = 5000d;
        return super.getPrice()+addPrice;
    }

    @Override
    public String getConfigure() {
        return super.getConfigure()+";真皮座椅";
    }
}

测试

测试代码DecoratorTest类,进行测试

/**
 * Author dengcs
 * date 2020-06-26
 * comment 测试
 */
public class DecoratorTest {
    private static void print(Car car){
        System.out.println("花费了:"+car.getPrice());
        System.out.println("配置:"+car.getConfigure());
        System.out.println("====================");
    }

    public static void main(String[] args){
        //标准配置
        Car car = new TangCar();
        print(car);

        //增加360全景影像
        car = new RoundCar(car);
        print(car);

        //增加真皮座椅
        car = new ZhenpiCar(car);
        print(car);
    }
}

测试结果如下
在这里插入图片描述

写在最后

从上个例子可以看出,装饰器模式的结构很像代理模式,装饰器模式的请求转发过程很像责任链模式,只不过:

职责链模式在转发请求过程中,最多只有一个对象会处理请求,而装饰器模式则有多个对象处一个请求。

装饰器模式是代替增加子类的一种解决方案,体现了聚合/合成复用原则的思想,尽量使用组合的方式来扩展功能,这样就把基本功能和扩展功能解耦了,使得代码可复用,可维护,灵活。关键点在于装饰器模式可以动态地为对象增加扩展功能。

源代码下载

相应了解更多的设计模式,请关注我哦O(∩_∩)O哈哈~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值