参考程杰《大话设计模式》
装饰模式
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。
Component是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator装饰抽象,继承Component,从外类来扩展Component功能,但对于Component来说,是无需知道Decorator的存在的。ConcreteDecorator是具体装饰对象,起到给Component添加职责功能。
装饰模式特点
- 装饰模式利用setComponent方法对对象进行包装,每个装饰对象的实现和如何使用这个对象分离开,装饰对象只关心实现自己的功能。
- 如果一个ConcreteComponent类没有继承抽象类或接口,那么Decorator类可以是ConcreteComponent的子类。如果只有一个ConcreteDecorator类,那也没必要有Decorator类。
- 把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此当要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象。
实例
要被动态添加职责的对象
//需要被添加职责的对象
public interface Component {
public void operation();
}
//需要被添加职责的对象的实现类
public class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("具体Component对象做的事情");
}
}
装饰类
//装饰类
public abstract class Decorator implements Component{
protected Component component;
public void setComponent(Component component) {
this.component = component;
}
@Override
public void operation() {
if (!Objects.isNull(component)){
this.component.operation();
}
}
}
//具体不同的装饰类实现类
public class ConcreteDecoratorA extends Decorator{
@Override
public void operation() {
functionA();
super.operation();
}
private void functionA(){
System.out.println("Decorator A 独有的方法");
}
}
//具体不同的装饰类实现类
public class ConcreteDecoratorB extends Decorator{
@Override
public void operation() {
super.operation();
functionB();
}
private void functionB(){
System.out.println("Decorator B 独有的方法");
}
}
使用
public class TestdemoApplication {
public static void main(String[] args) {
Component component = new ConcreteComponent();
ConcreteDecoratorA decoratorA = new ConcreteDecoratorA();
ConcreteDecoratorB decoratorB = new ConcreteDecoratorB();
decoratorA.setComponent(component);
decoratorB.setComponent(component);
decoratorA.operation();
decoratorB.operation();
}
}
输出结果
代理模式
为其他对象提供一种代理以控制对这个对象的访问。
代理模式使用场景
远程代理,也就是为一个对象在不同地址空间提供局部代表。可以隐藏一个对象存在于不同地址空间的事实
虚拟代理,根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。
安全代理,用来控制真实对象的访问权限。
智能指引,指当调用真实对象时,代理处理另外一些事。
代理模式在Java中非常常见,比如spring中的AOP。
public interface Subject {
void request();
}
//真实的类
public class RealSubject implements Subject{
@Override
public void request() {
System.out.println("真实的请求");
}
}
//代理类
public class Proxy implements Subject{
private Subject subject;
@Override
public void request() {
if (Objects.isNull(this.subject)){
this.subject = new RealSubject();
}
System.out.println("做一些其他事情");
this.subject.request();
}
}
使用
public class TestdemoApplication {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.request();
}
}