首页 > 其他分享 >装饰者模式和代理模式

装饰者模式和代理模式

时间:2023-01-29 14:46:55浏览次数:43  
标签:咖啡 coffee 对象 代理 模式 装饰

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

基础实现

定义一个咖啡的接口。

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

定义一个苦咖啡的实现。

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

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

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

装饰器模式

你喝了一口咖啡,觉得有点苦,于是你就想加点糖。

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

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

装饰器和代理模式的区别

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

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

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

装饰器模式和代理模式的使用场景不一样,比如IO流使用的是装饰者模式,可以层层增加功能。而代理模式则一般是用于增加特殊的功能,有些动态代理不支持多层嵌套。

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

所以,代理模式注重的是对对象的某一功能的流程把控和辅助,它可以控制对象做某些事,重心是为了借用对象的功能完成某一流程,而非对象功能如何。而装饰模式注重的是对对象功能的扩展,不关心外界如何调用,只注重对对象功能加强,装饰后还是对象本身。

总结

对于代理类,如何调用对象的某一功能是思考重点,而不需要兼顾对象的所有功能;对于装饰类,如何扩展对象的某一功能是思考重点,同时也需要兼顾对象的其他功能,因为再怎么装饰,本质也是对象本身,要担负起对象应有的职责,被装饰者的职责一旦增加,作为装饰类也需要有相应的扩展,必然会造成编码的负担。

设计模式本身是为了提升代码的可扩展性,灵活应用即可,不必生搬硬套,非要分出个所以然来,装饰器模式和代理模式的区别也是如此。

 

转载自:https://www.cnblogs.com/yanggb/p/10952843.html

标签:咖啡,coffee,对象,代理,模式,装饰
From: https://www.cnblogs.com/cnhk19/p/17072606.html

相关文章

  • 【设计模式】行为型
    职责链模式Client->A->B->C,避免请求发送者与接收者耦合,将接收者对象连接成一条链,直到有对象处理命令模式 将请求转换为一个包含与请求相关的所有信息的独立对象。 可......
  • 爬虫入门第1课:代理池概述及开发环境
    1.什么是代理池代理池就是有代理IP组成的池子,它可以提供多个稳定可用的代理IP2.为什么要实现代理池我们在做爬虫的时候,最常见一种反爬手段就是ip反爬;也就是当同一......
  • MyBatis完成代理方式查询数据以及核心文件配置
    MyBatis目标能够完成Mybatis代理方式查询数据能够理解Mybatis核心配置文件的配置一、Mybatis1.1Mybatis概述1.1.1Mybatis概念MyBatis是一款优秀的持久层框架,用于简化JDB......
  • golang并发编程-生产者消费者模式
    https://blog.csdn.net/qq_55752792/article/details/125917846packagemainimport("fmt""math/rand""sync""time")//JobstructtypeJobst......
  • 【Rancher】- 代理K8s部署记录
    1、在任意节点中,安装Rancherdockerrun-d--restart=unless-stopped-p8080:80-p8443:443--privilegedrancher/rancher:v2.5.9其中"v2.5.9”可以替换为“lates......
  • ExtJS-自定义事件(观察者模式)实现
    更新记录2023年1月6日从笔记迁移到博客。转载请注明出处:ExtJS教程汇总:https://www.cnblogs.com/cqpanda/p/16328016.html使用Ext.util.Observable类型即可。代码......
  • 界面控件DevExpress WinForm的先进技术——服务器和即时反馈模式
    DevExpressWinForm拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForm能完美构建流畅、美观且易于使用的应用程序,无论是Office风......
  • Python之装饰器
    #装饰器功能说明"""python中的装饰器(decorator)一般采用语法糖的形式,是一种语法格式。比如:@classmethod,@staticmethod,@property,@xxx.setter,@wraps(),@fun......
  • 24种设计模式之单例模式(singleton)
    24种设计模式之单例模式(singleton)目录24种设计模式之单例模式(singleton)饿汉模式:推荐使用懒汉模式:不推荐静态内部类模式:推荐最完美的方式java之父推荐:解决线程同步、反序......
  • 11-抽象工厂模式
    11-抽象工厂模式概念抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类举例项目中需要将数据库从SqlServer换成Access,User表和Departme......