
如果你前面开发出来的一些类,已经很稳定了。那么在后期做功能扩展时,直接去修改原有的类的话,就很容易引入新的bug。你可以用继承的方式去扩展,但是有可能会引起类在数量方面的暴增,如下面这个例子。其实,你可以用装饰者模式来完成,即不会影响原有的类,也不会引起类的暴增,还可以随意嵌套,因为里面可以递归调用。
装饰者模式就是动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。举个咖啡的例子:
你卖四种咖啡,分别是综合型咖啡(8元)、深焙咖啡(10元)、低咖啡因咖啡(7元)、浓缩咖啡(12元),配料方面有牛奶(2元)、摩卡(3元)、豆浆(1.5元)、奶泡(1元)。每种咖啡可以与1到4种配料搭配,就可以产生不同的咖啡。如果只考虑每种配料只能加一次,那至少也得从每种咖啡派生出14个子类,四种咖啡,共64个子类。如果还有新的配料进来呢?那就得派生更多的子类,造成类数量的暴增。所以用装饰者就可以解决这种问题。
装饰者模式:
1、抽取各种咖啡的共性部分。
public abstract class Coffee {
String description = "Unknown Coffee";
public String getDescription(){
return description;
}
public abstract double cost();
}
2、实现一种咖啡:浓缩咖啡,其他几种依次类推
public class Espresso extends Coffee {
public Espresso(){
description = "Espresso";
}
@Override
public double cost() {
return 12;
}
}
3、抽取所有的装饰器的共同部分,
public abstract class CondimentDecorator extends Coffee {
public abstract String getDescription();
}
4、实现一种配料,其他配料依次类推,里面一定要有对被修饰对象引用的持有,因为在嵌套时,递归调用要这通过此来完成。
public class Mocha extends CondimentDecorator {
Coffee coffee;
public Mocha(Coffee coffee){
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription()+",Mocha";
}
@Override
public double cost() {
return 3+coffee.cost();
}
}
5、开始供应咖啡
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//爱怎么搭配都行,里面会递归调用。
Espresso espresso = new Espresso();
Coffee coffee1 = new Mocha(espresso);
Coffee coffee2 = new Mocha(coffee1);
Coffee coffee3 = new Whip(coffee2);
Toast.makeText(this,coffee3.cost()+"",Toast.LENGTH_LONG).show();
}
}
装饰者模式不涉及修改父类的任何东西,避免了新bug的引入。
RecyclerView没有像ListView那样提供headerView。本质上headerView就是RecyclerView里的一个ItemView,那么我们先加呢个item再加列表就可以解决我们的问题了。这里就不展示代码了。
代码地址:https://github.com/wongkyunban/TestDecorator
欢迎关注公众号:山楂干Linux





