當我談Proxy與Adpater模式時,我談些什麼

當我談Proxy與Adpater模式時,我談些什麼

前言

今天跟同事談起了一道面試題:「Proxy模式跟Adpater模式的區別」,這兩個設計模式都是很類似的模式,不少有點經驗的程序員均可能會聊的頭頭是道,可是恐怕談起一些設計上的細節可能就會卡殼,所以我寫下了這篇文章,以此做爲一個簡短的回顧。java

Adapter(適配器)模式

Adpater屬於兩種適應設計模式中的其中一種,另一種是Iterator(迭代器)模式,下次有機會再仔細聊聊它。程序員

設計模式的書很喜歡以‘電源適配器插頭’做爲適配器模式的範例範例,那麼咱們也從這個例子開始吧。面試

參與模式的角色

1. Target (適配接口)

暴露給調用方的接口,定義了被適配對象暴露的方法。(咱們須要220V的電源)設計模式

2. Client (請求者)

實際須要使用接口的邏輯(某電器須要使用220V的電源)this

3. Adaptee(被適配對象)

被適配者,包含了具體的實現,及可能不太合適調用方使用的方法。(110V的電源不合適如今所用的電器)spa

4. Adpater(適配器)

實際適配的實現,用繼承的方式隱藏了被適配對象的實現,又以實現適配接口的方式暴露調用者適合的方法。設計

UML類圖

image

範例代碼

下面的代碼實現了一個輸出110V的電源,經過220V電源適配器,實現了一個符合22V標準接口的輸出,提供給客戶端的示範。代理

#  adpatee
public class Power110v {

    private int volte = 110;
    
    public Power110v(){
        System.out.print("the power is on at "+volte+"V");
    }
    
    public String get100vPower(){
        return volte;    
    }
    
}

# target
public interface Power220v {
    get220vPower(String input);
}

# adapter 
public PowerAdpater extends Power110v implemnts Power220v {
    
    public get220vPower(){
        volte = volte * 2;
        System.out.println("the power is on at "+volte+"V")
    }
    
}

#client
public class Main (){
    
    public static void main(String[] args){
    
        PowerAdapter pa = new PowerAdapter();
        pa.get220vPower();
        
    }
    
}

小結

Adapter模式適用於那些已有代碼很穩定,但新調用方須要對部分代碼進行調整,或者組合多個方法進行組合實現邏輯的狀況下適用。能夠儘可能適用已有的穩定代碼,只做適當的修改即可以完成新的邏輯功能。code

Proxy模式

參與模式的角色

1. Client

使用proxy的角色,功能的調用方,下面的例子是Manager(經理)類。對象

2. Subject

定義了proxy角色與RealSubject的一致性接口,範例代碼中,是Reportable(可彙報)接口,

3. Proxy

Proxy會處理來自Client的請求,能夠處理的功能本身處理,不能處理的功能讓RealSubject處理,範例代碼是TeamLeader類。

4. RealSubject

RealSubject將會在Proxy缺少功能時提供實現,跟Proxy同樣實現一樣的接口,範例代碼中是TeamMember類。

UML

image

範例代碼

public interface Reportable{
    public void setReportMatrial(String jobContent);
    public String getReportMatrial();
    public String getFeedback();
}

public TeamMember implements Reportable{
    String reportMatrial;
    
    public void setReportMatrial(String input){
        this.reportMatrial = input;
    }
    
    public String getReportMatrial(){
        return this.reportMatrial;
    }
    
    public String getFeedback(){
        return "Here is the report content ["+this.reportMatrial+"]";
    }
}
    
}

public TeamLeader implements Reportable{

    String reportMatrial;
    TeamMember member;
    
    public TeamLeader(String input){
        this.reportMatrial = input;
    }
    
    public void setReportMatrial(String input){
        if (member != null){
            member.setReportMatrial(input)
        }
        this.reportMatrial = input;
    }
    
    public String getReportMatrial(){
        return this.reportMatrial;
    }
    
    public String getFeedback(){
        if ( member != null ){
            return member.getFeedback();
        }
        member = new TeamMember();
        member.setReportMatrial(this.reportMatrial);
    }
    
    
}

public class Manager {
    public static void main(String[] args){
        TeamLeader tl = new TeamLeader("monthly report");
        tl.setReportMatrial("weekly report")
        String currentReportType = tl.getReportMatrial();
        // the manager forgot what kind report should receive
        System.out.println("the current report type is " + currentReportType);
        // the manager ask the teamleader for the report detail.
        System.out.println("get some report from team leader"tl.getFeedback());
    }
}

Proxy與Adpater的總結

相同點

二者頭經過實現接口暴露實際邏輯給調用方,核心邏輯都在最內一層的類中。

不一樣點

Proxy實現subject類與proxy類,都是實現同樣的接口,暴露同樣的方法。Adpater模式則Adpater與Adpatee則不必定實現一樣的方法。理論上Proxy模式的proxy類,也承擔一部分的功能,當它沒法實現調用功能時纔會建立被代理的RealSubject類。Adpater類則原則上與Adpatee共存亡。

參考資料

相關文章
相關標籤/搜索