JAVA设计模式——装饰者模式

JAVA设计模式——装饰者模式

一.主要概念

1.定义

以对客户端透明的方式动态扩展对象的功能,是继承关系的一个替代(继承会产生大量的子类,而且代码有冗余)

2.装饰者模式涉及的角色

抽象构件角色(Component):通常是一个抽象类或者一个接口,可以给这些对象动态的添加职责

具体构件角色(Concrete Component):是Component的子类,实现了对应的方法,它就是那个被装饰的类。

装饰角色(Decorator):是Component的子类,它是具体装饰角色共同实现的抽象类(也可以是接口),并且持有一个Component类型的对象引用,它的主要作用就是把客户端的调用委派到被装饰类。

具体装饰角色(Concrete Decorator):定义具体的装饰类,给Component添加职责

3.装饰者模式的UML图

JAVA设计模式——装饰者模式_第1张图片

二.具体实现

抽象构件角色(Component)

/**
 * 抽象构件角色(Component):定义对象动态的添加职责
 * 定义手抓饼的行为
 */
public interface Cake {

    String nameDetails();

    double price();
}

具体构件角色(Concrete Component)

/**
 * 具体构件角色(Concrete Component):就是那个被装饰的类。
 * 具体手抓饼(原味)
 */
public class CakeImpl implements Cake {
    @Override
    public String nameDetails() {
       return "原味手抓饼";
    }

    @Override
    public double price() {
        return 5;
    }
}

装饰角色(Decorator)

/**
 *装饰角色(Decorator):持有一个Component类型的对象引用,它的主要作用就是把客户端的调用委派到被装饰类。
 * 手抓饼装饰类
 */
public class CakeDecorator implements Cake {

    Cake cake;

    // 构造方法是重点,通过构造方法实现装饰
    public CakeDecorator(Cake cake){
        this.cake = cake;
    }

    @Override
    public String nameDetails() {
        return cake.nameDetails();
    }

    @Override
    public double price() {
        return cake.price();
    }
}

具体装饰角色(Concrete Decorator)

/**
 * 具体装饰角色(Concrete Decorator)
 * 奶油手抓饼
 */
public class CreamCakeDecorator extends CakeDecorator {

    public CreamCakeDecorator(Cake cake) {
        super(cake);
    }

    @Override
    public String nameDetails() {
        return "奶油" + super.nameDetails();
    }

    @Override
    public double price() {
        return super.price() + 3.0;
    }
}

test类

/**
 * test类
 * 采用装饰的方法相对于继承方法:减少了类定义的个数,通过装饰来组合原料,而不需要继承来实现不同的组合关系
 * eg:1,2,3的组合关系有4种(1,2)(1,3)(2,3)(1,2,3)
 * 继承方式需要再增加四个类来实现,而装饰是让客户端自由组合,而且还可以控制组合的顺序!
 */
public class Main {

    public static void main(String[] args) {

        System.out.println("小明要:");

        Cake plainCake = new CakeImpl();  // 需要被装饰的对象
        System.out.println(plainCake.nameDetails() + " $ " + plainCake.price());

        System.out.println("小花要:");
        // 通过构造方法装饰对象
        Cake eggCake= new EggCakeDecorator(plainCake);
        System.out.println(eggCake.nameDetails() + " $ " + eggCake.price());

        System.out.println("张三需要所有配料:");
        //让客户端自由组合,而且还可以控制组合的顺序!
        Cake beefEggCake = new BeefCakeDecorator(eggCake);
        Cake creamBuffEggCake = new CreamCakeDecorator(beefEggCake);
        System.out.println(creamBuffEggCake.nameDetails() + " $ " + creamBuffEggCake.price());
    }
}

三.总结

1.适配器模式与装饰模式的区别

适配器模式是为了包装接口的兼容性
装饰模式包装是为了动态的添加方法行为

2.优点

1.装饰模式代替继承模式更具灵活性
2.通过动态的方式来扩展对象功能,在客户端选择不同的装饰器,实现不同的行为

3.jdk使用情况

java.io.BufferedInputStream(InputStream)
java.io.DataInputStream(InputStream)
java.io.BufferedOutputStream(OutputStream)

你可能感兴趣的:(设计模式)