1、概述

  对于两个模式,首先要说的是,装饰模式就是代理模式的一个特殊应用,两者的共同点是都具有相同的接口,不同点则是代理模式着重对代理过程的控制,而装饰模式则是对类的功能进行加强或减弱,它着重类的功能变化,我们举例来说明它们的区别。

2、代理模式

  一个著名的短跑运动员有自己的代理人。如果你很仰慕他,你找运动员说“你跑个我看看”,运动员肯定不搭理你,不过你找到他的代理人就不一样了,你可能和代理人比较熟,可以称兄道弟,这个忙代理人还是可以帮的,于是代理人同意让你欣赏运动员的练习赛,那么你的目的就达成了。

2.1 类图

  这是一个套用代理模式的简单应用,非常简单。一个对象,然后再是自己的代理。

2.2 代码

2.2.1 抽象主题类

class CIRunner
{
public :
CIRunner (){};
~ CIRunner (){};
virtual void mvRun() = ;
};

2.2.2 短跑运动员

  一个具体的短跑运动员跑步是很潇洒的。

class CRunner :public CIRunner
{
public:
CRunner(){};
~CRunner(){};
void mvRun(){ cout << "运动员跑步: 动作很潇洒" << endl; };
};

2.2.3 代理人

  看看现在的明星运动员,一般都有自己的代理人,要么是专职的,要么就是自己的教练兼职,那我们来看看代理人的职责。

class CRunnerAgent : public CIRunner
{
public:
CRunnerAgent(CIRunner *opRunner) { mopRunner = opRunner; }
~CRunnerAgent(){}
void mvRun() { mopRunner->mvRun(); }
private:
CIRunner *mopRunner;
};

2.2.4 调用

  我们只是定义了一个代理人,并没有明确定义是哪一个运动员的代理,需要在运行时指定被代理者,对于主题类的行为是否可以发生,代理类有绝对的控制权。

int main()
{
//定义一个短跑运动员
CIRunner *op_runner = new CRunner(); //定义的代理人
CIRunner *op_agent = new CRunnerAgent(op_runner); //要求运动员跑步
cout << "====客人找到运动员的代理要求其去跑步===" << endl;
op_agent->mvRun(); return ;
}

2.2.5 运行结果

3、装饰模式

3.1 类图

  如果使用装饰模式,我们该怎么实现这个过程呢?装饰模式是对类功能的加强,怎么加强呢?增强跑步速度!在屁股后面安装一个喷气动力装置,类似火箭的喷气装置,那速度变得很快,《蜘蛛侠》中的那个反面角色不就是这样的吗?好,我们来看类图。

  很惊讶是吧?这个代理模式完全一样的类图。是的,完全一样!不过其实现的意图却不同。

3.2 代码

  我们来看代码,CIRunner和CRunner与代理模式相同,在此不再赘述。

3.2.1 装饰类

class CRunnerWithJet : public CIRunner
{
public:
CRunnerWithJet(CIRunner *opRunner){ mopRunner = opRunner; };
~CRunnerWithJet(){}; void mvRun()
{
cout << "加快运动员的速度: 为运动员增加喷气装置" << endl;
mopRunner->mvRun();
} private:
CIRunner *mopRunner;
};

  这和代理模式中的代理类也是非常相似的,只是装饰类对类的行为没有决定权,只有增强作用,也就是说它不决定被代理的方法是否执行,它只是再次增加被代理的功能。

3.2.2 场景调用

int main()
{
//定义运动员
CIRunner *op_runner = new CRunner();
//对其功能加强
op_runner = new CRunnerWithJet(op_runner);
//看看它的跑步情况如何
cout << "===增强后的运动员的功能===" << endl;
op_runner->mvRun(); return ;
}

3.2.3 执行结果

  注意思考一下我们的程序,我们通过增加了一个装饰类,就完成了对原有类的功能增加,由一个普通的短跑运动员变成了带有喷气装置的超人运动员。

4、总结

  通过例子,我们可以看出代理模式和装饰模式有非常相似的地方,甚至代码实现都非常相似,特别是装饰模式中省略抽象装饰角色后,两者代码基本上相同,但是还是有细微的差别。

  代理模式是把当前的行为或功能委托给其他对象执行,代理类负责接口限定:是否可以调用真实角色,以及是否对发送到真实角色的消息进行变形处理,它不对被主题角色(也就是被代理类)的功能做任何处理,保证原汁原味的调用。

  装饰模式是在要保证接口不变的情况下加强类的功能,它保证的是被修饰的对象功能比原始对象丰富(当然,也可以减弱),但不做准入条件判断和准入参数过滤,如是否可以执行类的功能,过滤输入参数是否合规等,这不是装饰模式关心的。

