面试官问:代理模式和装饰者模式有啥区别
今天面试聊到了模式。面试官问:装饰者模式了解吗,讲一下?我:blabla...面试官:那代理模式呢?我:blabla.....(说完感觉怎么都一样呢)果然,面试官又问了:那两者有什么区别呢?我: ....懵.........懵.........懵.........懵.........首先呢来看一下定义。一、代理模式代理模式:为其他对象提供一种代理以控制对这个对象的访问。代理模式是一项基本的设计技巧
今天面试聊到了模式。
面试官问:装饰者模式了解吗,讲一下?
我:blabla...
面试官:那代理模式呢?
我:blabla.....(说完感觉怎么都一样呢)
果然,面试官又问了:那两者有什么区别呢?
我: ....懵.........懵.........懵.........懵.........
首先呢来看一下定义。
一、代理模式
代理模式:为其他对象提供一种代理以控制对这个对象的访问。代理模式是一项基本的设计技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上也采用了代理模式。
在代理模式中主要包含三个角色:
- 抽象主题角色Subject:是真实主题和代理主题的共同接口,以便在任何可以使用真实主题的地方都可以使用代理主题。
- 代理主题角色Proxy Subject:也叫做委托类、代理类,该角色负责控制对真实主题的引用,负责在需要的时候创建或删除真实主题对象,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
- 真实主题角色Real Subject:也叫做被委托角色、被代理角色,是业务逻辑的具体执行者。
二、装饰者模式
装饰者模式:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式比生成子类更为灵活。
装饰模式有以下4个角色。
- 抽象构件(Component)角色:该角色用于规范需要装饰的对象(原始对象)。
- 具体构件(Concrete Component)角色:该角色实现抽象构件接口,定义一个需要装饰的原始类。
- 装饰(Decorator)角色:该角色持有一个构件对象的实例,并定义一个与抽象构件接口一致的接口。
- 具体装饰(Concrete Decorator)角色:该角色负责对构件对象进行装饰。
三、区别
从定义上看似乎能够回答面试官的问题,一个是用于实现访问控制,一个是增加功能。可是。。访问控制是什么,增加功能又是怎么样的?到底啥是佩琪,还是要搞清楚些,看一些具体的例子来了解下。
3.1 访问控制 -- 代理模式
// 抽象主题
interface AbstractSubject{
void doAction();
}
// 真实主题
class RealSubject implements AbstractSubject{
@Override
public void doAction() {
System.out.println(" Real Action ");
}
}
// 代理主题
class ProxySubject implements AbstractSubject{
private AbstractSubject subject;
public ProxySubject(){
this.subject = new RealSubject();
}
@Override
public void doAction() {
System.out.println(" Before Proxy do Action");
subject.doAction();
System.out.println(" Before Proxy do Action");
}
}
// 客户端
public class Client{
public static void main(String[] args) {
AbstractSubject subject = new ProxySubject();
subject.doAction();
}
}
3.2 功能扩展 -- 装饰者模式
// 抽象构件
interface Human{
void eat();
}
// 具体构件
class Baby implements Human{
@Override
public void eat() {
System.out.println("Baby eating");
}
}
// 装饰角色
class Guardian implements Human{
private Human human;
public Guardian(Human h){
human = h;
}
@Override
public void eat() {
human.eat();
}
}
// 具体装饰角色
class Parent extends Guardian{
public Parent(Human h) {
super(h);
}
@Override
public void eat() {
System.out.println("Wash hands for baby");
super.eat();
}
}
// 客户端
Baby baby = new Baby();
Human human = new Parent(baby);
human.eat();
四、总结
等待,看完例子怎么感觉又似懂非懂了呢。不是说一个控制访问,一个增强功能吗,为什么都是中间类和目标类实现了相同的接口,在调用目标类时增加了自己的方法呢?好像确实又懵了。
其实,代理模式的访问控制主要在于对目标类的透明访问,也就是说我们不需要知道目标类的具体情况,只需要知道代理类可以帮助我们完成想要的功能就对了;而对于装饰者模式,我们是有一个目标类的对象的,比如例子中的baby,这个对象可以完成特定的功能(eat),但是不能满足我们的要求,所以需要对其进行增强(饭前洗手)。
也就是说,在代理模式中,目标类对于客户端是透明的,由代理类隐藏其具体信息并响应客户端请求;而装饰者中客户端对特定的目标类对象进行增强。所以,代理类与真实对象的关系常在编译时就确定,而装饰者在运行时递归构造。
----------
终于搞明白了这两个相似的设计模式的关系,好像智商又占领了高地,就是脚有点麻 ------
更多推荐
所有评论(0)