设计模式-装饰者模式

装饰着模式:简单来说,就是现在有一个主体功能,需要在这个主体功能之外加一些附属功能,而且主体功能和附属功能都可以独立运行,类似于基础款和升级款的概念。就像是在主体功能之外加了一层装饰,所以叫装饰者模式,也叫包装者模式。

其实如果光从这个需求看,我们最直接的应该是想到继承。但是继承使用起来并不方便,如果我的附属功能有很多,而且主体功能也有很多具体的实现,那么使用继承将是一个非常大的工作量而且不利于扩展。

举个例子来说明一下:

比如我要买车,买车可以有很多选择,首先可能会有我们钟爱的品牌,品牌下有可能有各种型号,选中了某款车型之后,销售人员肯定就坐下来给你推销各种附加功能,什么真皮座椅,防滑垫,酷酷的轮毂,再加个尾翼等等。那么后面的这些附属功能就可以理解为装饰者模式中的装饰,其实完全不要这些,这辆车照样可以跑,不过经济不紧张的话再加些装饰也是可以让人心情愉悦的哈。

被装饰者,也就是主体功能,在我们这个例子中就是车

// 被包装
public interface Car {
    public String desc();
    public Double price();
}

根据品牌我们实现两个具体的被装饰者

// byd
public class Byd implements Car{
    @Override
    public String desc() {
        return "BYD ";
    }

    @Override
    public Double price() {
        return 1000.00;
    }
}
// Tesla
public class Tesla implements Car{
    @Override
    public String desc() {
        return "Tesla";
    }

    @Override
    public Double price() {
        return 800.00;
    }
}

然后就是装饰者了,这里我们要让装饰者实现主体功能,同时需要把被装饰者集成到自己的属性中。在被装饰之后,至少可以有主体功能,也可以在此基础之上进行扩展。

public abstract class CarWrapper implements Car{
    private Car car;

    public CarWrapper(Car car) {
        this.car = car;
    }

    @Override
    public String desc() {
        return car.desc();
    }

    @Override
    public Double price() {
        return car.price();
    }
}

具体的装饰着类

// 真皮座椅
public class CarWrapperDermis extends CarWrapper{
    public CarWrapperDermis(Car car) {
        super(car);
    }

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

    @Override
    public Double price() {
        return super.price()+666;
    }
}
// 双倍安全气囊
public class CarWrapperDoubleSafe extends CarWrapper{
    public CarWrapperDoubleSafe(Car car) {
        super(car);
    }

    @Override
    public String desc() {
        return super.desc() +" +双倍安全气囊";
    }

    @Override
    public Double price() {
        return super.price()+888;
    }
}

测试使用

public class Client {
    public static void main(String[] args) {
        // 被装饰者,主体功能
//        Car car = new Byd();
        Car car = new Tesla();
        // 装饰者,需要接收一个被装饰者作为参数
        CarWrapper carWrapper = new CarWrapperDermis(car);
        System.out.println(carWrapper.desc()+" : "+carWrapper.price());

        System.out.println("========================");
        // 这个设计的巧妙之处在于这里,包装器类的对象本身还可以作为被包装的对象传给新的包装器
        carWrapper = new CarWrapperDoubleSafe(carWrapper);
        System.out.println(carWrapper.desc()+" : "+carWrapper.price());

    }
}

小结一下:这个装饰着模式的关键点就在于:装饰者既继承自被装饰者,同时又拥有被装饰者作为一个属性。这样的设计就是为了使装饰者在提供被装饰者的主体功能之外,还能对它进行扩展。而且这样做之后,有一个巧妙的地方就是,装饰者本身又可以作为另外一个装饰者的参数,也就是可以进行多次包装。这样的话对于大量繁复的附属功能来说就可以随意的进行扩展使用。可扩展性特别好。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容