关闭

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

113人阅读 评论(0) 收藏 举报
分类:

愉快的工作又开始了。Leader安排了一个新的任务,给一个酸奶店的点单软件增加新的功能。
这个程序的原来所有的酸奶都继承于奶酪类(Cheese)

public  abstract class Cheese {
public String name;
public String introduce(){
    return name;
} 
public abstract int price();

所有具体的酸奶继承奶酪类并重写价格price方法,以原味酸奶和宫廷酸奶为例:

public class Original extends Cheese{
    public Original() {
        name="Original";
    }
@Override
    public int  price() {
    return 10;
    }
}
public class Court  extends Cheese{
    public Court() {
        name="Court";
    }
    @Override
    public int price() {
        return 8;
    }
}

这样的话直接调用实现类的introduce和price就可以得到名字和价格了。
但是随着酸奶店的规模越来越大,品种也越来越多,出现了一些新的品种的酸奶和配料,比如:草莓,奥利奥,樱桃。这些配料和酸奶进行搭配然后计算总共的价格和名称。
稍微思考一下,可能会有人选择这样写代码,以原味酸奶加草莓为例:

public class OriginalStrawberry extends Cheese{
    public Original() {
        name="OriginalStrawberry ";
    }
    @Override
    public int  price() {
    return 10;
    }
}

这样看起来,似乎并没有什么不妥,但是仔细想一想,酸奶加配料这样的组合有多少种可能呢?如果每一种可能都要写出来一个类的话,那么简直要类爆炸,并且如果任何一个酸奶或者配料更改了价格的话,那么所有关联类都需要修改,如果顾客想要双倍的草莓呢?或者草莓加樱桃呢?这样写下去简直是反人类的方法。
设计原则之一:类应该对扩展开发,对修改关闭。比如说对于一些我们经过测试没有问题的代码,原则上不应该修改源代码,而应该在源代码基础之上进行扩展。
如果我们这样设计代码是不是更好一点,还是以原味酸奶加草莓为例:我们先把一杯原味酸奶作为主体(被修饰者),用草莓作为修饰者修饰主体。就是先得到一个原味酸奶的对象,用草莓对象修饰它,然后调用price方法将草莓的价钱加上去。
这样的做法可以动态的将奶酪和配料松耦合的搭配在一起。所以先把系统分为奶酪和配料两个部分。

public abstract class Batching extends Cheese {
    public abstract String introduce();
}

草莓的实现类如下:

public class Strawberry extends Batching {
 Cheese cheese;

    public Strawberry(Cheese cheese) {
    this.cheese = cheese;
}

    @Override
    public int price() {
        return(cheese.price()+2);
    }

    @Override
    public String introduce() {
        return(cheese.introduce()+",Strawberry");
    }

}

樱桃的实现类如下:

public class Cherry extends Batching{
     Cheese cheese;

    public Cherry(Cheese cheese) {
        this.cheese = cheese;
    }

    @Override
    public String introduce() {
        return cheese.introduce()+"Cherry";
    }

    @Override
    public int price() {
        return cheese.price()+3;
    }

}

以原味酸奶加草莓为例:

public class Test {
    public static void main(String[] a){
     Cheese cheese=new Original();
     cheese =new Strawberry(cheese);
     System.out.println(cheese.introduce()+cheese.price());
 }
}

输出结果:Original,Strawberry12

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2382次
    • 积分:110
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章分类
    最新评论