设计模式之代理模式

      今天这篇博客笔者将会写一种特别重要的设计模式-代理模式,其实在23中设计模式里面,代理模式的原型应该来说属于比较简单。但是真正要扩展起来那么它的用处还是非常大的,知识面也非常的广。好了,闲话少说让我们直接进入今天的主题吧!

      照旧我们还是先来看看代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问,定义很简单明了。让我们来看看这样一个场景吧,假如你要结婚,然后就必须要去见一见女方的家长。但是这个时候,你女朋友又担心你最笨说错话。于是你们就商量好了,当岳父岳母问你的时候,尽量交由你女朋友来回答,避免岳父岳母对你不满意。好的,下面我们就将通过代理模式来模拟出这个场景。

      首先我们需要定义一个基接口IMeet来约定好你见岳父岳母过程中,应该做哪些事情。代码如下:

public interface IMeet {

	//介绍名字
	void IntroduceName();
	void IntroduceAge();
	void IntroduceWork();
	void IntroduceFaimly();
}

  然后我们肯定需要将你这个男朋友定义出来,同时让他集成上面的接口,完成上面的那些行为,才有可能得到岳父岳母的同意。代码如下:

public class BoyFriend implements IMeet {

	@Override
	public void IntroduceName() {
		System.out.println("xiaocai");
	}

	@Override
	public void IntroduceAge() {
		System.out.println("20");
	}

	@Override
	public void IntroduceWork() {
		System.out.println("软件工程师");
	}

	@Override
	public void IntroduceFaimly() {
		System.out.println("家里还有个妹妹");
	}
}

  最后要开始见面了,肯定少不了你女朋友这个见面代理人(MeetProxy)咯,同理她肯定也需要集成IMeet接口,因为代理者肯定也需要被代理人需要执行哪些行为。MeetProxy代码如下:

public class MeetProxy implements IMeet {

	private IMeet boyFriend;
	
	public MeetProxy(IMeet boyFriend){
		this.boyFriend=boyFriend;
	}
	
	@Override
	public void IntroduceName() {
		this.boyFriend.IntroduceName();
	}

	@Override
	public void IntroduceAge() {
		this.boyFriend.IntroduceAge();
	}

	@Override
	public void IntroduceWork() {
		this.boyFriend.IntroduceWork();
	}

	@Override
	public void IntroduceFaimly() {
		this.boyFriend.IntroduceFaimly();
	}
}

  好了,上面已经定义出来代理模式里面最重要的三个基本要素:代理人(MeetProxy)、被代理人(BoyFriend)、需要执行的行为协议(IMeet),接下来所有的对男朋友的访问都将通过你的女朋友来完成。代码如下:

public class MainTest {

	public static void main(String[] args) {
		
		IMeet boyFriend=new BoyFriend();
		MeetProxy grilFriend=new MeetProxy(boyFriend);
		grilFriend.IntroduceName();
		grilFriend.IntroduceAge();
		grilFriend.IntroduceFaimly();
		grilFriend.IntroduceWork();
	}
}

  ok,通过上面的代码你可以发现确实所有对男朋友的访问都屏蔽掉了,但是如果你仔细看代码会发现我还需要New出来一个BoyFriend,也就是说我还需要明确知道代理者现在具体要代理的是哪个对象。那么有没有什么办法能够让代理者内部消化掉这些判断逻辑呢?答案是肯定的,我们只需要修改一下代理者,代码如下:

public class MeetProxy implements IMeet {

	private IMeet boyFriend=new BoyFriend();
	
	@Override
	public void IntroduceName() {
		this.boyFriend.IntroduceName();
	}

	@Override
	public void IntroduceAge() {
		this.boyFriend.IntroduceAge();
	}

	@Override
	public void IntroduceWork() {
		this.boyFriend.IntroduceWork();
	}

	@Override
	public void IntroduceFaimly() {
		this.boyFriend.IntroduceFaimly();
	}
}

    上面的代码,我们只是简单去掉了代理者里面的构造函数,直接new出来了被代理者对象。这样我们就能够很明显的知道,女朋友只代理男朋友回答自己父母的问题。同时调用的时候,我们也不再需要new一个BoyFriend了,因为女朋友这个代理类里面已经知道自己男朋友是谁了,调用代码也会很简单。代码如下:

public class MainTest {

	public static void main(String[] args) {
		
		MeetProxy grilFriend=new MeetProxy();
		grilFriend.IntroduceName();
		grilFriend.IntroduceAge();
		grilFriend.IntroduceFaimly();
		grilFriend.IntroduceWork();
	}
}

  好了,说到这里笔者就想做一些扩展。其实在代理模式里面,也许大家还听过:普通代理、强制代理、动态代理等概念。下面我们就来针对这些不同的代理分类来具体说一说,首先是普通代理,很简单上面的代码示例就是普通代理的demo,普通代理的概念其实很简单:就是让代理明确能够知道被代理对象。

      强制代码这个概念就会有点复杂了,它的意思跟普通代理刚好相反。普通代理是通过代理找到被代理对象,而强制代理呢?则是通过被代理对象找到代理。两者刚好相反,说起来好像有点抽象,下面就让我们来具体看看代码吧。

public interface IMeet {

	//介绍名字
	void IntroduceName();
	void IntroduceAge();
	void IntroduceWork();
	void IntroduceFaimly();
	
	IMeet getProxy();
}
public class BoyFriend implements IMeet {

	private IMeet proxy;
	
	@Override
	public void IntroduceName() {
		this.proxy.IntroduceName();
	}

	@Override
	public void IntroduceAge() {
		this.proxy.IntroduceAge();
	}

	@Override
	public void IntroduceWork() {
		this.proxy.IntroduceWork();
	}

	@Override
	public void IntroduceFaimly() {
		this.proxy.IntroduceFaimly();
	}

	@Override
	public IMeet getProxy() {
		this.proxy=new MeetProxy(this);
		return this.proxy;
	}
}
public class MeetProxy implements IMeet {

	private IMeet boyFriend=null;
	
	public MeetProxy(IMeet boyFriend){
		this.boyFriend=boyFriend;
	}
	
	@Override
	public void IntroduceName() {
		this.boyFriend.IntroduceName();
	}

	@Override
	public void IntroduceAge() {
		this.boyFriend.IntroduceAge();
	}

	@Override
	public void IntroduceWork() {
		this.boyFriend.IntroduceWork();
	}

	@Override
	public void IntroduceFaimly() {
		this.boyFriend.IntroduceFaimly();
	}

	@Override
	public IMeet getProxy() {
		return this;
	}
}
public class MainTest {

	public static void main(String[] args) {
		
		IMeet boyFriend=new BoyFriend();
		IMeet grilFriend=boyFriend.getProxy();
		
		grilFriend.IntroduceName();
		grilFriend.IntroduceAge();
		grilFriend.IntroduceFaimly();
		grilFriend.IntroduceWork();
	}
}

    好了,强制代理的demo就到这里吧。其实说白了,就是通过getProxy方法在被代理者找到代理者,然后调用的时候,也要明确通过getProxy方法才能调到当前被代理者所需要的代理者。最后还有一种动态代理,这个概念其实在很多框架里面已经运用的很多了,是运用反射原理实现的。赶着去上班,时间太急,大家有兴趣可以自己研究研究。

      今天的博客就到这里,see you!

原文地址:https://www.cnblogs.com/xiaocai20091687/p/xiaocai_design_seven.html