2. 代理模式-为别人做嫁衣

来源:互联网 发布:炫酷桌面软件 编辑:程序博客网 时间:2024/06/12 01:13

        今天来说另外一个设计模式:代理模式。举个例子:张三想追李娇娇同学,这里李娇娇同学不认识张三。张三让戴笠帮忙去送花送零食之类的,最后李娇娇同学和戴笠在一起了,张三为戴笠做了嫁衣。下面来详细解释:

        首先定义一下代理模式:为其他对象提供一种代理以控制对这个对象的访问。

        1. 最开始的实现:没有代理

        追求者追求娇娇,这是一个没有使用代理的实例:这里完全没有用到戴笠这个人,也就是没有使用代理,直接是张三追求娇娇,然而实际上却是娇娇根本不认识张三,是戴笠帮忙追求娇娇的。

这个是被追求者的类的bean

package com.proxy;//被追求者的类public class SchoolGirl {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}
追求者类
package com.proxy.noproxy;import com.proxy.SchoolGirl;/** * 这个类是没有代理实现的 * @author Lou * */public class Pursuit1 {SchoolGirl mm;//定义要追求的对象public Pursuit1() {}public Pursuit1(SchoolGirl mm) {this.mm = mm;}public void giveDolls() {System.out.println(mm.getName() + ":送你洋娃娃");}public void giveFlowers() {System.out.println(mm.getName() + ":送你鲜花");}public void giveChocolate() {System.out.println(mm.getName() + ":送你巧克力");}}
客户端:是test1

package com.proxy;import org.junit.Test;import com.proxy.noproxy.Pursuit1;import com.proxy.onlyproxy.Proxy;import com.proxy.proxypattern.Proxy2;/** *  * @author Administrator * */public class Client {//这个实例没有代理@Testpublic void test1() {SchoolGirl jj = new SchoolGirl();jj.setName("李娇娇");Pursuit1 zhangsan = new Pursuit1(jj);//娇娇并不认识张三,所以此处没有代理zhangsan.giveDolls();zhangsan.giveFlowers();zhangsan.giveChocolate();}}


        2. 仅仅使用代理:

        这里把追求者换成了戴笠,变成了礼物是戴笠送的,与张三就毫无关系了,这时候,张三这个人是不存在的了。然而实际情况中却是张三让戴笠帮忙送礼物

代理类如下:

package com.proxy.onlyproxy;import com.proxy.SchoolGirl;public class Proxy {SchoolGirl mm;//定义要追求的对象public Proxy() {}public Proxy(SchoolGirl mm) {this.mm = mm;}public void giveDolls() {System.out.println(mm.getName() + ":送你洋娃娃");}public void giveFlowers() {System.out.println(mm.getName() + ":送你鲜花");}public void giveChocolate() {System.out.println(mm.getName() + ":送你巧克力");}}

客户端的接口是test2:

//这个测试只有代理,而没有张三。@Testpublic void test2() {SchoolGirl jj = new SchoolGirl();jj.setName("李娇娇");Proxy daili = new Proxy(jj);//这里只有代理,就不存在张三了daili.giveDolls();daili.giveFlowers();daili.giveChocolate();}

        3. 使用使用代理模式:

实际的情况应该是:追求者通过代理给娇娇送礼物,这才是合情合理。这时候追求者pursuit和代理proxy有一些相似的地方,比如他们都有送礼物的三个方法,不过礼物是代理proxy送的,但是礼物却是追求者张三买的,所以实质是追求者pursuit张三送的。他们有相同的方法,那我们就定义接口,这两个类实现同样的接口。

公共接口:

package com.proxy.proxypattern;public interface IgiveGift {public void giveDolls();public void giveFlowers();public void giveChocolate();}

追求者,实现接口

package com.proxy.proxypattern;import com.proxy.SchoolGirl;/** * 这个类是没有代理实现的 * @author Lou * */public class Pursuit2 implements IgiveGift{SchoolGirl mm;//定义要追求的对象public Pursuit2() {}public Pursuit2(SchoolGirl mm) {this.mm = mm;}public void giveDolls() {System.out.println(mm.getName() + ":送你洋娃娃");}public void giveFlowers() {System.out.println(mm.getName() + ":送你鲜花");}public void giveChocolate() {System.out.println(mm.getName() + ":送你巧克力");}}

代理类,通过内部的追求者,代理送礼物

package com.proxy.proxypattern;import com.proxy.SchoolGirl;/** * 这个类是没有代理实现的 * @author Lou * */public class Pursuit2 implements IgiveGift{SchoolGirl mm;//定义要追求的对象public Pursuit2() {}public Pursuit2(SchoolGirl mm) {this.mm = mm;}public void giveDolls() {System.out.println(mm.getName() + ":送你洋娃娃");}public void giveFlowers() {System.out.println(mm.getName() + ":送你鲜花");}public void giveChocolate() {System.out.println(mm.getName() + ":送你巧克力");}}

客户端测试如下:

//这个测试代理模式@Testpublic void test3() {SchoolGirl jj = new SchoolGirl();jj.setName("李娇娇");Proxy2 daili = new Proxy2(jj);//这里只有代理,就不存在张三了daili.giveDolls();daili.giveFlowers();daili.giveChocolate();}


4. 代理模式模板总结:

首先定义的Subject类是RealSubject和Proxy的共用接口,这样在任何使用RealSubject类的地方都可以是用Proxy来代理。

public interface Subject{public void request();}
RealSubject类定义了Proxy多代表的真实的实体。
public class RealSubject implement Subject {public void request() {System.out.println("真实的请求");}}

proxy类,保存一个引用,以使得代理可以访问实体,并提供一个与subject类相同的接口,这样代理就可以来代替实体

public class Proxy implement Subject {        RealSubject realSubject;public Proxy( RealSubject realSubject) {this.reakSubject = realSubject;}public void request() {realSubject.request();}}



0 0