JAVA设计模式笔记(装饰者模式)

装饰者模式:
装饰者模式对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

结构
在这里插入图片描述
角色
抽象构件(Component)角色:给出一个抽象接口,以规范准备接受附加责任的对象。
具体构件(ConCreteComponent)角色:定义一个将要接受附加责任的类。
装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

咖啡馆案例
有一个新开的咖啡馆,有很多种咖啡饮料,咖啡饮料种可以添加调料,调料也需要收费,需要设计一个订购咖啡的程序。

一种方式是建立一个饮料抽象类,然后每种调料组合都作为子类继承抽象类,这样会造成类爆炸,而且一种饮料或者调料的价格改变,多个类都要进行修改,不利于维护,不是一种好的方式。
在这里插入图片描述
使用装饰者模式可以比较好的解决这个问题

结构:
在这里插入图片描述
代码实现:

  //Drink类
    public abstract class Drink {
        public String description="";
        private float price=0f;
        public void setDescription(String description)
        {
            this.description=description;
        }

        public String getDescription()
        {
            return description;
        }
        public float getPrice()
        {
            return price;
        }
        public void setPrice(float price)
        {
            this.price=price;
        }
        public abstract float cost();
}

//Coffee类
public class Coffee extends Drink {
    @Override
    public float cost() {
        return getPrice();
    }
}

public class Decaf extends Coffee {
    public Decaf(){
        setDescription("Decaf");
        setPrice(5.0f);
    }
}

//装饰者类
public class Decorator extends Drink {
    private Drink Obj;

    public Decorator(Drink Obj){
        this.Obj=Obj;
    };

    @Override
    public float cost() {
        // TODO Auto-generated method stub

        return getPrice()+Obj.cost();
    }
}
//调料类
public class Milk extends Decorator {
    public Milk(Drink Obj) {
        super(Obj);
        setDescription(Obj.description+"+milk");
        setPrice(2.0f);
    }
}
public class Chocolate extends Decorator {
    public Chocolate(Drink Obj) {
        super(Obj);
        setDescription(Obj.description+"+Chocolate");
        setPrice(3.0f);
    }
}
//客户端使用
public class Client {
    public static void main(String[] args) {
        Drink decaf=new Decaf();
        decaf.getDescription();
        System.out.println(decaf.getDescription()+":"+decaf.cost());
        Drink decaf1=new Decaf();
        decaf1=new Chocolate(decaf1);
        decaf1=new Milk(decaf1);
        System.out.println(decaf1.getDescription()+":"+decaf1.cost());
    }
}

结果:
在这里插入图片描述
客户端调用的过程类似于打包装,比如说要订一杯牛奶巧克力摩卡咖啡,可以先创建一杯单品对象摩卡咖啡,然后创建装饰者对象milk包装decaf,再创建装饰者对象chocolate包装milk与decaf。
在这里插入图片描述
计算费用的时候,先计算最外层Chocolate的费用,再一层一层叠加内部的费用,层层递进。

装饰者提供了比继承更有弹性的扩展方案,各种调料可以随意组合,需要添加新的调料时只需要新增一个类就可以了。JAVA中的IO流就用到了装饰者模式。

发布了56 篇原创文章 · 获赞 3 · 访问量 1633

猜你喜欢

转载自blog.csdn.net/qq_20786911/article/details/103494980