Extract Interface (提煉接口)

Summary:若干客戶使用類接口中的同一子集,或者兩個類的接口有相同部分。將相同的子集提煉到一個獨立接口中。                                java

 動機程序員

類之間彼此相互用的方式有若干種。「使用一個類」一般意味用到該類的全部責任區。另外一種狀況是,某一組客戶只使用類責任區中的一個特定子集。再一種狀況則是,這個類須要與全部協助處理某些特定請求的類合做。函數

對於後兩種狀況,將真正用到的這部分責任分離出來一般頗有意義,由於這樣可使系統的用法更清晰,同時也更容易看清系統的責任劃分。若是新的類須要支持上述子集,也比較可以看清子集內有些什麼東西。spa

在許多面向對象語言中,這種責任劃分是經過多繼承(multiple inheritance)來實現的。你能夠針對每組行爲創建一個類,再將它們組合於同一個實現中。Java只提供單繼承(single inheritance),但你能夠運用接口來昭示並事項上述需求。接口對於java 程序的設計方式有着巨大的影響,就連Smalltalk程序員都認爲接口是一大進步。設計

Extract Superclass Extract Interface之間有些類似之處。Extract Interface 只能提煉共通接口,不能提煉共通代碼。使用Extract Interface可能形成難聞的「重複」壞味道,幸而你能夠運用Extract Class 先把共通行爲放進一個組件中,而後將工做委託該組件,從而解決這個問題。若是有很多共通行爲,Extract Superclass會比較簡單,可是每一個類只能有一個超類。code

若是某個類在不一樣環境下扮演大相徑庭的角色,使用接口就是個好主意。你能夠針對每一個角色以Extract Interface提煉出相應接口。另外一種能夠用上Extract Interface的狀況是:你想要描述一個類的外部依賴接口(outbound interface,即這個類要求服務提供方提供的操做)。若是你打算未來加入其餘種類的服務對象,只須要求它們實現這個接口便可。對象

作法 繼承

1.新建一個空接口接口

2.在接口中聲明待提煉類的共通操做。ip

3.讓相關的類實現上述接口

4.調整客戶端的類型聲明,令其使用該接口。

範例:

TimeSheet類表示員工爲客戶工做的時間表,從中能夠計算客戶應該支付的費用。爲了計算這筆費用,TimeSheet須要知道員工級別,以及員工是否有特殊技能

double charge(Employee emp,int days){
    int base = emp.getRate() * days;
    if(emp.hasSpecialSkill()){
        return base * 1.05;
    }else{
        return base;
    }
}

除了提供員工的級別和特殊技能信息外,Employee還有不少其餘方面的功能,但本應用程序只需這兩項功能。咱們能夠針對這兩項功能定義一個接口,從而強調「我只須要這部分功能」的事實:

interface Billable{
    public int getRate();
    public boolean hasSpecialSkill();
}

而後,聲明讓Employee實現這個接口

class Employee implements Billable

完成之後,修改charge()函數聲明,強調改函數只使用Employee的這部分行爲

double charge(Billable emp, int days){
    int base = emp.getRate() * days;
    if(emp.hasSpecialSkill()){
        return base * 1.05;
    }else{
        return base;
    }
}

到目前爲止,咱們只不過是在文檔化方面有一點收穫。單就這一個函數而言,這樣的收穫並無太大價值;但若是有若干個類都是用Billable接口,它就頗有用。若是我還想計算電腦租金,巨大的收穫就顯露出來了:要想計算客戶租用電腦的費用,只需讓Computer類實現Billable接口,而後就能夠把租用電腦的時間也填到時間表上了。

相關文章
相關標籤/搜索