当前位置: 首页 > 编程日记 > 正文

设计模式 之美 -- 代理模式

文章目录

        • 1. 解决问题
        • 2. 应用场景
          • 1. 业务系统的非功能性开发
          • 2. 代理模式在RPC、缓存中的应用
        • 3. 实现
          • C++实现
          • C语言实现

1. 解决问题

客户端和目标对象之间需要进行交互,此时客户端类和目标对象类相关操作之间的逻辑如果交合在一起,会导致客户端和目标对象模块耦合度升高,后期扩展客户端的功能时,则需要修改两者的源代码。

这样的架构设计在系统更加庞大(网络通信链路庞杂,功能增删频繁)的场景下,维护成本极高。

所以,推出代理模式,在客户端和目标对象之间增加代理类,客户端仅需要调用代理类相关的接口,即可完成对目标对象的操作;当客户端调用新的对象时,仅需要扩展代理类的接口即可。

2. 应用场景

1. 业务系统的非功能性开发

监控、统计、鉴权、事务、幂等、日志 这一些附加功能

通过代理模式,将其与业务功能解耦,在代理类中同一处理,程序员仅需关注业务方面的开发,附加功能的调用仅需通过代理类提供的封装好的接口即可。

如:Spring AOP切面 即为代理模式

2. 代理模式在RPC、缓存中的应用

通过远程代理,将网络通信、数据编解码等细节隐藏起来。客户端使用RPC时就像使用本地函数一样,无需了解和服务器的交互细节。

RPC服务的开发者也只需开发业务逻辑,就像开发本地函数一样,不需要关注跟客户端的交互细节。

代理模式在缓存中应用,对于需求中开发一个接口请求的缓存功能,支持缓存、支持实时查询两个接口。此时,随着需求的增加,每个需要都需要增加以上两个接口,这显著增加了开发成本,且会让代码臃肿。

此时增加代理模式,使用动态代理的方式维护 缓存功能的两个接口:支持缓存和支持查询。

3. 实现

C++实现

实现功能:

出版社:被代理对象,要卖书

淘宝、当当网:代理对象

客户端通过当当网进行买书。

#include <iostream>using namespace std;/*
subject(抽象主题角色)真实主题与代理主题的共同接口。RealSubject(真实主题角色):定义了代理角色所代表的真实对象。 Proxy(代理主题角色):含有对真实主题角色的引用,代理角色通常在将客户端调用传递给真是主题对象之前或者之后执行某些操作,而不是单纯返回真实的对象。提示:a中包含b类;a、b类实现协议类protocol 
*/class  Subject
{
public:virtual void SaleBook() = 0;
protected:
private:
};class  RealSubject : public Subject
{
public:virtual void SaleBook(){cout << "卖实体书\n";}
protected:
private:
};class  ProxyTaoBao : public Subject
{
public:virtual void SaleBook(){Double11();RealSubject rs;rs.SaleBook();Double11();}void Double11(){cout << "Double11 打折,半价" << endl;}
protected:
private:
};class  ProxyDangDang : public Subject
{
public:ProxyDangDang():m_s(NULL){}void SetRealSubject(RealSubject *rs){m_s = rs;}virtual void SaleBook(){Double11();SetRealSubject(new RealSubject());m_s->SaleBook();}void Double11(){cout << "Double11 打折,半价" << endl;}
protected:
private:RealSubject *m_s;
};int main()
{cout << "当当代理:" << endl;ProxyDangDang *pdd = new ProxyDangDang;pdd->SaleBook();delete pdd;cout << "淘宝代理:" << endl;ProxyTaoBao *ptb = new ProxyTaoBao;ptb->SaleBook();delete ptb;      return 0;
}

输出如下:

当当代理:
Double11 打折,半价
卖实体书
淘宝代理:
Double11 打折,半价
卖实体书
Double11 打折,半价
C语言实现

实现功能:

实现不同网络协议的代理发送

