装饰者:
当我们需要为某个现有的对象动态增加一个新的功能或职责时,可以考虑使用装饰者模式;
某个对象由于动态增加新的功能或职责,为了避免适应这种变化而增加子类,导致子类膨胀过快;
装饰者模式是在不改变原类文件和使用继承的情况下,动态的扩展一个功能,
它通过创建一个包装对象,通过装饰来包裹真实对象,使用组合的方式对对象进行功能扩展,降低了继承这种强耦合性,做到了对扩展开放,对修改关闭。
示例:
顶级制作面包接口:
public interface IBread {
public void maiMianfen();
public void huoMianfen();
public void zhengMantou();
public void process();
}
正常面包:
public class NormalBread implements IBread {
@Override
public void maiMianfen() {
System.out.println("买面粉..");
}
@Override
public void huoMianfen() {
System.out.println("和面..");
}
@Override
public void zhengMantou() {
System.out.println("蒸馒头..");
}
@Override
public void process(){
this.maiMianfen();
this.huoMianfen();
this.zhengMantou();
}
}
装饰者:
public abstract class DecoratorBread implements IBread {
private final IBread bread;
public DecoratorBread(IBread bread) {
this.bread = bread;
}
@Override
public void maiMianfen() {
System.out.println("买面粉..");
}
@Override
public void huoMianfen() {
System.out.println("和面..");
}
@Override
public void zhengMantou() {
System.out.println("蒸馒头..");
}
@Override
public void process(){
this.maiMianfen();
this.huoMianfen();
this.zhengMantou();
}
}
为了装饰正常面包,我们需要一个和正常面包一样的抽象装饰者,该类和正常面包类一样实现接口IBread,不同的是,该抽象类中包含一个IBread接口类型的私有属性bread成员,通过构造方法,将外部的IBread接口类型对象作为参数传入。
有色面包:
public class DecoratorBreadA extends DecoratorBread {
public DecoratorBreadA(IBread bread) {
super(bread);
}
public void paint(){
System.out.println("添加染色剂。。");
}
@Override
public void huoMianfen() {
this.paint();
super.huoMianfen();
}
}
加糖面包:
public class DecoratorBreadB extends DecoratorBread {
public DecoratorBreadB(IBread bread) {
super(bread);
}
public void paint(){
System.out.println("添加甜蜜剂。。");
}
@Override
public void huoMianfen() {
this.paint();
super.huoMianfen();
}
}
测试类:
public class Test {
public static void main(String[] args) {
IBread normalBread = new NormalBread();
DecoratorBreadA a = new DecoratorBreadA(normalBread);
a.process();
/*normalBread = new DecoratorBreadA(normalBread);
normalBread.huoMianfen();
normalBread = new DecoratorBreadB(normalBread);
normalBread.huoMianfen();
normalBread.process();*/
}
}
输出结果:
买面粉..
添加染色剂。。
和面..
蒸馒头..
结构图如下左:
这个是装饰者模式结构图............,再看io类图:
是不是结构类似,没错,io模块的类正式用了装饰者模式,将上文顶级接口IBread改为用抽象类Bread实现即等同于io模块类。。
FilterInputStream部分源码:
public
class FilterInputStream extends InputStream {
/**
* The input stream to be filtered.
*/
protected volatile InputStream in;
/**
* Creates a <code>FilterInputStream</code>
* by assigning the argument <code>in</code>
* to the field <code>this.in</code> so as
* to remember it for later use.
*
* @param in the underlying input stream, or <code>null</code> if
* this instance is to be created without an underlying stream.
*/
protected FilterInputStream(InputStream in) {
this.in = in;
}
DataInputStream部分源码:
public
class DataInputStream extends FilterInputStream implements DataInput {
/**
* Creates a DataInputStream that uses the specified
* underlying InputStream.
*
* @param in the specified input stream
*/
public DataInputStream(InputStream in) {
super(in);
}
是不是与上文装饰者面包的设计思路如出一辙。
End!