一、代理模式定义:为其他对象提供一种代理以控制对这个对象的访问。
二、组成:Subject抽象主题角色、RealSubject具体主题角色、Proxy代理主题角色(代理类)
三、通用UML图:
四、通用代码:
抽象主题角色:
package 代理模式;
public interface Subject {
public void request();
}
具体主题角色:
package 代理模式;
public class RealSubject implements Subject{
public void request() {
//需求
}
}
代理主题角色:
package 代理模式;
public class Proxy implements Subject {
private Subject real=null;
public Proxy() {
real=new Proxy();//默认的本体,为啥时proxy,暂时不清楚
}
public Proxy(Object obj) {
real=(Subject) obj;//指定本体,一般使用多态,,,,PS:本体的确定在高层模块中进行,“客户端”;
}
public void request() {
real.request();//代理人要调用本体的需求;
}
}
五、应用
1、远程代理:比如将“网络细节”隐藏起来,用户只考虑想要的结果即可。
2、虚拟代理:例如QQ的缩略图就是一个代理,本体就是点击后放大的图。
3、保护代理:代理类相当于网关,在某个对象本体访问某资源时,必须通过代理角色来代理访问,此时,代理类对传过来的参数“本体”进行核对,看是不是和实际本体对应,对应,可以操作,否则。。。(例如下面订单的例子)
4、智能引用:
六、具体示例:
①、小菜让别人替他追姑娘:
UML图:
实现代码:
1、抽象主题角色:
package 代理模式追姑娘;
public interface IPersons {
public void giveFlower();
public void giveWater();
public void giveChocolate();
}
2、具体主题角色:
package 代理模式追姑娘;
import 衣服搭配.Person;
public class BenTi implements IPersons {
private SchoolMeiMei meiMei=null;
public BenTi() {
}
public BenTi(SchoolMeiMei m) {
meiMei=m;
}
@Override
public void giveFlower() {
System.out.println(meiMei.getName()+",送你花花");
}
@Override
public void giveWater() {
// TODO Auto-generated method stub
System.out.println(meiMei.getName()+",给你喝水");
}
@Override
public void giveChocolate() {
System.out.println(meiMei.getName()+",给你吃巧克力");
}
}
3、代理主题角色:
package 代理模式追姑娘;
public class DaiLi implements IPersons {
private BenTi bt=null;
public DaiLi(SchoolMeiMei smm) {//这地方是用了默认的本体?传参这地方还不是很透彻;
bt=new BenTi(smm);
}
public DaiLi() {
}
@Override
public void giveFlower() {
bt.giveFlower();//调用本体的方法
}
@Override
public void giveWater() {
bt.giveWater();
}
@Override
public void giveChocolate() {
bt.giveChocolate();
}
}
4、美眉类:
package 代理模式追姑娘;
public class SchoolMeiMei {
private String name;
public SchoolMeiMei() {
}
public SchoolMeiMei(String name) {
this.name=name;
}
public String getName() {
return name;
}
}
5、情景类:
package 代理模式追姑娘;
public class Test {
public static void main(String[] args) {
SchoolMeiMei smm=new SchoolMeiMei("小美");
//没有具体本体,用的默认本体?,PS:看的资料说本体的确定要在高层模块,就是这里。
DaiLi dl=new DaiLi(smm);
dl.giveWater();
dl.giveFlower();
dl.giveChocolate();
}
}
②、远程代理(计算器)
UML图:一样的,,,,略,,,
1、抽象主题角色:
package 远程代理计算器;
public interface ICalculate {
public double add(double x,double y);
public double mul(double x,double y);
public double sub(double x,double y);
public double dev(double x,double y) ;
}
2、具体主题角色:
package 远程代理计算器;
public class CalculateBody implements ICalculate {
@Override
public double add(double x, double y) {
return x+y;
}
@Override
public double mul(double x, double y) {
return x*y;
}
@Override
public double sub(double x, double y) {
// TODO Auto-generated method stub
return x-y;
}
public double dev(double x, double y) {
//if(y-0<=1e-7)throw new Exception("除数不可为零");
return x/y;
}
}
3、代理主题角色:
package 远程代理计算器;
public class CalculateProxy implements ICalculate {
private CalculateBody cb=null;//这里好像写错了,用多态更好
public CalculateProxy() {
cb=new CalculateBody();
}
@Override
public double add(double x, double y) {
// TODO Auto-generated method stub
return cb.add(x, y);
}
@Override
public double mul(double x, double y) {
return cb.mul(x, y);
}
@Override
public double sub(double x, double y) {
// TODO Auto-generated method stub
return cb.sub(x, y);
}
@Override
public double dev(double x, double y) {
// TODO Auto-generated method stub
return cb.dev(x, y);
}
}
4、情景类:
package 远程代理计算器;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
int x,y;
x=cin.nextInt();
y=cin.nextInt();
CalculateProxy cp=new CalculateProxy();
double res=cp.add(x, y);
System.out.println(res);
}
}
③、安全控制示例(订单创建)
UML图都差不多,略,,,
1、抽象主题角色:
package 订单修改;
public interface IOrder {
public String getName();
public void setName(String name,IOrder body);//注意参数
public int getNumber();
public void setNumber(int number,IOrder body);
}
2、具体主题角色
package 订单修改;
public class OrderBody implements IOrder {
private String name;
private int number;
@Override
public String getName() {
return name;
}
@Override
public void setName(String name,IOrder body) {//注意参数的使用
this.name=name;
}
@Override
public int getNumber() {
return number;
}
@Override
public void setNumber(int number,IOrder body) {
this.number=number;
}
}
3、抽象主题角色
package 订单修改;
public class OrderProxy implements IOrder {
private IOrder order=null;
public OrderProxy() {
order=new OrderProxy();
}
public OrderProxy(OrderBody order) {
this.order=order;
}
@Override
public String getName() {
return order.getName();
}
@Override
public void setName(String name,IOrder body) {//注意参数的使用
if(body.equals(order)) {
order.setName(name, body);
}else {
try {
throw new Exception("用户不合法,不能修改名称!");
} catch (java.lang.Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public int getNumber() {
return order.getNumber();
}
@Override
public void setNumber(int number,IOrder body) {
if(body.equals(order)) {
order.setNumber(number, body);
}else {
try {
throw new Exception("用户不合法,不能修改数量!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
4、情景类
package 订单修改;
public class Client {
public static void main(String[] args) {
OrderBody body=new OrderBody();//ppt上嵌套来写
body.setName("订单A", body);
body.setNumber(100, body);
OrderBody body2=new OrderBody();//无权限者
IOrder proxy=new OrderProxy(body);
System.out.println(proxy.getNumber());//修改前
proxy.setNumber(200, body2);
System.out.println(proxy.getNumber());//不合法用户修改
proxy.setNumber(200, body);
System.out.println(proxy.getNumber());//合法用户修改
}
}
代理模式的优点:
职责清晰:真实主题角色只管实现实际的业务逻辑,不用关心其他非本职的事务。
高扩展性:具体主题角色可以根据需求的变换用不同的方式实现接口。
智能化:,,,
The end;