实际业务端调用操作时才知道具体调用的网络协议(动态代理)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>typedef struct CLIENT{void (*request)();
}PcClient;typedef struct PROXY{PcClient *client;	
}Proxy;void http_request()
{printf("http request!!!\n");return;
}void ftp_request()
{printf("ftp request!!!\n");return;
}void ntp_request()
{printf("ntp request!!!\n");return;
}Proxy *apply_proxy(void){struct PROXY *tmp_proxy = NULL;struct CLIENT *tmp_client = NULL;tmp_proxy = (Proxy*)malloc(sizeof(Proxy));if(tmp_proxy == NULL){return NULL;}tmp_client = (PcClient*)malloc(sizeof(PcClient));if(tmp_client == NULL){return NULL;}tmp_proxy -> client = tmp_client;tmp_client -> request = NULL;return tmp_proxy;
}int main()
{Proxy *proxy = NULL;proxy = apply_proxy();if(proxy == NULL) {return -1;}proxy -> client -> request = http_request;proxy -> client -> request();proxy -> client -> request = ftp_request;proxy -> client -> request();proxy -> client -> request = ntp_request;proxy -> client -> request();if(NULL != proxy) {free(proxy);proxy = NULL;}return 0;
}

输出如下:

http request!!!
ftp request!!!
ntp request!!!

相关文章:

java中注解的使用_java中注解的使用

使用过ssh框架的人一定也使用过注解&#xff0c;尤其是在spring框架中&#xff0c;注解可谓是spring容器和AOP编程的重要环节。注解就是用于修饰类、全局变量、方法、参数或局部变量的接口&#xff0c;java中规定&#xff0c;注解的使用不允许影响其修饰类的存在&#xff0c;也…

水题/poj 1852 Ants

1 /*2 PROBLEM:poj18523 AUTHER:Nicole4 MEMO:水题5 */6 #include<cstdio>7 using namespace std;8 int cmax(int a,int b){return a>b?a:b;}9 int cmin(int a,int b){return a<b?a:b;} 10 int main() 11 { 12 int cases; 13 scanf("%d…

素数、最大公约数、最下公倍数、质因数分解

2013-08-18 11:20:43 素数、最大公约数、最下公倍数、质因数分解都是与素数相关的&#xff0c;解决了素数的问题&#xff0c;其他的都可以此为基础求解。 小结&#xff1a; 求1到n之间的素数的基本方法是通过遍历2到sqrt(n)&#xff0c;判断每个数是否是素数来得到&#xff0c;…

Spring注解 开发

转载于:https://www.cnblogs.com/JBLi/p/10489541.html

读书:个人成长 -- 即兴演讲

与人交流时&#xff0c;有人发言语无伦次&#xff0c;舌头像打了结。 有人一开讲便滔滔不绝&#xff0c;却毫无重点。 也有人说话索然无味&#xff0c;没法让你投以关注。 如何在任何场合游刃有余地表达&#xff1f; 如何掌控此时此刻&#xff0c;用说话影响他人&#xff1f; …

php mysql环境搭配_centos6.7下搭配apache php mysql环境

安装过程安装apacheapache默认端口为80, 而nginx默认端口也是80, 所以安装apache前, 检查是否安装了nginx, 确保80端口没有被占用, 然后执行以下命令安装apacheyum install httpd httpd-devel启动apache服务/etc/init.d/httpd start或service httpd start停止apache服务/etc/in…

我们如此努力,也不过是个普通人

http://www.nowamagic.net/librarys/eight/posts/2500文 / 張君雅 南方日报曾刊登了一条新闻&#xff0c;大意是说有个女孩子以她的成绩考入北大清华没问题。但她从小参加各种社会活动&#xff0c;深受曾留学法国的母亲“生命的意义在于体验最多而不是最好”影响&#xff0c;决…

Citrix XenServer@cloudstack基本功能测试报告2

Cloudstack功能测试1、创建Zone、Pod、Clusters&#xff0c;添加hosts、Primary Storage、Secondary Storage步骤&#xff1a;1、 登录cloudstack控制板2、 选择基础架构&#xff0c;选择区域&#xff0c;点击查看全部&#xff0c;然后点击添加区域3、 选择基本区域类型4、 输入…

ABP中的Filter(下)

