设计模式-装饰者模式

前言

设计模式遍及咱们编码的每个角落,例如JAVA刚入门那会作的第一个窗口程序用的Swing中的ActionsListener类就是观察者模式实现的;以及咱们文件操做接触比较多的java.io包内的类有许多就是装饰者模式设计的。若是深刻研究过Spring源码的人都会有这个感慨:Spring就是一些设计模式狂魔的做品java

设计模式有一个很是重要的面向对象原则:针对接口编程,不针对实现编程。 在咱们debug排查故障或在写程序的时候多多少少都会有看过Spring MVC中的一些源码,大多数人都会发现Spring的代码是比较难看懂的。那是由于咱们大多都在用面向实现编程的思惟去思考代码。这样去看一群设计模式狂魔整出来的东西固然是有至关大的难度的。咱们须要看懂读懂Spring源码,或者其余开源代码必备的一个良好的功底那就是要熟悉常见的设计模式。编程

装饰者模式

什么是装饰者模式?咱们来看看度娘的解读设计模式

动态的将责任附加到对象上。若要扩展功能,装饰者提供了有别于继承的另外一种选择bash

咱们先从咱们所熟悉的java.io包内的装饰者模式实现的类入手。咱们来看一个熟悉的对象集合 测试

BufferedInputStreamLinerNumberInputStream都是扩展自 FilterInputStream,而 FilterInputStream是一个抽象的装饰类。

装饰java.io类

咱们从上边的java.io类中分析确认了装饰者的重要用途:动态的将责任附加到对象上。ui

为何要使用装饰者模式

咱们从设计一个简单饮料店提及,饮料店中有原味奶茶,珍珠奶茶,绿茶,抹茶等;调料有糖,牛奶,奶泡等。咱们会在第一时间在脑中进行一次类图分析。this

这种设计相似硬编码形式在后期并不能作很好的扩展,并违背了一个很是重要的面向对象设计原则: 类应该对扩展开放,对修改关闭

咱们能够看出这种经过继承设计的饮料店是有很大的缺陷:调料价钱出现改变是会使咱们更改现有的代码;一但出现新的调料或开发出新的饮料都需对现有代码做比较大的改动。这样的代码可维护性是很是糟糕的。编码

接着咱们用装饰者模式作一次的从新设计 spa

当咱们组件与装饰者模式组合时,就是再加入新的行为。例如红豆+珍珠=红豆珍珠奶茶,新的茶饮出来了,无需在添加一个新的类。debug

代码实现

饮料抽象类

public abstract class Berverage {//饮料店抽象基类
    public String description;
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public abstract int Cost();
}
复制代码

调料抽象类

public abstract class CondimentDecorator  extends  Berverage{
    public abstract String getDescription();
}
复制代码

饮料类

public class GreenTea extends Berverage {

    public GreenTea () {
        description = "this is a cup of green tea ";
    }

    public int Cost() {
        return 5;
    }
}
public class MilkTea extends  Berverage {
    public MilkTea() {
        description = "this is a cup of milk tea";
    }
    public int Cost() {
        return 6;
    }
}

public class PearlsMilkTea extends Berverage {
    public PearlsMilkTea() {
        description = "this is a cup of pearls milk tea ";
    }
    public int Cost() {
        return 2;
    }
}

复制代码

调料类

public class Milk extends CondimentDecorator {//牛奶
    Berverage berverage;
    public Milk( Berverage berverage) {
        this.berverage = berverage;
    }

    public String getDescription() {
        return berverage.getDescription()+"+milk";
    }

    public int Cost() {
        return berverage.Cost()+3;
    }
}

复制代码

测试代码

public class Application {

    public static void main(String[] args) {

        //珍珠奶茶
        Berverage berverage1 = new PearlsMilkTea();
        System.out.println(berverage1.getDescription() + " cost = " + berverage1.Cost());

        //绿茶加牛奶
        Berverage berverage = new GreenTea();
        berverage = new Milk(berverage);
        System.out.println(berverage.getDescription()+"cost = "+berverage.Cost());
    }
}
复制代码

测试结果

点题

装饰者模式:动态的将责任附加到对象上。若要扩展功能,装饰者提供了有别于继承的另外一种选择

篇幅中讲到了两个重要的面向对象设计原则

  • 针对接口编程,不针对实现编程
  • 类应该对扩展开放,对修改关闭

The last

三人行,必有我师。在给你们分享干货的同时,才疏学浅还望你们大刀予以斧正。也欢迎关注个人掘金或简书,名称为柴码

相关文章
相关标签/搜索