设计模式(八)——代理模式

213 阅读4分钟

上一篇:设计模式(七)——桥接模式

下一篇:设计模式(九)——装饰器模式

一、需求

官方解释: Provide a surrogate (代理) or placeholder for another object to control access to it.(为其他对象提供一种代理以控制对这个对象的访问。)

我的理解: 实体类和代理类都是继承于与同一个父类,那代理类存在的意义是什么呢?

不使用代理类的情况,可以,参见代码1

参与者: AbstractSubject抽象主题、ProxySubject代理主题、RealSubject真实主题

类图:

二、代码

代码1——不使用代理类

package mypackage;

public class DesignPatternDemo {

	public static void main(String[] args) {
		Image image = new RealImage();
		image.display();
	}

}

interface Image {
	public void display();
}

class RealImage implements Image {

	@Override
	public void display() {
		System.out.println("This is an Image");
	}

}

输出1:

This is an Image

既然不使用代理类可以访问对象,那么代理类的存在的意义是什么呢?

代理类存在的意义在于两点:

第一,给用户多一种选择方式,如果某件事实体类本身可以完成,代理类也可以完成,比如可以用exe可执行文件打开电脑上的某个软件或文件(本例中为图片Image),也可以用它的快捷方式打开它,快捷方式就是一种代理,它代理打开软件,它的存在给了用户多一种选择方式,这时代理类是可以或缺的。参见代码2

第二,某件事实体类不可以完成,代理类可以完成,比如在远程桌面上打开一种图片,但是实体类本身不能完成,这时只能通过该图片的远程代理来完成,这时代理类是不可或缺的。参见代码3

代码2——快捷方式代理:

package mypackage;

public class DesignPatternDemo {

	public static void main(String[] args) {
		Image image_proxy = new Image_shortCut(new RealImage());
		image_proxy.display();
	}

}

interface Image {
	public void display();
}

class RealImage implements Image {

	@Override
	public void display() {
		System.out.println("This is an Image");
	}

}

class Image_shortCut implements Image {
	private RealImage _image;

	public  Image_shortCut(RealImage _iImage) {
		this._image = _iImage;
	}

	@Override
	public void display() {
		_image.display();

	}

}

输出2:

This is an Image

通常来说,一个是实体类可以有多个代理类,但是一般一个代理类只代表一个实体类

代码3——代理类的扩展:(添加一个远程代理)

package mypackage;

public class DesignPatternDemo {

	public static void main(String[] args) {
		Image image_proxy = new Image_shortCut(new RealImage());
		image_proxy.display();
		
		image_proxy=new RemoteProxyImage(new RealImage());
		image_proxy.display();
	}

}

interface Image {
	public void display();
}

class RealImage implements Image {

	@Override
	public void display() {
		System.out.println("This is an Image");
	}

}

class Image_shortCut implements Image {
	private RealImage _image;

	public  Image_shortCut(RealImage _iImage) {
		this._image = _iImage;
	}

	@Override
	public void display() {
		_image.display();

	}

}
class RemoteProxyImage implements Image{
	private RealImage _image;

	 public   RemoteProxyImage(RealImage _iImage) {
		this._image = _iImage;
	}

	@Override
	public void display() {
		System.out.print("远程代理: ");
		_image.display();
	}
}

输出3:

This is an Image
远程代理: This is an Image

三、小结

设计模式只重其意不重其形,所以说,项目开发中,从来不要逼着自己去使用代理模式,当实体类可以完成某需求时,代理类是可以或缺的,只有当实体类不能完成某需求时,代理类才是不可或缺的。

附:桥接模式、代理模式与装饰器模式对比

 桥接模式代理模式装饰器模式
关键类多个维度,各个维度父类和子类代理类装饰类
继承关系各个维度内父类和子类继承关系,便于面向接口编程,各个维度之间类与类没有关系,相互独立实体类和代理类都继承于同一父类,它们与父类是继承关系,便于客户端面向接口编程实体类和装饰类都继承于同一父类,它们与父类是继承关系,便于客户端面向接口编程
组合关系各个维度之间类与类使用组合注入方式联系实体类和代理类之间是组合关系,将实体类引用注入代理类,在代理类中调用实体类方法或属性实体类和装饰类之间是组合关系,将实体类引用注入装饰类,在装饰类中调用实体类方法或属性,还有装饰类自己新增的方法和属性
联系 装饰器模式=代理模式+装饰方法

桥接模式:blog.csdn.net/qq_36963950…

代理模式:blog.csdn.net/qq_36963950…

装饰器模式:blog.csdn.net/qq_36963950…

 

上一篇:设计模式(七)——桥接模式

下一篇:设计模式(九)——装饰器模式