設計模式 - 代理人模式 (Structural Patterns - Proxy Design Pattern)

設計模式 - 代理人模式 (Structural Patterns - Proxy Design Pattern)

前言

在開始前我們先想想代理人這個詞彙,在中文我們用到代理人時通常都在甚麼時機呢?

  • 當將軍要出席敵國晚宴時,可能會找個長的和他很像的人當作代理人
    • 如果是鴻門宴的話,將軍還是安全的
  • 當老闆出國度假時,他可能需要一個職務代理人
    • 可以幫他篩選那些事情需要打給他

所以代理人通常代表著

  • 保護本體
  • 可以做決定的篩選

而Desing Pattern的Proxy也是相似概念

  • 保護本體物件 (決定誰可以Accesdd/接觸到此物件)
  • 在Access到本體時,會有一層篩選

類別圖

  • 對需要做Proxy的物件切分出介面和實作
  • 將Proxy一同實作此介面 (讓Proxy和被代理的物件可以做到互換)
  • 客戶端在呼叫時呼叫此Proxy介面

範例

以英雄遊戲中的玩家加入聯盟為範例,我們可以透過Proxy讓我們的聯盟物件包持單一原則,只做加入跟退出,而目前的其他檢驗就由Proxy做掉。

import java.util.HashSet;
import java.util.Set;

interface Team {
    boolean join(String name);

    boolean quit(String name);
}

class League implements Team {

    private Set<String> heroSet = new HashSet<>();

    @Override
    public boolean join(String name) {
        return heroSet.add(name);
    }

    @Override
    public boolean quit(String name) {
        return heroSet.remove(name);
    }

    public boolean isExist(String name) {
        return heroSet.contains(name);
    }
}

class LeagueProxy implements Team {

    League league = new League();

    @Override
    public boolean join(String name) {
        if (league.isExist(name)) {
            return false;
        }
        return league.join(name);
    }

    @Override
    public boolean quit(String name) {
        if (league.isExist(name)) {
            return league.quit(name);
        }
        return false;
    }
}


public class Proxy {

    public static void main(String[] args) {
        Team league = new LeagueProxy();

        System.out.println(league.join("HeroA"));
        System.out.println(league.join("HeroB"));
        System.out.println(league.join("HeroA"));
        System.out.println(league.quit("HeroC"));
    }
}

原始碼下載

結果

  • 如果物件是敏感資料,則可以使用Proxy來保護他
  • 我個人常用Proxy去紀錄method Log

留言

這個網誌中的熱門文章

Java Lambda Map篇

(InterviewBit) System Design - Design Cache System

設計模式 - 享元模式 (Structural Patterns - Flyweight Design Pattern)