装饰着模式用到最多的地方也就是io流:
首先需要知道装饰着模式有几个角色需要了解:
抽象构建角色:被装饰类的实现的接口;
具体构建角色:被装饰的类;
抽象装饰角色:装饰类的实现接口,接口中有被装饰类接口的引用;实现了抽象构建角色;
具体装饰角色:装饰被装饰的类,在这个类实现了抽象装饰角色;
整个装饰模式的理念:首先肯定需要有一个被装饰者角色,那么必然需要有装饰者,不然被装饰者谁来装饰。所以在装饰者中必然需要有被装饰者的引用。所以有面向接口的编程来解决;被装饰的类实现抽象构建角色,;装饰类实现抽象装饰角色;抽象的装饰角色实现抽象构建角色。那么在装饰者类中实例化对象的时候传的参数就是被装饰的类的实例。然后传给抽象装饰角色。在装饰者类中重写抽象装饰角色中重写的抽象构建角色中的方法。在方法中调用父类的改方法,并且可以增加功能。
具体查看代码:
抽象构建角色:
public interface Component
//这个相当于是那个抽象构建角色:被装饰的接口
{
public void doSomething();
}
具体构建角色:目的就是在这个功能上在增加功能,让自身感受不到
public class ConcreteComponent implements Component
//这个是具体的构件角色;//被装饰的角色
{
@Override
public void doSomething()
{
System.out.println("功能a");
}
}
抽象装饰角色:
public class Decorator implements Component
//抽象的装饰角色,这个和构件角色实现的是同一个接口
{
private Component component;
public Decorator(Component component)
{
this.component = component;
}
@Override
public void doSomething()
{
component.doSomething();
}
}
具体装饰者角色:
public class ConcreteDecorator2 extends Decorator
//这个是具体的装饰角色
{
public ConcreteDecorator2(Component component)
{
super(component);
//这个构造方法里面就把这个component这个传给了父类。然后调用方法也是调用这个父类的方法。那么也就是具体构建角色需要做这个事情还是会做自己的事情
//然后在这个原本具体构建角色需要做的基础上加上包装的功能。
}
@Override
public void doSomething()
{
// this.doAnotherThing();
super.doSomething();//这个里面的这个方法,其实就是ConcreteComponent这个里面的doSomething方法
this.doAnotherThing();
//这里调用的方法还是那个a功能,同时在这个里面增添了一个功能b
}
private void doAnotherThing()
{
System.out.println("功能B");
}
}
具体装饰者角色:
public class ConcreteDecorator3 extends Decorator
//这个也是具体的装饰角色,在装饰角色中增添了自己的方法
{
public ConcreteDecorator3(Component component)
{
super(component);
}
@Override
public void doSomething()
{
super.doSomething();//这个里面的方法其实就是ConcreteDecrator2里面的都Something()方法,
//又因为咱们在实例化ConCreteDecrator对象的时候传进去的参数是ConcreteConponent这个对象的引用,所以最终
//还是ConcreteConponent里面的方法
this.doAnotherThing();
//这个里面还是使用的那个具体构建角色里面的a功能,然后再这个基础上增添自己的一个c功能
}
private void doAnotherThing()
{
System.out.println("功能c");
}
}
客户端测试类:
public class Client
{
public static void main(String[] args)
{
//节点流
Component component = new ConcreteComponent();
//过滤流
Component component2 = new ConcreteDecorator2(component);
component2.doSomething();
System.out.println("-----------------------");
//过滤流
Component component3 = new ConcreteDecorator3(new ConcreteDecorator2(component));
//整个的执行机制就可以知道该怎么做,首先new ConcreteDecorator3()对象的时候先调用new ConcreteDecorator2,所以先
//构建ConcreteDecorator2,但是构建ConcreteDecorator2会调用super(),那么构建父类Decorator对象的时候就把这个参数
//component传进去了,。然后构建完对象后,调用doSomething()这个方法,这个时候虽然会检查父类有没有这个方法,有,但是在每一个类中
//都对父类进行了调用。所以调用ConcreteDecorator3前会去ConcreteDecorator2中调用,ConcreteDecorator2前会去
//Decorator中调用,Decorator中才是正真的调用new ConcreteComponent();的doSomethingn()。然后再去调用
//ConcreteDecorator2中的再加一些功能。再ConcreteDecorator3中的功能,再加一些功能。
//所以这种装饰是先执行最里面的功能。然后加上上一层,然后上一层。
component3.doSomething();
}
}
FileReader fr = new FileReader("D:/FileReader1.java");
BufferedReader br = new BufferedReader(fr);
String string;
while(null != (string = br.readLine()))
//一行一行的读取出来
{
System.out.println(string);
}
br.close();
这个例子就是io流中的,对于一个字符的流FileRead进行包装(装饰),对于FileRead的功能是不变了,但是为了用户的操作方便,包装了一层BufferReader缓冲功能。
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\test.txt");););
bw.write("http://www.google.com");
对于一个字节流进行包装一个字节字符转化流。在包装一层缓冲流。方便用户的操作,但是对于字节流FileOutputStream他自身不知道具体情况,还是做自己的本分工作;