【设计模式】 模式PK:代理模式VS装饰模式的更多相关文章

  1. Java设计模式:Proxy(代理)模式

    概念定义 代理模式是一种使用代理对象来执行目标对象的方法并在代理对象中增强目标对象方法的一种设计模式. 使用代理模式的原因有: 中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象, ...

  2. java设计模式之Proxy(代理模式)

    java设计模式之Proxy(代理模式) 2008-03-25 20:30 227人阅读 评论(0) 收藏 举报 设计模式javaauthorizationpermissionsstringclass ...

  3. Java设计模式之《代理模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6525527.html 代理模式算是我接触较早的模式,代理就是中介,中间人.法律上也有代理, ...

  4. C#设计模式之十三代理模式(Proxy)【结构型】

    一.引言   今天我们要讲[结构型]设计模式的第七个模式,也是"结构型"设计模式中的最后一个模式,该模式是[代理模式],英文名称是:Proxy Pattern.还是老套路,先从名字 ...

  5. Java进阶篇设计模式之七 ----- 享元模式和代理模式

    前言 在上一篇中我们学习了结构型模式的组合模式和过滤器模式.本篇则来学习下结构型模式最后的两个模式, 享元模式和代理模式. 享元模式 简介 享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能 ...

  6. Java设计模式之七 ----- 享元模式和代理模式

    前言 在上一篇中我们学习了结构型模式的组合模式和过滤器模式.本篇则来学习下结构型模式最后的两个模式, 享元模式和代理模式. 享元模式 简介 享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能 ...

  7. 《Java设计模式》之代理模式 -Java动态代理(InvocationHandler) -简单实现

    如题 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式可细分为如下, 本文不做多余解释 远程代理 虚拟代理 缓冲代理 保护代理 借鉴文章 ht ...

  8. 简介Python设计模式中的代理模式与模板方法模式编程

    简介Python设计模式中的代理模式与模板方法模式编程 这篇文章主要介绍了Python设计模式中的代理模式与模板方法模式编程,文中举了两个简单的代码片段来说明,需要的朋友可以参考下 代理模式 Prox ...

  9. 重学 Java 设计模式:实战代理模式「模拟mybatis-spring中定义DAO接口,使用代理类方式操作数据库原理实现场景」

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 难以跨越的瓶颈期,把你拿捏滴死死的! 编程开发学习过程中遇到的瓶颈期,往往是由于看不 ...

  10. 设计模式系列之代理模式(Proxy Pattern)——对象的间接访问

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

随机推荐

  1. 单源最短路——dijkstra算法

    Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...

  2. 【android】实现手指滑动来切换activity(转)

    http://code.eoe.cn/115 1.jpg外部引用 原始文档 MainActivity.java外部引用 原始文档 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

  3. js 拼接字符串时,本来想要’#1′ ,返回的却是’#01′

    今天在操作一个元素时,id值是拼接的. var index = $(this).attr(‘index’);    //0var id = ‘#’ + (index+1);    //#01$(id) ...

  4. Swift中避免在多个文件中重复import相同的第三方包

    swift中由于有命名空间的存在,在同一个target创建的文件,都可以不引用直接就可以拿来使用,但是不同target之间必须要import 之后才能使用,在不同的文件中使用都要重复的import这个 ...

  5. IDEA编译的JAR包运行出现“没有主清单属性”

    运行编译好的包出现: 解决方案就是: 确保MANIFEST.MF文件在src/main/resources/META_INF/而不是src/main/java/META_INF/

  6. Java多线程同步机制之同步块(方法)——synchronized

    在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法或者代码块,解决了资源共享.下面代码示意三个窗口购5张火车票: package com.jikexueyuan.t ...

  7. 钉钉 E应用 打开分享外链

    钉钉 E应用 打开分享外链 外部链接 https://open-doc.dingtalk.com/microapp/dev https://open-doc.dingtalk.com/microapp ...

  8. 【hdu3555】Bomb 数位dp

    题目描述 求 1~N 内包含数位串 “49” 的数的个数. 输入 The first line of input consists of an integer T (1 <= T <= 1 ...

  9. BZOJ4737 组合数问题(卢卡斯定理+数位dp)

    不妨不管j<=i的限制.由卢卡斯定理,C(i,j) mod k=0相当于k进制下存在某位上j大于i.容易想到数位dp,即设f[x][0/1][0/1][0/1]为到第x位时是否有某位上j> ...

  10. P1365 WJMZBMR打osu! / Easy

    题目背景 原 维护队列 参见P1903 题目描述 某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:( 我们来简化一下这个游戏的规则 有 nnn 次点击要做,成功了就是o,失败了 ...