設計模式Android 其他相關文章:
【設計模式Android】設計模式六大原則
定義:為其他對象提供一種代理以控制這個對象的訪問
代理模式中的角色
Subject抽象主題
抽象主題可以是一個抽象類也可以是一個接口。
public interface Subject{
public void doSomeThing();
}
RealSubject具體實例
被代理的角色,是邏輯的具體執(zhí)行者。
public class RealSubject implements Subject{
@Override
public void doSomeThing() {
//do some things
}
}
代理類
用來代理實際類執(zhí)行邏輯
public class Proxy implements Subject{
private Subject subject = null;
public Proxy(){
subject = new RealSubject();
}
@Override
public void doSomeThing() {
subject.doSomeThing();
}
}
舉個例子
在這里我們舉這樣一個例子。
比如我們在玩游戲的時候希望找個代練,代替我們升級打怪。這個這個代練就可以認為是一個代理。
我們可以簡單寫一下做個對比:
Subject抽象主題類
我們在這里定義一下游戲玩家的抽象行為:
public interface IGame {
public void attack();
public void move();
public void dead();
public void update();
}
RealSubject真是主題類
在這里我們定義下玩家的實際行為:
public class GamePlayer implements IGame
{
private String name;
public GamePlayer(String name){
this.name = name;
}
@Override
public void attack() {
System.out.println(name+"正在"+"攻擊");
}
@Override
public void move() {
System.out.println(name+"正在"+"行走");
}
@Override
public void dead() {
System.out.println(name+"已經"+"死亡");
}
@Override
public void update() {
System.out.println(name+"已經"+"升級");
}
}
代理類
現(xiàn)在需要找一個類替我們去執(zhí)行我們要執(zhí)行的行為。
public class GamePlayerProxy implements IGame {
private IGame player = null;
public GamePlayerProxy(IGame player){
this.player = player;
}
@Override
public void attack() {
player.attack();
}
@Override
public void move() {
player.move();
}
@Override
public void dead() {
player.dead();
}
@Override
public void update() {
player.update();
}
}
實例化執(zhí)行
我們現(xiàn)在看一下應該如何在程序中調用:
public class Main {
public static void main(String[] args) {
IGame player = new GamePlayer("deep");
IGame proxy = new GamePlayerProxy(player);
proxy.move();
proxy.attack();
proxy.update();
proxy.dead();
}
}
為什么要用代理模式
有些開發(fā)者看了這篇文章可能會問,我們在寫程序中,為什么要用代理模式,我們直接商用上面提到的真是主題類RealSubject不就行了嗎?
可以是可以,但是不符合我們之前提到過的設計原則(【設計模式Android】設計模式六大原則)
隔離原則
在某些情況下,一個對象不適合或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用, 其特征是代理類與委托類有同樣的接口。
開閉原則
代理類不僅僅是一個隔離客戶端和委托類的中介。我們還可以借助代理來在增加一些功能,而不需要修改原有代碼,嚴重的復合開閉原則哦。
優(yōu)點:
- 職責清晰,RealSubject只處理實際業(yè)務邏輯,不用關心其它。
- 高擴展性,復合開閉原則,方便進行修改
拓展
普通代理
客戶端只訪問代理,不訪問真實角色。
就如同上文中舉的例子一樣。調用者只知道代理而不知道真實角色,我們修改一下上面的例子:
public class GamePlayerProxy implements IGame {
private IGame player = null;
public GamePlayerProxy(String name){
this.player = new GamePlayer(name);
}
@Override
public void attack() {
player.attack();
}
@Override
public void move() {
player.move();
}
@Override
public void dead() {
player.dead();
}
@Override
public void update() {
player.update();
}
}
修改一下調用,可以看出:
public class Main {
public static void main(String[] args) {
IGame proxy = new GamePlayerProxy("deep");
proxy.move();
proxy.attack();
proxy.update();
proxy.dead();
}
}
強制代理
強制代理比較特殊,它是通過真實角色找到代理角色,我們還是修改一下上面的例子的代理類:
public class GamePlayer implements IGame
{
private String name;
private IGame proxy = null;
public GamePlayer(String name){
this.name = name;
}
public IGame getProxy() {
this.proxy = new GamePlayerProxy(this);
return this.proxy;
}
@Override
public void attack() {
if (this.getProxy()!=null){
System.out.println(name+"正在"+"攻擊");
}else {
System.out.println("請指定代理");
}
}
@Override
public void move() {
if (this.getProxy()!=null) {
System.out.println(name + "正在" + "行走");
}else {
System.out.println("請指定代理");
}
}
@Override
public void dead() {
if (this.getProxy()!=null) {
System.out.println(name + "已經" + "死亡");
}else {
System.out.println("請指定代理");
}
}
@Override
public void update() {
if (this.getProxy()!=null) {
System.out.println(name + "已經" + "升級");
}else {
System.out.println("請指定代理");
}
}
private boolean isProxy(){
if (this.proxy == null){
return false;
}else {
return true;
}
}
}
增加一個私有方法,檢查是否有指定的代理。通過這個方式你可以看出,你想繞過代理直接訪問真實的類,但是,真實類,還是給你返回代理。我們訪問如下:
public class Main {
public static void main(String[] args) {
IGame player = new GamePlayer("deep");
player.move();
player.attack();
player.update();
player.dead();
}
}
總結
代理模式跟中介者模式容易搞混,之后的文章我們會再介紹一下中介者模式,并進行一下對比。