代理模式(Proxy)
动机:在面向对象时,有些对象由于某种原因,直接访问会给使用者,或者系统结构带来很多麻烦。
增加一层间接层是软件开发中面对不失去透明操作对象的同时来管理/控制这些对象特有的负责性问题常见的解决方法。
案例:送花。
1 男一给女一送花,送巧克力,送洋娃娃
2.男一找男二把花,巧克力和洋娃娃送给女一
两种方式,达到的目的是一样的。
import java.util.*;
class SchoolGirl
{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Pursuit
{
SchoolGirl mm;
public Pursuit(SchoolGirl mm)
{
this.mm=mm;
}
public void GiveDolls()
{
System.out.println(mm.getName()+"送你洋娃娃");
}
}
//加入代理
class Proxy1
{
SchoolGirl mm;
public Proxy1(SchoolGirl mm)
{
this.mm=mm;
}
public void GiveDolls()
{
System.out.println(mm.getName()+"送你洋娃娃");
}
}
public class main
{
public static void main(String[] args) {
SchoolGirl jiaojiao=new SchoolGirl();
jiaojiao.setName("李娇娇");
Pursuit nanyi=new Pursuit(jiaojiao);
nanyi.GiveDolls();
//从代码上看男一直接把东西送给娇娇,男一和娇娇是认识的。但是娇娇不认识男一。
/*Proxy1 daili=new Proxy1(jiaojiao);
daili.GiveDolls();*///这样写表示为代理送给娇娇东西,没有男一的事了
}
}
综上:Pursuit 和 Proxy应该实现相同的接口,两者行为一样,代理送的礼物是男一买的。所以,用面向对象的思想考虑要把变化点抽象出来。
class SchoolGirl
{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
interface Givegift
{
void GiveDolls();
}
class Pursuit implements Givegift
{
SchoolGirl mm;
public Pursuit(SchoolGirl mm)
{
this.mm=mm;
}
public void GiveDolls()
{
System.out.println(mm.getName()+"送你洋娃娃");
}
}
//加入代理
class Proxy1 implements Givegift
{
Pursuit gg;
public Proxy1(SchoolGirl mm)
{
gg=new Pursuit(mm);
}
public void GiveDolls()
{
gg.GiveDolls();
}
}//代理替男一送礼物
public class main
{
public static void main(String[] args) {
SchoolGirl jiaojiao=new SchoolGirl();
jiaojiao.setName("李娇娇");
Proxy1 daili=new Proxy1(jiaojiao);
daili.GiveDolls();
}
}
代理模式,为其他对象提供一种代理以控制对这个对象的访问。
- 抽象主题角色:声明了真实主题和代理主题的共同接口,这样在任何使用真实主题的地方都可以使用代理主题。
- 代理主题角色: 代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象。
- 真实主题角色: 定义了代理角色所代表的真实对象
abstract class Subject
{
public abstract void Request();
}
class RealSubject extends Subject
{
public void Request()
{
System.out.println("真实的请求");
}
}
class Proxy extends Subject
{
RealSubject realSubject;
@Override
public void Request() {
// TODO Auto-generated method stub
if(realSubject==null)
{
realSubject=new RealSubject();
}
realSubject.Request();
}
}
public class main
{
public static void main(String[] args) {
Proxy proxy=new Proxy();
proxy.Request();
}
}
注意:
在软件系统中,无时不在跨越障碍:
当访问网络上一台计算机资源时,需要跨越网络的障碍,
当访问服务器上数据库的时候,需要跨越数据库访问障碍还有网络障碍
Proxy模式有助于解决这些问题
简单的数学计算
interface IMath
{
double Add(double x,double y);
double Sub(double x,double y);
double Mul(double x,double y);
double Dev(double x,double y);
}
class Math implements IMath//如果Math类并没有部署在本地上,而是部署在一台服务器上,也就是说Math类与客户程序不在同一个地址空间内,现在要面对一个跨越Internt的一个网络障碍
{
public double Add(double x,double y)
{
return x+y;
}
public double Sub(double x,double y)
{
return x-y;
}
public double Mul(double x,double y)
{
return x*y;
}
public double Dev(double x,double y)
{
return x/y;
}
}
class MathProxy implements IMath
{
private Math math;
public MathProxy()
{
math=new Math();
}
public double Add(double x,double y)
{
return math.Add(x, y);
}
public double Sub(double x,double y)
{
return math.Sub(x, y);
}
public double Mul(double x,double y)
{
return math.Mul(x, y);
}
public double Dev(double x,double y)
{
return math.Dev(x, y);
}
}
public class main
{
public static void main(String[] args) {
MathProxy proxy=new MathProxy();
double addresult = proxy.Add(2, 3);
double subresult = proxy.Sub(2, 3);
double mulresult = proxy.Mul(2, 3);
double devresult = proxy.Dev(2, 3);
}
}
回顾整个过程,无非是在客户端程序和Math类之间加了个间接层,这也是比较常见的解决问题的手段之一。
大多数情况下,为了保持对对象操作的透明性,并强制实现类实现代理类所要调用的所有方法,会让它们实现同一个接口。
但是代理类其实只是在一定程度上代表了原来的实现类,所以他们有时候也可以不实现同一个接口。
代理模式本质
用来控制对象的访问