前言:这篇文章本来应该在昨天就应该写好的,因为我的惰性,拖到今天才把它总结好。昨天看了一本关于品牌营销的电影——《模范家庭》。在电影中几个主角被雇佣在一个高档的小区假装成一个模范的家庭,他们被品牌商提供他们最新的高端产品,他们的任务就是在这个高端小区中向邻居展示他们使用的最新的高端产品,并通过口碑营销的方式,潜移默化的说服邻居去购买和使用该产品。
在邻居眼里,他们这个家庭似乎高贵、富裕、并十分有爱。邻居们羡慕他们的生活,并开始尝试购买他们使用过得产品,好像通过使用他们使用的产品,他们也会变成他们渴望的那个样子。
这部电影让我感受到了口碑营销的能力,并在生活中,我们有多少的购物选择是在身边朋友的影响下对我们的购物选择产生影响的?当我们有时候去超市只是为了买一瓶水,如果我们身边的朋友给我们推荐一款新的上市的饮料,并对我们说这个饮料十分好喝,保证你喝了一次会再想尝试的,说着他就拿起了一瓶,去柜台结账。这个时候你可能就会被他的话语影响,可能你在刚开始只想解渴买一瓶水,结果你买了一瓶没有水更解渴的饮料。
装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
装饰者模式在Android中其实并不少见,在日常开发中,我们经常会继承一些Adapter然后在此基础上拓展一些新的方法和功能。
接下来我们就通过一个奶茶店的案例来了解一下装饰者模式,同样这个案例来自于Head First 设计模式,但我把例子更加简洁化了,为了能够让自己和读者阅读的时候能够快速理解装饰者模式的使用和精髓。
案例:我们经常会去一点点(强势插入广告)喝奶茶,我们会在点一杯奶茶后,在奶茶中加入一些辅料,类似奶泡、仙草之类的东西。那比如现在我们要帮一点点奶茶设计一个点单系统,你会怎么设计。
如果在学习装饰者模式之前,你可能会这样设计:
一个奶茶饮料的接口,所有奶茶都继承这个接口。
然后我们拿乌龙奶茶举例,我们可能会设计出这么多类:WuLongTea、WuLongTeaWithMesona(乌龙奶茶加仙草)、WuLongTeaWithPudding(乌龙奶茶加布丁)、WuLongTeaWithMesonaAndPudding(乌龙奶茶加仙草和布丁).......等等的类。
这样设计的确好像没什么问题,但是如果一杯乌龙奶茶加一些辅料,我们要设计出几十种类,那换成四季青奶茶等等其他奶茶,我们设计的这个点单系统简直就是类爆炸,当我们想去维护的时候,也会十分不易于维护、拓展性太差了。
这时候我们就可以使用我们的装饰者模式来帮助我们设计这么一个系统。
首先我们来设计一个我们的饮料接口,所有的饮料都要实现这个饮料接口:
package com.example.decoratorpattern;
/**
* Created by Vicky on 2016/10/29.
*/
//饮料的抽象类
public abstract class Beverage {
String description="Unknown Beverage";
public String getDescription(){
return description;
}
//返回价格
public abstract double cost();
}
接着我们来实现一杯我们的乌龙奶茶:
package com.example.decoratorpattern;
/**
* Created by Vicky on 2016/10/30.
*/
//乌龙奶茶
public class WuLongTea extends Beverage{
@Override
public double cost() {
return 10;
}
public WuLongTea(){
description="乌龙奶茶";
}
}
这样我们就完成了一杯乌龙奶茶的类。那接着我们可能就需要在乌龙奶茶上添加我们的辅料,并根据动态添加的辅料来获得我们的总价。
package com.example.decoratorpattern;
/**
* Created by Vicky on 2016/10/29.
*/
//辅料类
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();
}
我们来设计我们的辅料仙草和布丁类:
package com.example.decoratorpattern;
/**
* Created by Vicky on 2016/10/30.
*/
public class Mesona extends CondimentDecorator{
private Beverage beverage;
public Mesona(Beverage beverage){
this.beverage=beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+"+仙草";
}
@Override
public double cost() {
return beverage.cost()+2;
}
}
package com.example.decoratorpattern;
/**
* Created by Vicky on 2016/10/30.
*/
public class Pudding extends CondimentDecorator{
private Beverage beverage;
public Pudding(Beverage beverage){
this.beverage=beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+"布丁";
}
@Override
public double cost() {
return beverage.cost()+3;
}
}
好了,这样我们就完成了我们的装饰者类,我们来调用试试看是否正常运行:
Mesona mesona=new Mesona(wuLongTea);
Pudding pudding=new Pudding(mesona);
Log.d("YWK",pudding.getDescription());
Log.d("YWK","总价为:"+pudding.cost());
结果为:
10-30 14:05:42.269 23412-23412/com.example.decoratorpattern D/YWK: 乌龙奶茶+仙草布丁
10-30 14:05:42.269 23412-23412/com.example.decoratorpattern D/YWK: 总价为:15.0
可以看出我们的代码正常运行了。
这里在总结下,装饰者模式其实就是先设计一个接口或者抽象类(Beverage),然后实现该接口或者抽象类(WulongTea),在日后可能我们需要动态的为这个接口添加一些职责和功能的时候,我们只需讲动态添加的职责和功能设计成类并继承或者实现之前的抽象类或者接口(Pudding、Mesona),然后包裹之前的实现类。这样我们就能在之前的实现类基础上,动态的为其添加一些职责和功能,具有更好的拓展性。