`
coral0212
  • 浏览: 101389 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

代理模式

 
阅读更多

       

        代理模式,另外一个名称叫委托模式,下面我从代理购票的例子来说说我的个人看法。

 

 

       火车站购票代理门面店,被称为代理对象(A),个体对象是被代理对象(P),这个P过年回家需要买票,可以买火车票也可以是汽车票,也可以飞机票,P要做的事情就是回家,回家有多种方式,那么回家的方式是接口I,代理对象A也肯定实现了购买车票的方式,如果少了一样没有实现,估计这店很难继续开下去了,

 

       好了,所有的条件都符合了,这时店面可以营业了,这时来了一个人,当然这个人就是实例化过的对象实例了,必须是person了,这个被代理对象的实例,肯定有身份证号,当然我们称没有身份证号的实例,不能叫person人,姑且这样确定.

 

package cn.coral.proxy;

/**
 */
public interface TicketBuy {
	
	/**
	 * @Method: buyTrainTicket 
	 * @Description: 购买火车票
	 * @param     参数 
	 * @return void    返回类型 
	 * @throws
	 */
	public void buyTrainTicket();
	
	/**
	 * @Method: buyBusTicket 
	 * @Description: 购买汽车票
	 * @param     参数 
	 * @return void    返回类型 
	 * @throws
	 */
	public void buyBusTicket();
	
	/**
	 * @Method: buyAirTicket 
	 * @Description: 购买飞机票
	 * @param     参数 
	 * @return void    返回类型 
	 * @throws
	 */
	public void buyAirTicket();
	
}

 

 

package cn.coral.proxy;

public class Agent implements TicketBuy{
	private TicketBuy proxy;
	
	/**
	 * @Method: Agent
	 * @Description: 只有拿到用户的身份证号,才能进行买票,当然还有cash哦,这里只要一个条件吧。所以购票点就只是代理,有台能上网的电脑而已
	 * @param @param userId    参数 
	 * @return void    返回类型 
	 * @throws
	 */
	public Agent(String userId){
		this.proxy = new Person(userId);
	}

	@Override
	public void buyAirTicket() {
		System.out.println("飞机票要登记安检信息,查看身份证号码是否是通缉犯");
		proxy.buyAirTicket();
	}

	@Override
	public void buyBusTicket() {
		proxy.buyBusTicket();
	}

	@Override
	public void buyTrainTicket() {
		proxy.buyTrainTicket();
		System.out.println("火车票买完了要登记购票日志记录");
	}
}

 

 

package cn.coral.proxy;

public class Person implements TicketBuy{

	private String userId;//身份证号
	
	public Person(String userId){
		this.userId = userId;
	}
	@Override
	public void buyAirTicket() {
		System.out.println(userId+"购买了飞机票!\n");
	}

	@Override
	public void buyBusTicket() {
		System.out.println(userId+"购买了汽车票!\n");
	}

	@Override
	public void buyTrainTicket() {
		System.out.println(userId+"购买了火车票!\n");
	}

}

 

       那么这个实例,必须拿出身份证,交给代理对象A,A拿到身份证后,可以购买汽车火车票了.买完结束了.整个过程就是代理模式了,

 

package cn.coral.proxy;

public class Test {
	public static void main(String args[]){
		
		Agent agent = new Agent("110");
		/**
		 * 仔细的读者发现了,这里是调用agent的方法,但是真实执行的person的方法,是不是中间绕了一道.
		 * 代理模式重要特点之一:agent肯定有个可以访问实体,比如如何初始化这个实体,代理知道,外部调
		 * 用者无需知道.在spring中,更恰当的称呼叫注入一个实体.
		 * 代理模式重要特点之二:agent和person同时都实现了购票的接口.
		 */
		agent.buyAirTicket();
		
		agent.buyTrainTicket();
		
		agent.buyBusTicket();
	}
}

 

 

飞机票要登记安检信息,查看身份证号码是否是通缉犯
110购买了飞机票!

110购买了火车票!

火车票买完了要登记购票日志记录
110购买了汽车票!

 

        分析:代理对象本身,并没有购买火车票,因为门面这个店,虽然有钱,它没有身份证,所以不具备购买汽车票火车票的条件,这个很好理解的,只有了身份证号,才能购买,因此这里的身份证号是关键因素(汽车票除外,现在还没有被实名制绑定),火车票和飞机票正常。

 

       特点在于:代理类与被代理类实现的是同一个接口,因此代理类与被代理类的结构是相同的; 

 

       抽象角色:声明真实对象和代理对象的共同接口。(I)

       代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作(这里比如,发现身份证号码是个A级通缉犯,买票成功不说(必要时锁定该对象),反正是一件不好的事情,要报警的,或者要缴纳一些代理费用,购票有抽奖活动,这时P对象还是购票的功能,那么抽奖活动交给代理对象即可),相当于对真实对象进行封装。

 

       例如:接口A有一个接口方法operator(),真实角色:RealA实现接口A,则必须实现接口方法operator()。客户端Client调用接口A的接方法operator()。现在新需求来了,需要修改RealA中的operator()的操作行为。怎么办呢?如果修改RealA就会影响原有系统的稳定性,还要重新测试。这是就需要代理类实现附加行为操作。创建代理ProxyA实现接口A,并将真实对象RealA注入进来。ProxyA实现接口方法operator(),另外还可以增加附加行为,然后调用真实对象的operator()。从而达到了“对修改关闭,对扩展开放”的原则.

 

       从而达到了“对修改关闭,对扩展开放”,保证了系统的稳定性。我们看客户端Client调用仍是接口A的接口方法operator(),只不过实例变为了ProxyA类了而已。也就是说代理模式实现了ocp原则。

 

       这里想多说两句:代理对象的智能引用,可以对一个身份证号,查看本年度累计多少次购票,指定的列车票如果卖完了,可以推荐其他的回家路线,在实际编码中,可能是添加一个记录日志功能,操作方法权限校验,有权限了,进行权限过滤等等.这是代理对象的智能指引场景应用,本实例不能包含所有的场景,但是比起网页图片延迟加载,代理卖毛巾的超市,专卖店,代理商的啥具体一点。

 

       真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。这里就是P。

 

       接下来我想说说实际应用中的场景:

       1)单点登录,在现在很多的网站中,都嵌入了qq互联,微信互联等等登录方式。本身系统可能也有用户名登录,手机号登录,身份证号登录等方式,加上第三方认证登录,恐怕有小十种登录方式要处理。这个案例理解起来应该非常之简单了。吾辈在面试的时候,的确没有考虑到太多,导致这个问题的答案出现了偏差,这里汗一个。首先看行为抽象,都是登录,这是很关键的,都做的是同一件事情,因为都是登录所以有很多共性存在,比如记录登录日志,会员日访问量统计等等。但是登录方式有很多种,这里对应的就是接口实现了。对于自身的系统,可能得到的手机号,用户名,而对于qq互联得到认证后,如qq号,微信号等等,后面的事情就是该干嘛干嘛了。这点延伸一下,就是在设计的时候考虑到第三方认证,比如一个集团上了5个系统,都是一家供应商服务的,就是5个登录入口了,从设计层面上考虑一下单点登录的方案是上上策。

 

       2)数据分表查询,有兴趣的可以看看这个http://zhengdl126.iteye.com/blog/443993,用户信息表非常庞大,以用户名做hash把所有用户打散到不同的表,如取md5('小强')的首英文字母(hash方法很多,这边简单以md5示例)进行横向分表后假设创建如下表名:

            users_a、users_b、users_c、users_d、.....、users_other
            users_a 设置主健基数 10000000
            users_b 设置主健基数 20000000
            users_c 设置主健基数 30000000  
            这样以后,若我们查询  username='小张',则hash后得到小张所在的表名为 users_a,构建sql语句:
                   select * from users_a where username='小张';
            若我们查询用户  ID=21001234,则可间接得到ID21001234所在的表名为 users_b,构建sql语句:
                   select * from users_b where ID=21001234;
             以上这些办法都能在分表后大幅提升数据库查询性能。
             题外话太多太多了,接下来转入正题了,这里又看到共性的存在了,就是查询功能,并且这个查询功能都是查询用户信息表的,只不过查询的方式各有不同,比如根据用户名查询的,ID查询的等等,还有可能是like查询,这就是复杂点的了(这样多个条件组合查询的都是后话了)。此时我们又想到了代理模式了,代理模式的目的是什么,大家可以仔细揣摩揣摩了,“对修改关闭,对扩展开放”。我理解的狭义的意思是,不论后端如何存储,前端调用的时候,依然是那个接口,find(object),对扩展开放,以后加上复杂的查询方式,巨复杂,很复杂的查询方式,只要添加一个实现即可。采用代理模式的时候,可以对查询进行分析,哪些查询使用的最多,以便统计,然后对数据库进行优化,我想360,淘宝应该也是这样的,因为他们网页都是静态化了,每个网页都是html,如果命中查询条件,返回已有的html,如果没有立即静态化。这里是自己的臆想的部分,希望大家拍砖,哈哈。
 
码字挺累的。
分享到:
评论
2 楼 coral0212 2015-01-23  
基于代理模式实现权限管理的案例

举例说明数据权限如下:

例1:论坛A的版主与论坛B的版主拥有同样的角色“版主”,即其功能权限是一致的,但A版主只能管理A论坛的帖子,B版主只能管理B论坛的帖子。

例2:A和都为副总经理,都可审批合同,但A副总经理可审批50万以上的合同,B副总经理只能审批50万以下的合同。

上述两例的共性为:角色都相同,功能权限也相同(例1:论坛管理,例2:合同审批),但可访问的数据权限不同(例1:A版主-论坛A数据,B版主-B论坛数据;例1:A副总经理-大于等于50万合同数据,B副总经理-小于50万合同数据)。

详情请异步http://simpleframework.net/news/view?newsId=9edb9793cab74cbdaa7f206ff9223aed
1 楼 coral0212 2015-01-22  
面向对象设计原则:
1.开闭原则
2.少用继承,多用聚合
3.针对接口编程,不用实现类 编程

相关推荐

    代理模式的使用示例程序

    代理模式是一种设计模式,它在软件工程中扮演着重要的角色,允许我们为其他对象提供一个替代接口,以控制对原始对象的访问。这种模式的主要目的是为了增加灵活性、安全性或者在不修改原有对象的情况下,增强或扩展其...

    JAVA设计模式之代理模式实例

    代理模式是设计模式的一种,它提供了一种对目标对象进行增强或者控制访问的方式。在本实例中,我们将深入探讨Java中的代理模式及其应用。 代理模式的核心思想是为一个对象创建一个代理对象,这个代理对象在客户端和...

    设计模式之代理模式Proxy

    代理模式是设计模式中的一种结构型模式,它在对象交互中起到了中介的作用,允许通过代理对象来控制对原对象的访问。代理模式的核心思想是为一个对象提供一个替身,以便增加新的功能或者控制对原对象的访问。这种模式...

    Android设计模式之代理模式(Proxy Pattern)

    代理模式是设计模式的一种,它的主要目的是在不改变原有对象的基础上,为一个对象提供额外的功能或者控制对这个对象的访问。在Android开发中,代理模式的应用尤为常见,尤其在处理复杂的业务逻辑、网络请求、界面...

    android使用signalr代理模式和非代理模式

    SignalR提供了两种主要的工作模式:代理模式和非代理模式。这两种模式在实现上有所不同,各自具有优缺点,适用于不同的场景。 **1. 代理模式(Proxy Mode)** 在代理模式下,SignalR为每个Hub(服务端的业务逻辑...

    设计模式-代理模式

    代理模式是一种常用的设计模式,它在软件开发中扮演着重要的角色,特别是在iOS平台的应用程序设计中。代理模式的核心思想是为一个对象提供一个替身或代理,以控制对这个对象的访问。这种模式允许我们通过代理来间接...

    java中的三种代理模式

    在Java编程中,代理模式是一种常用的面向对象设计模式,它允许我们为一个对象提供一个代理以控制对该对象的访问。代理模式通常用于增加额外的功能,如日志、权限检查等,或者为了创建虚拟代理以提高性能。以下是Java...

    JAVA设计模式(代理模式)

    **Java设计模式——代理模式详解** 代理模式是软件设计模式中的一个重要组成部分,它在Java编程中扮演着举足轻重的角色。代理模式的核心思想是为一个对象提供一个替身,这个替身即代理对象,代理对象可以控制对原...

    代理模式小例子

    代理模式是一种设计模式,它在软件工程中扮演着重要的角色,允许我们为其他对象提供一个替代接口,以控制对原对象的访问。这种模式的主要目的是为了增加灵活性、安全性或者为对象提供额外的功能,同时保持客户端代码...

    设计模式之代理模式proxy

    **设计模式之代理模式(Proxy Pattern)** 设计模式是软件工程中的一种最佳实践,它是在特定情境下解决常见问题的模板。代理模式是其中一种行为设计模式,它的核心思想是为一个对象提供一个替身或者代理,以控制对...

    设计模式实现——代理模式

    **设计模式实现——代理模式** 在软件工程中,设计模式是一种通用可重用的解决方案,它描述了在特定上下文中经常出现的问题以及该问题的解决方案。代理模式是设计模式的一种,它提供了一种对目标对象的间接访问方式...

    结构型模式之代理模式(Proxy)

    代理模式是一种设计模式,属于结构型模式之一,其主要目的是为其他对象提供一个代理,以控制对该对象的访问。在实际应用中,代理模式能够帮助我们实现如下的功能: 1. 远程代理:代理对象可以代表一个位于远程系统...

    Java设计模式-代理模式例子

    在这个“Java设计模式-代理模式例子”中,我们将深入探讨代理模式的概念、实现方式以及它在实际开发中的应用。 代理模式的核心思想是为一个对象提供一个替身,这个替身即代理对象,代理对象控制对原对象的访问。在...

    android设计模式之代理模式

    代理模式在软件设计中是一种常用的设计模式,尤其在Android开发中,它可以帮助我们实现复杂的控制逻辑,隔离复杂性,以及提供额外的功能。在Android上下文中,代理模式常常用于数据加载、权限控制、事件处理等方面。...

    设计模式C++学习之代理模式(Proxy)

    代理模式是一种设计模式,它是结构型模式之一,主要用于在客户端和目标对象之间建立一个代理对象,以便控制对目标对象的访问。在C++中,代理模式可以用来为其他对象提供一种代理以控制对这个对象的访问,或者增加...

    Java代理模式Java动态代理

    ### Java代理模式与Java动态代理详解 #### 一、代理模式概述 代理模式是一种软件设计模式,它在客户端和目标对象之间提供了一种间接层。这种模式的主要目的是控制客户端对目标对象的访问,并且可以在不修改原有...

    设计模式--代理模式

    代理模式是一种常用的设计模式,它在软件开发中扮演着重要角色,允许我们通过一个代理类来控制对原对象的访问。在《设计模式:可复用面向对象软件的基础》(通常称为GoF设计模式)中,代理模式被定义为“为其他对象...

    代理模式 C++实现

    代理模式(Proxy) 定义: 为其他对象提供一种代理以控制对这个对象的访问 结构: 由三部分组成 1.RealSubject(真实对象): 真正会调用到的对象 2.Proxy(代理对象): 代理真实对象的地方 3.Subject(共同点): 代理对象...

    cas代理模式代码示例

    在IT行业中,代理模式是一种常见的设计模式,它允许我们在不修改原有对象的基础上,为对象添加新的功能或控制访问。在本示例中,我们将重点讨论如何在Java环境下使用代理模式来实现代理逻辑,特别是在CAS(Central ...

Global site tag (gtag.js) - Google Analytics