一、装饰模式
1、装饰模式的定义
“动态地给对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活”。因此,装饰模式的目的是增加功能,而且是对某一类增加功能,通过持有不同的子类实例,来对不同的子类实现增强,从而比生成不同的子类来获取增加了功能的类来说更加灵活。
2、装饰模式结构图
Component是定义的需要动态添加功能的一个对象接口,ConcreteComponent是实现了Component的一个具体对象。Decorator是装饰器抽象类,继承了Component,以此来扩展Component类的功能,ConcreteDecorator就是具体的装饰对象,真正起到给Component添加功能的作用。
Component类:
public interface Component{
public void operation();
}
ConcreteComponent类:
public class ConcreteComponent implements Componnet{
@Override
public void operation(){
System.out.println("具体对象的操作");
}
}
Decorator类:
public abstract class Decorator implements Component{
private Component component;
public void setComponent(Component component){
this.component = component;
}
@Override
public void operation(){
if(component != null){
component.operation();
}
}
}
ConcreteDecoratorA类:
public class ConcreteDeacoratorA extends Decorator{
private void enhanceCode(){
System.out.println("增强代码A");
}
@Override
public void operation(){
super.operation();
enhanceCode();
}
}
装饰模式利用setComponent来对具体对象进行包装,每个装饰类只需关心自己的功能。
3、装饰模式总结
在系统需要新功能的时候,普通的做法是向旧类方法中添加新的代码,例如新的字段、新的方法,从而增加了旧类的复杂性。而这些新加入的功能可能只是在某些特定情况想才会去使用执行,例如为一个类增加同步功能,但并不是任何场景下都需要同步功能,这时灵活性就大大降低,因此在jdk中使用了Collections.synchornizedList()等方法来为对应的类进行包装,只在需要的时候这么做即可。
并且由于装饰器也是Component,因此各装饰器之间可以链式的set装饰器,从而有序的增加多个功能。
ConcreteDecoratorB类:
public class ConcreteDeacoratorB extends Decorator{
private void enhanceCode(){
System.out.println("增强代码B");
}
@Override
public void operation(){
super.operation();
enhanceCode();
}
public static void main(String[] args) {
Component component = new ConcreteComponent();
Decorator decorator = new ConcreteDecorator();
Decorator decoratorB = new ConcreteDecoratorB();
decorator.setComponent(component);
decoratorB.setComponent(decorator);
decoratorB.operation();
}
}
输出:
具体对象的操作
增强代码A
增强代码B
二、代理模式
1、代理模式的定义
“为其他对象提供一种代理以控制对这个对象的访问”。因此,代理模式重在控制对目标对象的访问。不能直接访问目标对象,而是需要代理对象来达到访问的目的。这就增加了一定程度的间接性,也因为这种间接性,可以附加多种用途。
2、代理模式结构图
Subject类:
Subject类是RealSubject和Proxy的父接口,因此在任何使用RealSubject的地方都可以使用Proxy进行替代。
public interface Subject{
public void request();
}
RealSubject类:
RealSubject类是需要访问控制的具体被代理类
public class RealSubject implements Subject{
@Override
public void request(){
System.out.println("RealSubject request");
}
}
Proxy类:
Proxy即代理类。
public class Proxy implements Subject{
RealSubject realSubject;
@Override
public void request(){
if(realSubject == null){
realSubject = new RealSubject();
}
realSubject.request();
}
public static void main(String[] args){
Proxy proxy = new Proxy();
proxy.request();
}
}