Java design patterns-structural design pattern (decorator design pattern)

Introduction

    1、也叫包装设计模式,属于结构型模式,它是作为现有的类的⼀个包装,允许向⼀个现有的对象添加新的功能,同时⼜不改变其结构
    2、给对象增加功能,⼀般两种⽅式 继承或关联组合,将⼀个类的对象嵌⼊另⼀个对象中,由另⼀个对象来决定是否调⽤嵌⼊对象的⾏为来增强功能,这个就是装饰器模式,⽐继承模式更加灵活

Application scenarios

    1、买了个⾃⾏⻋,店家提供多种改装⽅案,加个⼤的喇叭、加个防爆胎等,经过装饰之后成为⽬的更明确的⾃⾏⻋,更能解决问题。像这种不断为对象添加装饰的模式就叫 Decorator 模式,Decorator 指的是装饰物。
    2、以动态、透明的⽅式给单个对象添加职责,但⼜能不改变其结构
    3、JDK源码⾥⾯应⽤的最多的就是IO流,⼤量使⽤装饰设计模式

Insert image description here

Role (the decorator and the decorated object have the same superclass (Component))

Abstract Component

    定义装饰⽅法的规范,最初的⾃⾏⻋,仅仅定义了⾃⾏⻋的API

Decorated (ConcreteComponent)

    1Component的具体实现,也就是我们要装饰的具体对象
    2、实现了核⼼⻆⾊的具体⾃⾏⻋

Decorator component (Decorator)

    1、定义具体装饰者的⾏为规范,Component⻆⾊有相同的接⼝,持有组件(Component)对象的实例引⽤
    2、⾃⾏⻋组件 都有 名称和价格

ConcreteDecorator

    1、负责给构件对象装饰附加的功能
    2、⽐如 喇叭,防爆胎

Case demo

    买了个⾃⾏⻋,店家⾥⾯ 有⼩号、中号、⼤号等规格的⾃⾏⻋。然后改造加⼀个喇叭,后来不够⼜要加多⼀个,⼀个防爆胎不够,⼜有两个,存在很多个随机组合的改装。店家就苦恼了,这样的结构难搞,价格也难算,⽽且需求再变动,就更麻烦了。使⽤装饰者就可以解决这个问题

Create common components

/**
 *
 * @Description  通用组件
 **/

public interface Bike {
    
    

    String getDescription();

    int getPrice();

}

concrete decorator

/**
 *
 * @Description 具体的被装饰者,ConcreteComponent
 **/

public class BigBike implements Bike{
    
    

    private String description = "大号自行车";

    @Override
    public String getDescription() {
    
    
        return description;
    }

    /**
     * 200元是大号自行车的价格
     * @return
     */
    @Override
    public int getPrice() {
    
    
        return 200;
    }
}

specific decorator

/**
 *
 * @Description 具体的被装饰者,ConcreteComponent
 **/

public class SmallBike implements Bike{
    
    

    private String description = "小号自行车";

    @Override
    public String getDescription() {
    
    
        return description;
    }

    /**
     * 100元是小号自行车的价格
     * @return
     */
    @Override
    public int getPrice() {
    
    
        return 200;
    }
}

Decorator

/**
 * 组件Decorator
 **/

public class BikeDecorator implements Bike {
    
    

    private String description = "我只是装饰器,啥都不表示,子类帮我传递";




    @Override
    public String getDescription() {
    
    
        return description;
    }

    @Override
    public int getPrice() {
    
    
        return 0;
    }
}

RoleConcreteDecorator

/**
 *
 * @Description RSC 是防爆胎的缩写,角色 ConcreteDecorator
 **/

public class RSCBikeDecorator extends BikeDecorator {
    
    


    private String description = "增加一个防爆胎";


    private Bike bike;

    public RSCBikeDecorator(Bike bike){
    
    
        this.bike = bike;
    }


    @Override
    public String getDescription() {
    
    
        return bike.getDescription() + ","+ description;
    }

    /**
     * 100 是防爆胎的价格
     * @return
     */
    @Override
    public int getPrice() {
    
    
        return bike.getPrice() + 100;
    }
}

RoleConcreteDecorator

/**
 *
 * @Description 喇叭,角色 ConcreteDecorator
 **/

public class SuonaBikeDecorator extends BikeDecorator {
    
    


    private String description = "增加一个喇叭";


    private Bike bike;

    public SuonaBikeDecorator(Bike bike){
    
    
        this.bike = bike;
    }


    @Override
    public String getDescription() {
    
    
        return bike.getDescription() + ","+ description;
    }

    /**
     * 50 是唢呐喇叭的价格
     * @return
     */
    @Override
    public int getPrice() {
    
    
        return bike.getPrice() + 50;
    }
}

test

public class Main {
    
    

    public static void main(String[] args) {
    
    

        /**
         * 大自行车 200
         * 小自行车 100
         * 防爆胎 100
         * 喇叭 50
         */

        //选个自行车
        Bike bike = new BigBike();

        //搭配了个RSC防爆胎
        bike = new RSCBikeDecorator(bike);
        bike = new RSCBikeDecorator(bike);

        //搭配了一个喇叭
        bike = new SuonaBikeDecorator(bike);
        bike = new SuonaBikeDecorator(bike);

        System.out.println(bike.getDescription()+", 价格:"+bike.getPrice());

    }
}

result

大号自行车,增加一个防爆胎,增加一个防爆胎,增加一个喇叭,增加一个喇叭,价格:500

Advantages and Disadvantages

advantage

    1、装饰模式与继承关系的⽬的都是要扩展对象的功能,但装饰模式可以提供⽐继承更多的灵活性。
    2、使⽤不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同⾏为的组合,原有代码⽆须改变,符合“开闭原则”

shortcoming

    1、装饰模式增加了许多⼦类,如果过度使⽤会使程序变得很复杂 (多层包装)
    2、增加系统的复杂度,加⼤学习与理解的难度

Comparison between decorator mode and bridge mode

    1、相同点都是通过封装其他对象达到设计的⽬的,和对象适配器也类似,有时也叫半装饰设计模式
    2、没有装饰者和被装饰者的主次区别,桥接和被桥接者是平等的,桥接可以互换,不⽤继承⾃同⼀个⽗类⽐如例⼦⾥⾯的,可以是Phone持有Color,也可以是Color持有Phone
    3、桥接模式不⽤使⽤同⼀个接⼝;装饰模式⽤同⼀个接⼝装饰,接⼝在⽗类中定义

Guess you like

Origin blog.csdn.net/csdn_mycsdn/article/details/131036870