1. 程式人生 > >JAVA的23種設計模式---代理模式(一)

JAVA的23種設計模式---代理模式(一)

概要:

該文章參考了《設計模式之禪》一書及一些前輩的部落格文章

1.該文章闡述了代理模式的基礎原理及示例程式碼;
2.該文章適合初學設計模式的技術人員研習;
3.該文章有許多不足之處,請各位大咖指正,噴子繞道;
4.該文章後續《JAVA的23種設計模式—代理模式(二)》,點此跳轉到第二部分

正文:

代理模式:為其他物件提供一種代理以控制對這個物件的訪問

1.代理模式原理示例程式碼:

package com.csdn;
/**
 * 抽象開店
 * @author Administrator
 *
 */
public interface Shop {
    //開門營業
    public
void openTheDoor(); //賣東西 public void sell(); //關門打烊 public void closeTheDoor(); }
package com.csdn;
/**
 * 具體的一家店
 * @author Administrator
 *
 */
public class Boss implements Shop {
    //店主名字
    private String name = "";
    //帶參構造器
    public Boss(String _name) {
        this.name = _name;
    }
    //店門開啟方法
@Override public void openTheDoor() { System.out.println(this.name+"的店門打開了.."); } //營業、賣東西方法 @Override public void sell() { System.out.println(this.name+"的店開始出售東西.."); } //關門打烊方法 @Override public void closeTheDoor() { System.out.println(this
.name+"的店門關上了.."); } }
package com.csdn;
/**
 * 代理開店服務
 * @author Administrator
 *
 */
public class BossProxy implements Shop {

    private Shop boss = null;
    //獲取需要代理服務的店的資訊
    public BossProxy(Shop _boss){
        this.boss = _boss;
    }
    //代理開啟店門方法
    @Override
    public void openTheDoor() {
        this.boss.openTheDoor();
    }
    //代理營業、賣東西方法
    @Override
    public void sell() {
        this.boss.sell();
    }
    //代理關門打烊方法
    @Override
    public void closeTheDoor() {
        this.boss.closeTheDoor();
    }
}
package com.csdn;
/**
 * 模擬代理經營店鋪
 * @author Administrator
 *
 */
public class Business {
    public static void main(String[] args) {
        //初始化“小明”的店鋪
        Boss boss = new Boss("小明");
        //“小明”的店鋪需要代理服務
        BossProxy proxy = new BossProxy(boss);
        //代理開啟小明的店門
        proxy.openTheDoor();
        //代理幫小明賣東西
        proxy.sell();
        //代理關上小明的店門
        proxy.closeTheDoor();
    }
}

輸出:

小明的店門打開了..
小明的店開始出售東西..
小明的店門關上了..

注:通過代理來訪問真實角色

2.普通代理模式示例程式碼:

package com.csdn;
/**
 * 抽象開店
 * @author Administrator
 *
 */
public interface Shop {
    //開門營業
    public void openTheDoor();
    //賣東西
    public void sell();
    //關門打烊
    public void closeTheDoor();
}
package com.csdn;
/**
 * 具體的一家店
 * @author Administrator
 *
 */
public class Boss implements Shop {
    //店主名字
    private String name = "";
    //構造器限制誰能建立物件,並同時傳遞店主名
    public Boss(Shop shop,String _name)throws Exception {
        if(shop == null){
            throw new Exception("不能建立一個店鋪");
        }else{
            this.name = _name;
        }
    }
    //店門開啟方法
    @Override
    public void openTheDoor() {
        System.out.println(this.name+"的店門打開了..");
    }
    //營業、賣東西方法
    @Override
    public void sell() {
        System.out.println(this.name+"的店開始出售東西..");
    }
    //關門打烊方法
    @Override
    public void closeTheDoor() {
        System.out.println(this.name+"的店門關上了..");
    }
}
package com.csdn;
/**
 * 代理開店服務
 * @author Administrator
 *
 */
public class BossProxy implements Shop {

