码迷,mamicode.com
首页 > 编程语言 > 详细

Java装饰器模式

时间:2016-04-25 17:40:14      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:

某一个商店卖咖啡,咖啡有很多种,不管以后它变成什么,刚开始它都来自于一杯普通的咖啡,我们把这个Coffee设置成一个接口,它有两种方法:说明它是什么咖啡,以及它卖多少钱。

public interface Coffee {
    public void getDescription();
    public void cost();
}

现在我们开始设计其他咖啡,如加了牛奶的咖啡,加了巧克力的咖啡等等。

咖啡可以有各种各样的调料,根据调料的不同,最后咖啡的种类就不同,能卖多少钱也就不同。

假设有三种调料,他们可以随意搭配,那么可以产生7种咖啡。

这时候可以把每一种都单独设置成一个类。

那么假如有4种调料

会有16种。。。

诸如此类,如果把每一种咖啡都设计成一个类,会出现类"类爆炸"。

这时候,可以使用装饰器模式完成这些需求。

装饰器模式分为以下几个角色:

抽象产品角色

具体产品类角色

抽象装饰器角色

具体装饰器角色

直接上代码:

抽象产品类,它是其他三种角色的爸爸,咖啡,牛奶,糖水等都需要继承它。

public abstract class Beverage {
    public void cost() {
    }
}

抽象装饰类,它的子类是具体的装饰类,如添加牛奶,添加糖水之类的。 

public abstract class CondimentDecorator extends Beverage {
}

具体产品类

public class PureCoffee extends Beverage {
    public void cost() {
        System.out.println("Buy coffee!");
        System.out.println("6-RMB!");
    }
}

这个具体产品可以加糖水,也可以加牛奶,在这种场景下,先添加糖水还是牛奶是没有区别的。

具体装饰类(糖水和牛奶)

牛奶装饰器

public class Milk extends CondimentDecorator {
    Beverage beverage;

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

    public void cost() {
        beverage.cost();
        System.out.println("Add new condiment:milk");
        System.out.println("9-RMB");
    }
}

糖水装饰器

public class Sugar extends CondimentDecorator {
    Beverage beverage;

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

    public void cost() {
        System.out.println("Add new condiment:sugar");
        System.out.println("5-RMB!");
    }
}

测试

public class BeverageTest {
    @Test
    public void test(){
        PureCoffee pureCoffee = new PureCoffee();
        Beverage beverage = new Milk(pureCoffee);//添加牛奶
        beverage.cost();
        beverage = new Sugar(beverage);//添加糖水
        beverage.cost();
    }
}
//Buy coffee!
//6-RMB!
//Add new condiment:milk
//9-RMB
//Add new condiment:sugar
//5-RMB!

在Java IO中使用的就是这种设计模式

可以通过继承FilterInputStream这个抽象装饰角色,实现一个具体的装饰角色Lower,用来装饰FileInputStream这个具体产品,他们的爸爸都是InputStream抽象产品)。

public class Lower extends FilterInputStream {//具体装饰角色

    public Lower(InputStream in) {
        super(in);
    }

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

}

 测试:

    @Test
    public void test1() throws IOException {
        int c;
        InputStream in = new Lower(new BufferedInputStream(new FileInputStream("/Users/roomy/Desktop/1.txt")));

        while ((c = in.read()) >= 0) {
            System.out.print((char)c);
        }
        in.close();
    }
//YDSOFJFsfsafa
//ydsofjfsfsafa

以上:)

 

参考资料:

Head First 设计模式

Java装饰器模式

标签:

原文地址:http://www.cnblogs.com/zhangxd-stn/p/dp1.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!