接着上面的一个部分来叙述&#xff0c;这一篇我们来重点看ABP中的AbpUowActionFilter、AbpExceptionFilter、AbpResultFilter这三个部分也是按照之前的思路来一个个介绍&#xff0c;当然这里面如果和前面的Interceptor有重复的部分&#xff0c;那么将会对两者进行一个对比并作出…

LRU算法 -- 链表 完整实现

LRU算法(Least Recently Used) 算是我们经常遇到的一种淘汰算法&#xff0c;其中内存管理模块进行内存页回收时有用到&#xff0c;针对不经常使用的内存页&#xff0c;LRU淘汰策略能够将该内存页回收给操作系统。 属于 我们操作系统设计中的 时间局部性原理&#xff0c;最长时…

python getostime_python中sys,os,time模块的使用(包括时间格式的各种转换)

sys模块sys.argv: 实现从程序外部向程序传递参数。位置参数argv[0]代表py文件本身&#xff0c;运行方法 python xx.py 参数1&#xff0c;参数2 。。self sys.argv[0]name sys.argv[1]age sys.argv[2]print self, name, agesys.getdefaultencoding(): 获取系统当前编码&#…

关于SpringMVC和Struts2的区别

1. 与struts2不同 1、 springmvc的入口是一个servlet即前端控制器&#xff0c;而struts2入口是一个filter过虑器。 2、 springmvc是基于方法开发&#xff0c;传递参数是通过方法形参&#xff0c;可以设计为单例或多例(建议单例)&#xff0c;struts2是基于类开发&#xff0c…

DC-RC加固修补型砂浆

DC-RC加固修补型砂浆www.hrbjg.net一、DC-RC加固修补型砂浆的产品特点&#xff1a;1、耐火、耐高温、耐腐蚀、耐老化性能优良。2、强度高&#xff0c;抹灰操作性好。3、与原混凝土结构的粘结性能良好。4、无收缩&#xff0c;基本不会产生裂缝。5、二氧化碳、氯化物等透过性差&a…

类,实例,属性习题

