前言
笔者在学习装饰者模式的时候感觉其与静态代理模式有点相似,本文主要介绍了什么是装饰者模式,什么是静态代理,二者之间有什么异同。
装饰者模式
什么是装饰者模式
装饰着模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰者模式比生成子类更加灵活
怎样实现装饰者模式
装饰者模式类图如下:
Component类:
public abstract class Component {
public abstract void operation();
}
ConcreteComponent类:
public class ConcreteComponent extends Component {
@Override
public void Operation() {
System.out.println("具体对象的操作");
}
}
Decorator类:
public abstract class Decorator extends Component{
protected Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
if (component != null){
component.operation();
}
}
}
ConcreteDecoratorA类:
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
@Override
public void operation() {
super.operation();
System.out.println("具体修饰对象A的操作");
}
}
ConcreteDecoratorB类:
public class ConcreteDecoratorB extends Decorator{
public ConcreteDecoratorB(Component component) {
super(component);
}
@Override
public void operation() {
super.operation();
System.out.println("具体装饰对象B操作");
}
}
客户端代码:
public class Client {
public static void main(String[] args) {
ConcreteComponent concreteComponent = new ConcreteComponent();
ConcreteDecoratorA a = new ConcreteDecoratorA(concreteComponent);
a.operation();
System.out.println("====================");
ConcreteDecoratorB b = new ConcreteDecoratorB(a);
b.operation();
}
}
输出结果:
具体对象的操作
具体修饰对象A的操作
====================
具体对象的操作
具体修饰对象A的操作
具体装饰对象B操作
静态代理
什么是静态代理
代理模式:在某些情况下,一个对象不适合或者不能直接引用另一个对象,需要代理对象在客户类和目标对象之间起到中介的作用。
静态代理:代理类在程序运行前就已经定义好,其与目标类的关系在程序运行前就已经确定。静态代理类似于企业与企业的法律顾问间的关系。法律顾问与企业的代理关系,并不是在“官司”发生后才建立的,而是之前就确立好的一种关系。
怎样实现静态代理
静态代理的类图如下所示:
通过类图我们可以很快的写出代码:
接口类:
public interface IUserDao {
public void save();
}
目标对象:
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("保存数据");
}
}
静态代理对象:(需要与被代理的对象实现同一接口即:IUserDao)
public class UserDaoProxy implements IUserDao{
private IUserDao target;
public UserDaoProxy(IUserDao target) {
this.target = target;
}
@Override
public void save() {
System.out.println("开启事务");//扩展了额外功能
target.save();
System.out.println("提交事务");
}
}
测试类:
import org.junit.Test;
public class StaticUserProxy {
@Test
public void testStaticProxy(){
//目标对象
IUserDao target = new UserDao();
//代理对象
UserDaoProxy proxy = new UserDaoProxy(target);
proxy.save();
}
}
输出结果:
开启事务
保存数据
提交事务
区别与联系
相同点:
- 装饰者类与目标类要求实现同一接口;静态代理类与目标类要求也实现同一接口。
- 装饰者类与静态代理类都可以实现增强目标类的功能。
- 装饰者类与静态代理类中都具有目标类的引用,目的都是为了在其中调用目标类的方法。
不同点
- 装饰者设计模式就是为了增强目标类;静态代理设计模式是为了保护和隐藏目标对象, 让客户类只能访问代理对象,而不能直接访问目标对象。
- 装饰者类中的目标类的引用是通过带参构造器传入的;静态代理类中的目标类的引用, 一般都是在代理类中直接创建的,目的就是为了隐藏目标对象。
- 装饰者基类一般不对目标对象进行增强,而是由不同的具体装饰者进行增强的,且这 些具体的装饰者可以形成增强链,对目标对象进行连续增强。静态代理类会直接对目标对象 进行增强,需要哪些增强的功能,一次性在静态代理类中完成,没有增强链的概念。