代码改变世界

代理模式和装饰者模式

  youxin  阅读(664)  评论(0编辑  收藏  举报

装饰模式:以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案
代理模式:给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用


装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,并不提供对象本身的增强功能

二者的实现机制确实是一样的,可以看到他们的实例代码重复是很多的。但就语义上说,这两者的功能是相反的,模式的一个重要作用是简化其他程序员对你程序的理解,

你在一个地方写装饰,大家就知道这是在增加功能,你写代理,大家就知道是在限制

虽然代码很可能相同,但如果你都叫他们装饰,别人会很迷惑的。

 

代理模式和装饰者模式上在语法形式上几乎完全一样,那么它们的区别在哪里呢?

  • 装饰者模式:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更加灵活
    代理模式: 
  • 为其它对象提供一种代理以控制对这个对象的访问。


    其实,它们的着重点一个在于“增加”职责,另一个在于“控制”访问。这是它们最本质的区别。

     

学习设计模式重点在于“语义”上把握,而不是追求它的“形式”。

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

        我们可以用另外一句话来总结这些差别:使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。    

代理模式:

复制代码
//代理模式
public class Proxy implements Subject{

       private Subject subject;
       public Proxy(){
             //关系在编译时确定
            subject = new RealSubject();
       }
       public void doAction(){
             ….
             subject.doAction();
             ….
       }
}
复制代码
//代理的客户
public class Client{
        public static void main(String[] args){
             //客户不知道代理委托了另一个对象
             Subject subject = new Proxy();
             …
        }
}
复制代码
//装饰器模式
public class Decorator implements Component{
        private Component component;
        public Decorator(Component component){
            this.component = component
        }
       public void operation(){
            ….
            component.operation();
            ….
       }
}
复制代码
//装饰器的客户
public class Client{
        public static void main(String[] args){
            //客户指定了装饰者需要装饰的是哪一个类
            Component component = new Decorator(new ConcreteComponent());
            …
        }
}

 

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
历史上的今天:
2012-07-15 二叉树
2012-07-15 转:提高VS2010的运行速度
2012-07-15 回溯法求排列问题
2012-07-15 最好使用C++转型操作符
2012-07-15 c++ delete 后还有必要set Null 吗?
2012-07-15 STL array
2012-07-15 转:C++关键字详解(volatile, mutable, explicit, dynamic_ cast<T>(expression))等
点击右上角即可分享
微信分享提示