设计模式--装饰器模式
设计模式--装饰器模式
1 概述
1.1 定义
装饰器模式(Decorator Design)动态的扩展一个对象的功能。论扩展功能而言,装饰器提供了比继承更有弹性的替代方案。
1.2 应用
JDK中的java.io包就使用的装饰器来扩展IO接口。
1.2 类图
- Component抽象组件角色:定义我们最核心的抽象对象。
- ConcreteComponent具体组件角色:定义最核心抽象对象的实现,你要装饰的对象就是它。
- Decorator装饰角色:装饰的抽象对象,其有一个私有的变量指向Component抽象组件。
- ConcreteDecorator具体装饰角色:具体的装饰对象,用来装饰组件。
2 详解
Component 抽象构件
1 public abstract class Component { 2 // 抽象方法 3 public abstract void operate(); 4 }
ConcreteComponent 具体构件-->你要装饰的具体对象
1 public class ConcreteComponent extends Component { 2 @Override 3 public void operate() { 4 System.out.println("ConcreteComponent.operate()"); 5 } 6 }
Decorator 抽象的装饰者-->需要接受一个具体的需要被装饰的对象
1 public abstract class Decorator extends Component { 2 private Component component; 3 4 // 通过构造函数传递被装饰者 5 Decorator(Component component) { 6 this.component = component; 7 } 8 9 // 委托被装饰者执行 10 @Override 11 public void operate() { 12 component.operate(); 13 } 14 }
ConcreteDecoratorA、ConcreteDecoratorB 具体的装饰者
1 public class ConcreteDecoratorA extends Decorator { 2 // 定义被被装饰者 3 ConcreteDecoratorA(Component component) { 4 super(component); 5 } 6 7 // 重写父类的operate方法, 以用来定义自己的装饰行为 8 @Override 9 public void operate() { 10 System.out.println("ConcreteDecoratorA do some operate"); 11 super.operate(); 12 } 13 } 14 15 public class ConcreteDecoratorB extends Decorator { 16 // 定义被装饰者 17 ConcreteDecoratorB(Component component) { 18 super(component); 19 } 20 // 重写父类的operate方法,以用来定义自己的装饰行为 21 @Override 22 public void operate() { 23 System.out.println("ConcreteDecoratorB do some operate"); 24 super.operate(); 25 } 26 }
测试
1 public class Client { 2 public static void main(String[] args) { 3 Component component = new ConcreteComponent(); 4 component.operate(); 5 System.out.println("-------------------------------------"); 6 // 使用ConcreteDecoratorA装饰原对象 7 Component component1 = new ConcreteDecoratorA(component); 8 component1.operate(); 9 System.out.println("-------------------------------------"); 10 // 使用ConcreteDecoratorB装饰原对象 11 Component component2 = new ConcreteDecoratorB(component); 12 component2.operate(); 13 System.out.println("-------------------------------------"); 14 // 先使用ConcreteDecoratorA装饰对象,再使用ConcreteDecoratorB装饰对象 15 Component component3 = new ConcreteDecoratorB(new ConcreteDecoratorA(component)); 16 component3.operate(); 17 } 18 }output: 19 ConcreteComponent.operate() 20 ------------------------------------- 21 ConcreteDecoratorA do some operate 22 ConcreteComponent.operate() 23 ------------------------------------- 24 ConcreteDecoratorB do some operate 25 ConcreteComponent.operate() 26 ------------------------------------- 27 ConcreteDecoratorB do some operate 28 ConcreteDecoratorA do some operate 29 ConcreteComponent.operate()
3 应用
java.io类包中就是使用了装饰器设计模式来装饰,避免过多的使用继承,但也造成了API繁琐。
自己写的IO装饰者--->UpperCaseInputStream(小写字符转换成大写字符)
1 public class UpperCaseInputStream extends FilterInputStream { 2 3 protected UpperCaseInputStream(InputStream in) { 4 super(in); 5 } 6 7 public int readCharToUpperCase() throws IOException { 8 int c = read(); 9 return c == -1 ? c : Character.toUpperCase(c); 10 } 11 } 12 13 public class Client { 14 public static void main(String[] args) throws Exception { 15 UpperCaseInputStream in = new UpperCaseInputStream( 16 new BufferedInputStream(new FileInputStream("E:\\java\\America.java"))); 17 int c; 18 while((c = in.readCharToUpperCase()) != -1) { 19 System.out.print((char) c); 20 } 21 } 22 }