定義:
- 為其他對象提供一種代理以控制對這個對象的訪問卦睹。
通用類圖:
/*
* 定義一個抽象的主題類
* */
public interface Subject {
// 定義一個方法
public void request();
}
public class RealSubject implements Subject {
@Override
public void request() {
// 定義具體的業(yè)務(wù)邏輯
}
}
/*
* 實現(xiàn)相關(guān)的代理類
* */
public class Proxy implements Subject {
private Subject subject;
public Proxy(Subject subject) {
this.subject = subject;
}
@Override
public void request() {
// TODO Auto-generated method stub
doBefore();
subject.request();
doAfter();
}
private void doBefore() {
}
private void doAfter() {
}
}
代理模式的優(yōu)點:
代理模式的拓展:
- 普通代理模式(調(diào)用者知道代理的存在见坑,同時知道代理的名字,但是不知道代理的是誰):
public interface IGamePlayer {
void login(String user, String password);
void killBoss();
void upgrade();
}
public class GamerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;
public GamerProxy(String name) {
// TODO Auto-generated constructor stub
try {
gamePlayer = new GamerPlayer(this, name);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void login(String user, String password) {
// TODO Auto-generated method stub
this.gamePlayer.login(user, password);
}
@Override
public void killBoss() {
// TODO Auto-generated method stub
this.gamePlayer.killBoss();
}
@Override
public void upgrade() {
// TODO Auto-generated method stub
this.gamePlayer.upgrade();
}
}
public class GamerPlayer implements IGamePlayer {
private String name = "";
public <T extends GamerProxy> GamerPlayer(T t, String name) throws Exception {
// TODO Auto-generated constructor stub
if (t == null) {
throw new Exception("不能創(chuàng)建對應(yīng)的用戶!");
} else {
this.name = name;
}
}
@Override
public void login(String user, String password) {
// TODO Auto-generated method stub
System.out.println(user + "" + name + "" + password);
}
@Override
public void killBoss() {
// TODO Auto-generated method stub
System.out.println(name + "killBoss");
}
@Override
public void upgrade() {
// TODO Auto-generated method stub
System.out.println(name + "upgrade");
}
}
- 強制代理模式(只能通過真實角色指定的代理類才能訪問,也就是說由真實角色管理代理角色,即高層模塊new了一個真實的對象鲜结,但是返回的確是代理角色)
public interface IGamePlayer {
void login(String user, String password);
void killBoss();
void upgrade();
IGamePlayer getProxy();
}
public class GamerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;
public <T extends GamerProxy> GamerProxy(GamerPlayer gamerPlayer) {
// TODO Auto-generated constructor stub
this.gamePlayer = gamePlayer;
}
@Override
public void login(String user, String password) {
// TODO Auto-generated method stub
this.gamePlayer.login(user, password);
}
@Override
public void killBoss() {
// TODO Auto-generated method stub
this.gamePlayer.killBoss();
}
@Override
public void upgrade() {
// TODO Auto-generated method stub
this.gamePlayer.upgrade();
}
@Override
public IGamePlayer getProxy() {
// TODO Auto-generated method stub
return this;
}
}
public class GamerPlayer implements IGamePlayer {
private String name = "";
private IGamePlayer proxy;
public GamerPlayer(String name) {
// TODO Auto-generated constructor stub
this.name = name;
}
@Override
public void login(String user, String password) {
// TODO Auto-generated method stub
if (isProxy()) {
System.out.println("login");
} else {
System.out.println("failed");
}
}
@Override
public void killBoss() {
}
@Override
public void upgrade() {
}
@Override
public IGamePlayer getProxy() {
this.proxy = new GamerProxy(this);
return this.proxy;
}
private boolean isProxy() {
if (this.proxy == null) {
return false;
} else {
return true;
}
}
}
public class Client {
public static void main(String[] args) {
IGamePlayer gamer = new GamerPlayer("zhangsan");
IGamePlayer gamerProxy = gamer.getProxy();
gamerProxy.login("", "");
}
}
- 增加接口整合不同的任務(wù)(圖片少一個getProxy( )方法瘸爽,參照上圖)
public interface IProxy {
// 計算費用
public void count();
}
public class GamerProxy implements IGamePlayer,IProxy {
private IGamePlayer gamePlayer = null;
public <T extends GamerProxy> GamerProxy(GamerPlayer gamerPlayer) {
// TODO Auto-generated constructor stub
this.gamePlayer = gamePlayer;
}
@Override
public void login(String user, String password) {
// TODO Auto-generated method stub
this.gamePlayer.login(user, password);
}
@Override
public void killBoss() {
// TODO Auto-generated method stub
this.gamePlayer.killBoss();
}
@Override
public void upgrade() {
// TODO Auto-generated method stub
this.gamePlayer.upgrade();
this.count();
}
@Override
public IGamePlayer getProxy() {
// TODO Auto-generated method stub
return this;
}
@Override
public void count() {
// TODO Auto-generated method stub
System.out.println("總費用");
}
}
- 動態(tài)代理:實現(xiàn)階段不用關(guān)心代理誰您访,而在運行階段才指定代理哪一個對象。(面向截面編程AOP的核心剪决,被代理類實現(xiàn)必須實現(xiàn))
public interface IAdvice {
// 通知方法
public void exec();
}
public class BeforeAdvice implements IAdvice {
@Override
public void exec() {
// TODO Auto-generated method stub
System.out.println("前置通知");
}
}
public interface Subject {
// 業(yè)務(wù)操作
public void doSomething(String str);
}
public class ResultSubject implements Subject {
@Override
public void doSomething(String str) {
// TODO Auto-generated method stub
System.out.println("具體實際的操作方法");
}
}
public class DynamicProxy<T> {
public static <T> T newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h){
//尋找JoinPoint鏈接點灵汪,AOP框架使用元數(shù)據(jù)定義
if(true){
//執(zhí)行前置通知
(new BeforeAdvice()).exec();
}
//執(zhí)行目標,并返回結(jié)果
return (T)Proxy.newProxyInstance(loader, interfaces, h);
}
}
public class SubjectDynamicProxy extends DynamicProxy {//根據(jù)不同的主題進行二次封裝
public static <T> T newProxyInstance(Subject subject){
//獲取ClassLoader
ClassLoader loader = subject.getClass().getClassLoader();
//獲取接口數(shù)據(jù)
Class<?>[] classes = subject.getClass().getInterfaces();
//獲取handler
DemoInvocationHandler demoIH = new DemoInvocationHandler(subject);
return newProxyInstance(loader, classes, demoIH);
}
}
public class DemoInvocationHandler implements InvocationHandler {
// 被代理的對象
private Object target = null;
// 通過構(gòu)造函數(shù)傳遞一個對象
public DemoInvocationHandler(Object object) {
// TODO Auto-generated constructor stub
this.target = object;
}
// 代理方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
// 被代理的方法
return method.invoke(this.target, args);
}
}
public class Client {//兩種方式
public static void main(String[] args) {
// 定義主題
Subject subject = new ResultSubject();
// 定義主題代理類
Subject proxy = SubjectDynamicProxy.newProxyInstance(subject);
proxy.doSomething("");
///////////////////////////////////////
// 定義主題
Subject subjectTwo = new ResultSubject();
// 定義handler
InvocationHandler iH = new DemoInvocationHandler(subjectTwo);
// 定義主題代理類
Subject proxyTwo = DynamicProxy.newProxyInstance(subjectTwo.getClass().getClassLoader(),
subjectTwo.getClass().getInterfaces(), iH);
proxyTwo.doSomething("");
}
}