一、代理模式的定义
代理模式是一个使用率非常高的模式 :
为其他对象提供一种代理以控制对这个对象的访问。
1、Sudject 抽象主题角色
抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。
public interface Subject { //定义一个方法 public void request(); }
2、RealSubject 具体主题角色
也叫做被委托角色、被代理角色。它才是业务逻辑的具体执行者。
public class RealSubject implements Subject { //实现方法 public void request() { //业务逻辑处理 } }
3、Prixy 代理主题角色
也叫做委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
public class Proxy implements Subject { //要代理哪个实现类 private Subject subject = null; //默认被代理者 public Proxy(){ this.subject = new Proxy(); } //通过构造函数传递代理者 public Proxy(Object...objects ){} //实现接口中定义的方法 public void request() { this.before(); this.subject.request(); this.after(); } //预处理 private void before(){ //do something } //善后处理 private void after(){ //do something } }
二、代理模式的优点
1、职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰。
2、高扩展性
具体主题角色是随时都会发生变化的,只要它实现了接口,甭管它如何变化,都逃不脱如来佛的手掌(接口),那我们的代理类完全就可以在不做任何修改的情况下使用。
3、 智能化
这在我们以上的讲解中还没有体现出来,不过在我们以下的动态代理章节中你就会看到代理的智能化有兴趣的读者也可以看看Struts是如何把表单元素映射到对象上的。
三、代理模式的使用场景
我相信第一次接触到代理模式的读者肯定很郁闷,为什么要用代理呀?想想现实世界吧,打官司为什么要找个律师?因为你不想参与中间过程的是是非非,只要完成自己的答辩就成,其他的比如事前调查、事后追查都由律师来搞定,这就是为了减轻你的负担。代理模式的使用场景非常多,大家可以看看Spring AOP,这是一个非常典型的动态代理。
代码
引子 : 现在这个时代大家基本上都有玩游戏当然感觉现在最火的应该是王者荣耀吧 , 在公司里吃饭的时候和同事来撸一把增进增进大家之间的 “团结” ,我们今天就通过游戏的方式来给大家介绍并学习一下代理模式。
游戏者接口
package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.daili;
/**
* Created by liangshaoteng on 17-7-24.
*/
public interface IGamePlayer {
//游戏登录
public void login(String user, String password);
//开撸
public void killBoss();
//排位升级
public void upgradle();
}
游戏者
package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.daili;
/**
* Created by liangshaoteng on 17-7-24.
*/
public class GamePlayer implements IGamePlayer {
private String name="";
public GamePlayer(String name) {
this.name = name;
}
@Override
public void login(String user, String password) {
System.out.println("登录名为"+user+"的用户"+this.name+"登录成功!");
}
@Override
public void killBoss() {
System.out.println(this.name + "正在游戏中!");
}
@Override
public void upgradle() {
System.out.println(this.name + " 排位等级升了一星!");
}
}
游戏场景
package com.example.liangshaoteng.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.daili.GamePlayer;
import com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.daili.IGamePlayer;
import com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.jianzhaozhe.BenzModel;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IGamePlayer iGamePlayer = new GamePlayer("活力の邮筒");
iGamePlayer.login("liangshaoteng","123456");
//正在游戏中
iGamePlayer.killBoss();
//排位升级
iGamePlayer.upgradle();
}
}
运行结果 :
登录名为liangshaoteng的用户 活力の邮筒登录成功!
活力の邮筒正在游戏中!
活力の邮筒排位等级升了一星!
OK可以正常吃的玩游戏,但是我们过一段时间发现我们现实中我们的排位等级一直上不上去 , 然找代练 下面给大家看一下代码是怎么找代练的
代练者
package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.daili;
/**
* Created by liangshaoteng on 17-7-24.
*/
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer iGamePlayer;
//给谁进行代练
public GamePlayerProxy(IGamePlayer iGamePlayer) {
this.iGamePlayer = iGamePlayer;
}
//代练登录
@Override
public void login(String user, String password) {
this.iGamePlayer.login(user,password);
}
//代练游戏中
@Override
public void killBoss() {
this.iGamePlayer.killBoss();
}
//代练升级
@Override
public void upgradle() {
this.upgradle();
}
}
修改后的场景类
package com.example.liangshaoteng.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.daili.GamePlayer;
import com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.daili.GamePlayerProxy;
import com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.daili.IGamePlayer;
import com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.jianzhaozhe.BenzModel;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IGamePlayer iGamePlayer = new GamePlayer("]");
GamePlayerProxy gamePlayerProxy = new GamePlayerProxy(iGamePlayer);
gamePlayerProxy.login("liangshaoteng","123456");
//正在游戏中
gamePlayerProxy.killBoss();
//排位升级
gamePlayerProxy.upgradle();
}
}
运行结果 :
登录名为liangshaoteng的用户 活力の邮筒登录成功!
活力の邮筒正在游戏中!
活力の邮筒排位等级升了一星!
好了,你会发现好像没有什么区别啊,但是你有没有发觉你的游戏已经在升级,并且有人帮你在干活啦! 这就是代理模式。