class Restaurant(): def __init__(self,restaurant_name,cuisine_type): self.restaurant_namerestaurant_name self.cuisine_typecuisine_type def describle_restaurant(self): print("打印的第一条消息") print("打印的第…

数据结构和算法 -- 学习导图

数据结构和算法 是作为程序员写出高效代码的基础&#xff0c;为了今后的两年在高效代码之路上持续精进&#xff0c;将按照此学习导图进行 算法和数据结构的刻意练习&#xff0c;同时也希望为同样有高效代码追求的伙伴们提供一条学习路径&#xff0c;共同进步。 以下为今后持续…

HDU 1248 寒冰王座(全然背包:入门题)

HDU 1248 寒冰王座(全然背包:入门题) http://acm.hdu.edu.cn/showproblem.php?pid1248 题意: 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,仅仅有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店前. 死亡骑士:"我要买…

java 彩票系统_JAVA版彩票随机生成系统

import java.io.*;import java.util.Random;class num{public static void main(String[]args){//声明一个随机数组int sjsh[]new int[7];int sum;try{InputStreamReader anew InputStreamReader(System.in);BufferedReader bnew BufferedReader(a);System.out.println ("…

Windows Server 2012 文件服务器群集

概述&#xff1a;之前已经测试了Windows Server 2012系统群集、Hyper-V群集&#xff0c;接下来将测试Windows Server 2012 文件服务器群集功能。实验环境&#xff1a;4台服务器都为Windows Server 2012 DataCenter操作系统在之前配置了群集的基础上&#xff0c;SRV2012服务器新…

023 判断出栈顺序是否正确

1.题目 输入两个整数序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;请判断第二个序列是否为该栈的弹出顺序。 假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压栈序列&#xff0c;序列4、5、3、2、1是该压栈序列对应的一个弹出序列&#xff0c;但4、3…

栈 -- 顺序栈、链式栈的实现 及其应用(函数栈,表达式求值,括号匹配)

文章目录实现顺序栈实现链式栈实现应用函数栈 的应用表达式求值中 的应用括号匹配中 的应用我们使用浏览器的时候经常会用到前进、后退功能。依次访问完一串页面 a – b – c之后点击后退功能&#xff0c;则能够依次看到c – b – a的页面。但是这个过程中&#xff0c;如果后退…

OC中的NSArray和NSMutableArray、NSDictionary和NSMutableDictionary用法

一&#xff1a;NSArray 和NSMutableArray1: NSArray&#xff1a;不可变数组NSArray是OC中使用的数组&#xff0c;只能用来存放OC对象&#xff0c;不能存放非OC对象如基本数据类型它使不可变的&#xff0c;一旦初始化完毕&#xff0c;内容不能改变&#xff0c;也不能添加元素。而…

java中ContentArea_java中TextArea怎么加载指定路径的文本内容

展开全部这设计到IO操作&#xff0c;很62616964757a686964616fe58685e5aeb931333332643334久以前练手写的加载文本到文本域的界面。具体代码第一步&#xff1a;得到一个File对象&#xff0c;需要参数文本路径File file new File("C:\\test.txt");第二步&#xff1a;…

文本分类技术基础

分类体系 分类&#xff1a;给定一个对象&#xff0c;从一个事先定义好的分类体系中挑出一个或多个最适合该对象的类别。 文本分类(TC, Text Categorization)&#xff1a;在给定的分类体系下&#xff0c;根据文本内容自动的确定文本关联的类别。从数学角度看&#xff0c;文本分类…

C# 返回值为 listT

public List<T> test<T>(List<T> EntityList) where T : class{return EntityList;} 转载于:https://www.cnblogs.com/enych/p/10497312.html

ceph bluestore 源码分析:ceph-osd内存查看方式及控制源码分析

文章目录内存查看内存控制内存控制源码分析通过gperftools接口获取osd进程实际内存 动态设置cache大小动态调整cache比例trim释放内存本文通过对ceph-osd内存查看跟踪的5种手段以及osd内存控制的方式进行源码层面的说明&#xff0c;并未通过修改相关源码进行控制&#xff08;水…

c语言函数库学习~sscanf~格式化输入

---恢复内容开始--- 今天算是被打击到了吧&#xff0c;由郑轻的acm老师来我学院指导安排了个现场的小比赛&#xff0c;&#xff0c;俺们居然有还是输给一个大一的新手&#xff0c;&#xff0c;哎&#xff0c;情何以堪&#xff0c;&#xff0c;所以还是要重视下基础编程能力的培…

java mobile phone games_j2me100-src Java

文件名大小更新时间codesc.net\[J2SE]应用编程150例\chap01\实例1\BorderLayoutDemo.class8192003-07-07codesc.net\[J2SE]应用编程150例\chap01\实例1\BorderLayoutDemo.java5752003-07-07codesc.net\[J2SE]应用编程150例\chap01\实例1\BoxLayoutFrame.class7262003-07-15code…

***突然断开可能是ADSL猫惹的祸

在我们使用服务器的时候&#xff0c;最讨厌的就是无故的断线了&#xff0c;可能正在和好一起副本&#xff0c;或者正在视频热聊中&#xff0c;还或者youtube视频看的正起劲&#xff0c;突然windows一个对话框弹出 - “连接已经断开”。实在是太影响体验了&#xff0c;断开之后&…

文件中数组的最大值及其对应的最小下标

2019年春季学期第二周作业基础作业请在第一周作业的基础上&#xff0c;继续完成&#xff1a;找出给定的文件中数组的最大值及其对应的最小下标&#xff08;下标从0开始&#xff09;。并将最大值和对应的最小下标数值写入文件。 输入&#xff1a;请建立以自己英文名字命名的txt文…

ceph bluestore源码分析:admin_socket实时获取内存池数据

环境&#xff1a; 版本&#xff1a;ceph 12.2.1 部署完cephfs 使用ceph-fuse挂载&#xff0c;并写入数据 关键参数&#xff1a; debug_mempool true 将该参数置为true即可查看详细的blustore管理的内存池的数据 命令&#xff1a; ceph daemon osd.id dump_mempools该命令为ad…