设计模式的装饰器模式和代理模式
装饰器模式
装饰者和被装饰者实现同一个接口,
public interface Coffee {
/**
* 打印当前咖啡里有什么
*/
void printMaterial();
}
定义一个苦咖啡
public class BitterCoffee implements Coffee {
@Override
public void printMaterial() {
System.out.println("咖啡");
}
}
定义一个装饰器“加糖”,来修饰苦咖啡
public class CoffeeDecorator implements Coffee {
/**
* 持有一个咖啡对象
*/
private final Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public void printMaterial() {
System.out.println("糖");
this.coffee.printMaterial();
}
}
打印结果
@Test
public void addSugerIntoCoffee {
Coffee coffee = new BitterCoffee(); // 点了一杯苦咖啡
coffee = new SugarDecorator(coffee); // 给咖啡加了点糖,传入一个对象给装饰器
coffee.printMaterial(); // 糖 咖啡
}
代理模式(静态代理)
public class CoffeeProxy implements Coffee {
private final Coffee coffee;
public CoffeeProxy() {
this.coffee = new BitterCoffee(); // 不需要传入对象,直接在内部生成对象
}
@Override
public void printMaterial() {
System.out.println("糖");
this.coffee.printMaterial();
}
}
打印结果
@Test
public void addSugerIntoCoffee {
Coffee coffee = new CoffeeProxy();
coffee.printMaterial(); // 糖 咖啡
}
装饰器模式和代理模式异同
相同点:装饰者和被装饰者,代理类和被代理类都是实现了同一个接口,都是对原有类的功能进行加强。
区别:装饰器模式关注的是对一个类功能的拓展,而代理模式关注的是对对象的访问控制。
比如说对A对象、B对象进行动态代理,使访问他们之前都去检查是否登录。用代理模式可以对一个类信息进行隐藏,侧重于不能直接访问一个对象,只能通过代理来间接访问,比如对象在另外一台机器上,或者对象被持久化了,对象是受保护的。对象在另外一台机器上,其实就是rpc,感兴趣的可以看看dubbo的源码本地反问的其实就是远程对象的代理,只不过代理帮你做了访问这个对象之前和之后的很多事情,但是对使用者是透明的了。