好了,昨天我们说完了单利模式,趁着现在想写博客就多写几篇吧.
下面开始说这个装饰模式
装饰模式其实还有做成一个类,一个类的不断的继承,从而实现功能(装饰)的加强,不过这样做太复杂,
同时耦合性太高,为了加一次功能就需要一个新类继承一次.
我们要不断的往饼上加肉或者加蛋的,毕竟加了肉和蛋更好吃.哈哈
代码如下:
//一个饼的抽闲类
abstract class Bing{
public abstract double
price();//价格
public abstract String name();//名字
public void product(){
System.out.println("生产的饼,名字是"
+name()+",价格是"+price());
}
}
//炊饼 class ChuiBing extends Bing { @Override public double price() { return 1.0; } @Override public String name() { return "炊饼"; } }
//老婆饼 class LaopaoBing extends Bing { @Override public double price() { return 2.6; } @Override public String name() { return "老婆饼"; } }
下面就开始给炊饼加蛋了
//炊饼加个蛋,记为炊饼1 class Egg1 extends ChuiBing{ //加个在原来的基础上1 @Override public double price() { return super.price()+1.0; } @Override public String name() { return super.name()+"加了蛋"; } }
老板,再加个蛋
//炊饼1上继续加蛋,只能继续继承炊饼1 class Egg2 extends Egg1{ //加个在原来的基础上1 @Override public double price() { return super.price()+1.0; } @Override public String name() { return super.name()+"加了蛋"; } }
如果再继续加肉的话,需要继续往上继承,非常的复杂.以后的维护非常的困难.
而如果我们使用装饰模式,就能够很方便的添加新的功能(装饰),得到很多加了肉又加了单的饼了.
//加个鸡蛋的装饰类 class EggDecorate extends Bing{ private Bing b; public EggDecorate(Bing b) { this.b = b; } @Override public double price() { return b.price()+0.5; } @Override public String name() { return b.name()+"加了个鸡蛋"; } }
//加肉的装饰类 class MeatDecorate extends Bing{ private Bing b; public MeatDecorate(Bing b) { this.b = b; } @Override public double price() { return b.price()+1.0; } @Override public String name() { return b.name()+"加了肉"; } }
//测试方法
public static void main(String[] args){ //使用加蛋的来装饰炊饼 EggDecorate ed=new EggDecorate(new ChuiBing()); ed.product(); //继续使用加蛋,来装饰刚才的对象 EggDecorate decorate = new EggDecorate(ed); decorate.product(); }
通过这种方法,我们就能够随意的进行装饰了,得到解耦合的目的,同时,维护一起也会更加的方便.
装饰模式的关键是装饰类持有基类的对象,同时继承基类,在构造函数中进行初始化,表示要进行装饰的对象,对这个对象进行装饰,继承基类,就能够进行方法的重写,外面就是调用重写过的方法,而外面的外用没有任何的感觉.
我们只需要对这个对象在原来的基础上直接进行添加新的装饰就可以了.从整体上看解耦,同时也没有改变原来对象
的方法,有点像切面.
关于装饰模式,在java的IO中有很好的使用,官方封装的非常好.
这是java 的IO的部分,下面的BufferedInputStream 就是一个常用的读取的缓存包装类,其构造函数中需要InputStream 这是读入的基类,相当于上面的Bing,所以能够对其他的一些需要的子类进行包装.
这就是我的一点理解,如有错误,请指正.谢谢
2017年8月21日19:33:48