Java设计模式

设计模式之装饰者模式

2020-10-08  本文已影响0人  无聊到学习

一、简介

一种结构型模式,它可以在不改变原有对象的情况下,动态的给一个对象扩展新的功能。

一般包括:

需要注意的是装饰者模式也建立在继承的基础之上的,类似于继承(装饰者和被装饰者继承同一个类,以便装饰者扩展被装饰者的功能以及装饰者作为被装饰者)+聚合复用(复用被装饰者的功能)

即扩展的功能AB=装饰者中重写功能A(){被装饰者的功能A+额外的功能B},其中原有功能A相当于被装饰者,额外的功能B相当于装饰者,由于装饰者和被装饰者继承了同一个类,扩展的功能AB又可以作为被装饰者装饰,如此一直嵌套下去,其行为类似于递归,返回的条件就是基础功能A。

二、优缺点

它的优点是:

它的缺点是动态装饰时,多层装饰时会更复杂(使用继承来拓展功能会增加类的数量,使用装饰者模式不会像继承那样增加那么多类的数量但是会增加对象的数量,当对象的数量增加到一定的级别时,无疑会大大增加我们代码调试的难度)

三、举例

1.定义抽象的被装饰者(面条)

abstract class Noodle{
    public abstract String getDesc();
    public abstract int getPrice();
}

2.定义具体的被装饰者(炒面),被装饰者的初始状态或者称为主体

class FriedNoodle extends Noodle{
    @Override
    public String getDesc() {
        return "炒面 ";
    }
    @Override
    public int getPrice() {
        return 10;
    }
}

3.定义抽象的装饰者(和面相关的一些调料)

abstract  class Others extends Noodle{
    private Noodle noodle;//将要被装饰的被装饰者
    public Others(Noodle noodle){
        this.noodle=noodle;
    }
    public Noodle getNoodle() {
        return noodle;
    }
    public abstract void printInfo();
}

4.定义具体的装饰者(如鸡蛋,肉丝)——鸡蛋

class NoodleWithEgg extends Others{
    public NoodleWithEgg(Noodle noodle){
        super(noodle);//初始化被装饰者
    }
    @Override
    public void printInfo() {
        if(getNoodle() instanceof  Others){
            ((Others)getNoodle()).printInfo();
        }
        System.out.println("装饰者为:鸡蛋,"+"被装饰者为:"+getNoodle().getDesc());
    }
    @Override
    public String getDesc() {
        return getNoodle().getDesc()+"加一个鸡蛋 ";
    }

    @Override
    public int getPrice() {
        return getNoodle().getPrice()+1;
    }   
}

4.定义具体的装饰者(如鸡蛋,肉丝)——肉丝

class NoodleWithMeat extends Others{
    public NoodleWithMeat(Noodle noodle){
        super(noodle);//初始化被装饰者
    }
    @Override
    public void printInfo() {
        if(getNoodle() instanceof  Others){
            ((Others)getNoodle()).printInfo();
        }
        System.out.println("装饰者为:肉丝,"+"被装饰者为:"+getNoodle().getDesc());
    }
    @Override
    public String getDesc() {
        return getNoodle().getDesc()+"加一份肉丝 ";
    }

    @Override
    public int getPrice() {
        return getNoodle().getPrice()+2;
    }   
}

测试:

public class 装饰者模式 {

    public static void main(String[] args) {
        //订一份炒粉,加两个鸡蛋,一份肉丝(最外层的装饰者是肉丝,被装饰者是炒粉+两个鸡蛋)
        //1.先做好主体——炒粉
        FriedNoodle friedNoodle=new FriedNoodle();
        //2.用一个鸡蛋对炒粉进行装饰
        NoodleWithEgg egg1_Noodle=new NoodleWithEgg(friedNoodle);
        //3.再用一个鸡蛋对上面的(1个鸡蛋+炒粉)进行装饰
        NoodleWithEgg egg2_Noodle=new NoodleWithEgg(egg1_Noodle);
        //4.再用一份肉丝对上面的(2个鸡蛋+炒粉)进行装饰,大功告成
        NoodleWithMeat myNoodle=new NoodleWithMeat(egg2_Noodle);
        //显示我们的订餐信息,及价格
        System.out.println(myNoodle.getDesc()+"价钱:"+myNoodle.getPrice());
        //显示我们的装饰过程
        myNoodle.printInfo();
    }

}

运行结果:

炒面 加一个鸡蛋 加一个鸡蛋 加一份肉丝 价钱:14
装饰者为:鸡蛋,被装饰者为:炒面 
装饰者为:鸡蛋,被装饰者为:炒面 加一个鸡蛋 
装饰者为:肉丝,被装饰者为:炒面 加一个鸡蛋 加一个鸡蛋 

四、扩展

装饰者和代理模式
装饰者模式关注的是对象的动态添加功能。代理模式关注的是对对象的控制访问,对它的用户隐藏对象的具体信息。

五、参考

设计模式(三)—— 装饰者模式
JAVA设计模式初探之装饰者模式
装饰者模式

上一篇 下一篇

猜你喜欢

热点阅读