    private Shop boss = null;
    //通過建構函式來傳遞對誰的店進行代理
    public BossProxy(String _boss){
        try {
            boss = new Boss(this, _boss);
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
    //代理開啟店門方法
    @Override
    public void openTheDoor() {
        this.boss.openTheDoor();
    }
    //代理營業、賣東西方法
    @Override
    public void sell() {
        this.boss.sell();
    }
    //代理關門打烊方法
    @Override
    public void closeTheDoor() {
        this.boss.closeTheDoor();
    }
}
package com.csdn;
/**
 * 模擬代理經營店鋪
 * @author Administrator
 *
 */
public class Business {
    public static void main(String[] args) {
        //“小明”的店鋪需要代理服務
        Shop proxy = new BossProxy("小明");
        //代理開啟小明的店門
        proxy.openTheDoor();
        //代理幫小明賣東西
        proxy.sell();
        //代理關上小明的店門
        proxy.closeTheDoor();
    }
}

輸出:

小明的店門打開了..
小明的店開始出售東西..
小明的店門關上了..

注:
a:與第一個示例相比較,普通代理模式對店鋪類和代理類的構造器做了部分改動,更改後的結果是代理角色只要傳入代理者名字既可,無需說是替那個物件做代理。呼叫者只知道代理的存在,不用知道代理了誰
b:該做法遮蔽了真實角色的變更對高層模組的影響,真實角色想怎麼修改就怎麼修改
c:實際專案中一般是通過約定方式來禁止建立一個真實的角色,通過技術約束不利於系統維護

3.強制代理模式示例程式碼:

package com.csdn;
/**
 * 抽象開店
 * @author Administrator
 *
 */
public interface Shop {
    //開門營業
    public void openTheDoor();
    //賣東西
    public void sell();
    //關門打烊
    public void closeTheDoor();
    //每個店都可以找自己的代理
    public Shop getProxy();
}
package com.csdn;
/**
 * 具體的一家店
 * @author Administrator
 *
 */
public class Boss implements Shop {
    //店主名字
    private String name = "";
    //這個店的代理
    private Shop proxy = null;
    //帶參構造器
    public Boss(String _name) {
            this.name = _name;
    }
    //店門開啟方法
    @Override
    public void openTheDoor() {
        if(this.isProxy()){
            System.out.println(this.name+"的店門打開了..");
        }else{
            System.out.println("請使用指定的代理");
        }   
    }
    //營業、賣東西方法
    @Override
    public void sell() {
        if(this.isProxy()){
            System.out.println(this.name+"的店開始出售東西..");
        }else{
            System.out.println("請使用指定的代理");
        }   
    }
    //關門打烊方法
    @Override
    public void closeTheDoor() {
        if(this.isProxy()){
            System.out.println(this.name+"的店門關上了..");
        }else{
            System.out.println("請使用指定的代理");
        }       
    }
    //找到代理
    @Override
    public Shop getProxy() {
        this.proxy = new BossProxy(this);
        return this.proxy;
    }
    //判斷是否是代理在訪問
    private boolean isProxy(){
        if(this.proxy == null){
            return false;
        }else{
            return true;
        }
    }
}
package com.csdn;
/**
 * 代理開店服務
 * @author Administrator
 *
 */
public class BossProxy implements Shop {

    private Shop boss = null;
    //通過構造器傳遞使用者
    public BossProxy(Shop _boss){
        this.boss = _boss;      
    }
    //代理開啟店門方法
    @Override
    public void openTheDoor() {
        this.boss.openTheDoor();
    }
    //代理營業、賣東西方法
    @Override
    public void sell() {
        this.boss.sell();
    }
    //代理關門打烊方法
    @Override
    public void closeTheDoor() {
        this.boss.closeTheDoor();
    }
    //代理就是自身
    @Override
    public Shop getProxy() {
        return this;
    }
}
package com.csdn;
/**
 * 模擬代理經營店鋪
 * @author Administrator
 *
 */
public class Business {
    public static void main(String[] args) {
        //初始化“小明”的店鋪
        Boss boss = new Boss("小明");
        //小明開啟店門
        //輸出:請使用指定的代理
        boss.openTheDoor();
        //小明賣東西
        //輸出:請使用指定的代理
        boss.sell();
        //小明關閉店門
        //輸出:請使用指定的代理
        boss.closeTheDoor();

        //初始化“小明”的店鋪
        Boss boss2 = new Boss("小明");
        //獲得指定的代理
        Shop proxy = boss2.getProxy();
        //小明的代理開啟小明的店門
        //輸出:小明的店門打開了..
        proxy.openTheDoor();
        //小明的代理幫小明賣東西
        //輸出:小明的店開始出售東西..
        proxy.sell();
        //小明的代理關上小明的店門
        //輸出:小明的店門關上了..
        proxy.closeTheDoor();
    }
}

注:
a:這個示例主要增加了尋找自身代理的方法和判斷是否是代理在訪問的方法
b:強制代理概念就是從真實角色查詢到代理角色,不允許直接訪問真實角色