装饰器模式和代理模式的区别

代理模式和装饰器模式很像,这里用【到咖啡馆喝咖啡】做例子来说解。设计模式

基础实现ide

定义一个咖啡的接口。this

public interface Coffee {
    /**
     * 打印当前咖啡里有什么
     */
    void printMaterial();
}

定义一个苦咖啡的实现。编码

public class BitterCoffee implements Coffee {
    @Override
    public void printMaterial() {
        System.out.println("咖啡");
    }
}

定义一个默认的点咖啡逻辑。spa

@Test
public void orderCoffee {
    Coffee coffee = new BitterCoffee();
    coffee.printMaterial(); // 咖啡
}

装饰器模式设计

你喝了一口咖啡,以为有点苦,因而你就想加点糖。代理

定义一个咖啡装饰器(加糖)。code

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(); // 糖 咖啡
}

装饰器适用场景:我有一个对象,可是这个对象的功能不能使我满意(咖啡太苦了),我就拿装饰器给他装饰一下(给咖啡加糖)。blog

代理模式(静态代理)

约好的朋友来了,要给她点一杯咖啡,你知道咖啡很苦,决定直接点一杯加了糖的咖啡给她。

定义一个加糖咖啡的类。

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(); // 糖 咖啡
}

装饰器和代理模式的区别

对装饰器模式来讲,装饰者(Decorator)和被装饰者(Decoratee)都实现一个接口。对代理模式来讲,代理类(Proxy Class)和真实处理的类(Real Class)都实现同一个接口。此外,不论咱们使用哪个模式,均可以很容易地在真实对象的方法前面或者后面加上自定义的方法。

在上面的例子中,装饰器模式是使用的调用者从外部传入的被装饰对象(coffee),调用者只想要你把他给你的对象装饰(增强)一下。而代理模式使用的是代理对象在本身的构造方法里面new的一个被代理的对象,不是调用者传入的。调用者不知道你找了其余人,他也不关心这些事,只要你把事情作对了便可。

装饰器模式关注于在一个对象上动态地添加方法,而代理模式关注于控制对对象的访问。换句话说,用代理模式,代理类能够对它的客户隐藏一个对象的具体信息。所以当使用代理模式的时候,咱们经常在一个代理类中建立一个对象的实例;当使用装饰器模式的时候,咱们一般的作法是将原始对象做为一个参数传给装饰器的构造器。

装饰器模式和代理模式的使用场景不同,好比IO流使用的是装饰者模式,能够层层增长功能。而代理模式则通常是用于增长特殊的功能,有些动态代理不支持多层嵌套。

代理和装饰其实从另外一个角度更容易去理解两个模式的区别:代理更多的是强调对对象的访问控制,好比说,访问A对象的查询功能时,访问B对象的更新功能时,访问C对象的删除功能时,都须要判断对象是否登录,那么我须要将判断用户是否登录的功能抽提出来,并对A对象、B对象和C对象进行代理,使访问它们时都须要去判断用户是否登录,简单地说就是将某个控制访问权限应用到多个对象上;而装饰器更多的强调给对象增强功能,好比说要给只会唱歌的A对象添加跳舞功能,添加说唱功能等,简单地说就是将多个功能附加在一个对象上。

因此,代理模式注重的是对对象的某一功能的流程把控和辅助,它能够控制对象作某些事,重心是为了借用对象的功能完成某一流程,而非对象功能如何。而装饰模式注重的是对对象功能的扩展,不关心外界如何调用,只注重对对象功能增强,装饰后仍是对象自己。

总结

对于代理类,如何调用对象的某一功能是思考重点,而不须要兼顾对象的全部功能;对于装饰类,如何扩展对象的某一功能是思考重点,同时也须要兼顾对象的其余功能,由于再怎么装饰,本质也是对象自己,要担负起对象应有的职责,被装饰者的职责一旦增长,做为装饰类也须要有相应的扩展,必然会形成编码的负担。

设计模式自己是为了提高代码的可扩展性,灵活应用便可,没必要生搬硬套,非要分出个因此然来,装饰器模式和代理模式的区别也是如此。

 

"咱们提着过去,走向人群。"

相关文章
相关标签/搜索