装饰者模式

装饰者模式

概念

1、装饰者模式 动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性地替代方案。
2、装饰者和被装饰对象有相同的超类型
3、装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。
4、对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。

场景

咖啡店有多种咖啡,如深焙咖啡等,每种咖啡还可以加入任意种调料,例如牛奶(milk)、豆浆(Soy)、摩卡(Mocha)、奶泡等等。
如果顾客想要摩卡和咖啡,那么我们要做的就是:
1、拿一个深焙咖啡对象
2、以摩卡对象装饰它
3、以奶泡对象装饰它
4、调用cost()方法,并依赖委托将调料的价钱加上去

类图

在这里插入图片描述

代码

抽象类

饮料类

//饮料类
public abstract class Beverage {
    String description="Unknown Beverage";

    public String getDescription(){
        return  description;
    }

    public abstract double cost();
}

调料类

//调料类
public abstract class Condiment  extends Beverage{
        public abstract String getDescription();
}
具体实现

饮料类的具体实现:深焙咖啡

public class DarkRoast extends Beverage {

    public DarkRoast(){
        this.description="DarkRoast";
    }

    @Override
    public double cost() {
        return 1.88;
    }
}

调料类的具体实现:摩卡

public class Mocha extends Condiment {

    Beverage beverage;

    public  Mocha(Beverage beverage){
        this.beverage=beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription()+", Mocha";
    }

    @Override
    public double cost() {
        return 0.20+beverage.cost();
    }
}

调料类的具体实现:奶泡

public class Whip extends Condiment {

    Beverage beverage;

    public Whip(Beverage beverage){
        this.beverage=beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription()+",Whip";
    }

    @Override
    public double cost() {
        return 0.4+beverage.cost();
    }
}
测试
    public static void main(String[] args) {
/*        Beverage beverage=new Espresso();
        System.out.println(beverage.getDescription()+"$"+beverage.cost());

        Beverage beverage1=new HouseBlend();
        beverage1=new Mocha(beverage1);
        beverage1=new Mocha(beverage1);
        beverage1=new Whip(beverage1);
        System.out.println(beverage1.getDescription()+"$"+beverage1.cost());*/

        Beverage beverage2=new DarkRoast() ;
        beverage2=new Mocha(beverage2);
        beverage2=new Whip(beverage2);
        System.out.println(beverage2.getDescription()+",$"+beverage2.cost());
    }

结果
在这里插入图片描述

理解

上述代码的逻辑大致如下,通过递归的方式,在被装饰者外面,层层包装,在每一层添加当前层的特有功能。
这样就可以任意组合,而不需要为每种组合都去独立创建一个类。
在这里插入图片描述

Java中用到装饰者的地方–IO包

实现一个功能:把读取的所有字符都转成小写

public class LowerCaseInputStream extends FilterInputStream {

    protected LowerCaseInputStream(InputStream in) {
        super(in);
    }

    public int read() throws IOException{
        int c=super.read();
        return (c==-1 ? c:Character.toLowerCase((char) c));
    }

    public int read(byte[] b,int offset, int len)throws IOException
    {
        int result=super.read(b,offset,len);
        for (int i=offset;i<offset+result;i++){
            b[i]=(byte) Character.toLowerCase((char)b[i]);
        }
        return result;
    }
}   
public class InputTest {
    public static void main(String[] args) throws IOException {
        int c;
        InputStream in=new LowerCaseInputStream(new BufferedInputStream(new FileInputStream("test.txt")));
        while ((c=in.read())>=0){
            System.out.print((char)c);
        }
        in.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值