2装饰者模式

装饰者模式

装饰者模式(Decorator Pattern) 是一种比较常见的模式。

1装饰者模式的定义

装饰者模式的英文原话是:
Attach Additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.
意思是:动态的给对象添加一些额外的职责。就增加功能来说,装饰者模式比生成子类更为灵活。

装饰者模式有4个角色:
  • 抽象构件(Component)角色:该角色用于规范需要装饰的对象(原始对象)。
  • 具体构件(Concrete Component)角色:该角色实现抽象构件接口,定义一个需要装饰的原始类。
  • 装饰者(Decorator)角色:该角色持有一个构件对象的实例,并定义一个与抽象构件接口一致的接口。
  • 具体装饰(Concrete Decorator)角色:该角色负责对构件对象进行装饰。

引例:
                                 
装饰者模式类图
Component接口
package com.eric.结构型模式.装饰者模式.引例;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 抽象构件
 * @CreateTime 2020-11-29 19:52:25
 */
public interface Component {
    public void operation();
}
ConcreteComponent类---->实现了Component接口
package com.eric.结构型模式.装饰者模式.引例;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 具体构件类
 * @CreateTime 2020-11-29 20:04:05
 */
public class ConcreteComponent implements Component {
    @Override
    public void operation() {
        //业务代码
    }
}
Decorator类实现了Component接口
package com.eric.结构型模式.装饰者模式.引例;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 装饰者
 * @CreateTime 2020-11-29 20:04:47
 */
public class Decorator implements Component {
    private Component component = null;

    public Decorator(Component component){
        this.component = component;
    }

    @Override
    public void operation() {
        this.component.operation();
    }
}
ConcreteDecorator类---->继承了Decorator
package com.eric.结构型模式.装饰者模式.引例;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 具体装饰者
 * @CreateTime 2020-11-29 20:06:35
 */
public class ConcreteDecorator extends Decorator {
    public ConcreteDecorator(Component component) {
        super(component);
    }

    //定义自己的方法
    private void method(){
        System.out.println("装饰");
    }

    //重写operation()方法
    @Override
    public void operation() {
        this.method();
        super.operation();
    }
}

2装饰者模式的应用

a.装饰者模式的优缺点
  • 装饰者类和被装饰类可以独立发展,而不会相互耦合。即Component类无需知道Decorator类,Decorator类是从外部来扩展Component类的功能,而Decorator也不用知道具体的构建。
  • 装饰者模式是继承关系的一种替代方案。装饰类Decorator,不管装饰多少层,返回对象还是Component.
  • 封装模式可以动态的扩展一个实现类功能。
装饰者模式的缺点:多层的装饰是比较复杂的。
b.装饰者模式的使用场景
  • 需要扩展一个类的功能,或给一个类增加附加功能。
  • 需要动态的给一个对象增加功能,这些功能可以再动态地撤销。
  • 需要为一批类进行改装或加装功能。
装饰者模式是对继承的有力补充。单纯的使用继承时,在一些情况下就会增加很多子类,而且灵活性差,维护起来也不容易。装饰者模式可以代替继承,解决类膨胀的问题,如Java基础类库中的IO(输入输出流)相关的类大量使用了装饰者模式。

3装饰者模式实例

例1裸车的装饰过程

                                                
汽车装修的类图
汽车的接口
Car.java
package com.eric.结构型模式.装饰者模式.例1;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 汽车接口
 * @CreateTime 2020-11-29 23:46:29
 */
public interface Car {
    //车的装配
    public void show();
}
汽车的实现类---->实现Car接口
Benz.java
package com.eric.结构型模式.装饰者模式.例1;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 奔驰车(裸车-需装饰)
 * @CreateTime 2020-11-29 23:47:10
 */
public class Benz implements Car{
    @Override
    public void show() {
        System.out.println("奔驰车的默认颜色是黑色!");
    }
}

装饰者的抽象类--->实现Car接口
CarDecorator.java
package com.eric.结构型模式.装饰者模式.例1;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 汽车装饰抽象类
 * @CreateTime 2020-11-29 23:48:36
 */
public abstract class CarDecorator implements Car {
    private Car car = null;
    public CarDecorator(Car car){
        this.car = car;
    }
    @Override
    public void show() {
        this.car.show();
    }
}
装饰者的实现类---->继承CarDecorator类
ConcreteCarDecorator.java
package com.eric.结构型模式.装饰者模式.例1;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 具体的汽车装饰类
 * @CreateTime 2020-11-29 23:50:14
 */
public class ConcreteCarDecorator extends CarDecorator {
    public ConcreteCarDecorator(Car car) {
        super(car);
    }

    //给汽车进行彩绘
    private void print(){
        System.out.println("在车尾绘制“新手“字样,颜色是紫色霞光");
    }
    //给车安装GPS设备
    private void setGps(){
        System.out.println("安装GPS定位导航系统!");
    }

    //重写show()方法
    public void show(){
        super.show();
        this.print();
        this.setGps();
    }
}
测试类
package com.eric.结构型模式.装饰者模式.例1;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 测试
 * @CreateTime 2020-11-29 23:54:31
 */
public class ClientDemo {
    public static void main(String[] args) {
        Car car = new Benz();
        //对奔驰车进行装饰
        ConcreteCarDecorator decorator = new ConcreteCarDecorator(car);
        decorator.show();
    }
}
测试结果

例2给形状上色

形状的接口
Shape.java
package com.eric.结构型模式.装饰者模式.例2;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 形状接口
 * @CreateTime 2020-11-30 00:09:30
 */
public interface Shape {
    //画画
    public void draw();
}
Shape接口的两个实现类
Circle.java
package com.eric.结构型模式.装饰者模式.例2;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 圈圈
 * @CreateTime 2020-11-30 00:10:09
 */
public class Circle implements Shape{

    @Override
    public void draw() {
        System.out.println("画了个圈圈...");
    }
}
Rectangle.java
package com.eric.结构型模式.装饰者模式.例2;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 矩形
 * @CreateTime 2020-11-30 00:11:29
 */
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("画了一个框框...");
    }
}
有了Shape的两个实现类后,开始创建它的抽象装饰者类。
ShapeDecorator.java
package com.eric.结构型模式.装饰者模式.例2;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 矩形
 * @CreateTime 2020-11-30 00:11:29
 */
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("画了一个框框...");
    }
}
最后是具体的装饰者类------>继承ShapeDecorator
RedShapeDecorator.java
package com.eric.结构型模式.装饰者模式.例2;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 红色的装饰者
 * @CreateTime 2020-11-30 00:14:41
 */
public class RedShapeDecorator extends ShapeDecorator {
    public RedShapeDecorator(Shape shape) {
        super(shape);
    }

    private void setRedBorder(){
        System.out.println("边边是红色的...");
    }

    @Override
    public void draw() {
        shape.draw();
        this.setRedBorder();
    }
}
测试类
package com.eric.结构型模式.装饰者模式.例2;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 测试
 * @CreateTime 2020-11-30 00:20:50
 */
public class DecoratorPatternDemo {
    public static void main(String[] args) {
        Shape circle = new Circle();
        ShapeDecorator redShapeDecorator1 = new RedShapeDecorator(circle);
        redShapeDecorator1.draw();

        Shape rectangle = new Rectangle();
       ShapeDecorator redShapeDecorator2 = new RedShapeDecorator(rectangle);
        redShapeDecorator2.draw();
    }
}
测试截图
后续可能会精简和改进。




posted @ 2020-12-29 08:49  喵酱张-Eric  阅读(73)  评论(0编辑  收藏  举报