四、單一職責原則與接口分離原則

單一職責原則 (Simple Responsibility Pinciple,SRP)

這個原則其實很有意思,他規(guī)定每個類所擁有的能力必須明確劃分,吃飯就吃飯,洗澡就洗澡,睡覺就睡覺,這保證了每個類的相互的能力不會互相污染,你不能一個吃飯的類居然可以出來洗澡的方法,這聽起來就很荒謬。

如果你在學習的時候樂于查看源碼,不難會有這樣疑問:為什么我們看起來明明可以一步完成的操作他要寫那么多封裝類還有那么深的層次結(jié)構(gòu)來完成,這很難理解。這也是源碼學習晦澀難懂的一部分的原因。

但是,我還是那句話,如果站在更高層次來思考這個問題,不難發(fā)現(xiàn)設(shè)計者的良苦用心,職責分的細彼此之間相互耦合的可能性就小,功能也就方便維護,不過這個請適可而止,也并不是說吃飯功能你需要細節(jié)到吃哪一粒米,這沒有必要,不必要的借口太多反而不好維護。你只要在怎么吃這個功能上細分就好。

今天呢,我還是去吃飯,不過飯店推出了簡約套餐豪華套餐 。

簡約套餐:做得很快,但是菜品很簡單,很適合早餐,讓我們在短時間內(nèi)就可以完成吃飯動作。

豪華套餐:做得比簡約套餐慢許多,但是菜品很豐富,很適合聚餐,晚餐這種有較多時間等待和享用的類型。
老樣子,最簡單的初版。對套餐(Set)進行編寫。

public class Set{
    public void eat(String type){
        if("簡約套餐".equals(type)){
            // print 選擇簡約套餐
        }else{
            // print 選擇豪華套餐
        }
    }
}
public static void main(String[] ars){
    Set set = new Set();
    set.eat("簡約套餐");
    set.eat("豪華套餐");
}

當然,寫成這樣還是老問題,就是開閉原則之類的問題。

不過有一點我想要說明的是,設(shè)計原則最多也還是參考作用,我們應該盡量遵守,因為真正的業(yè)務可能會讓我們不得不打破一些看起來很美好的原則,所以比起強制套用設(shè)計原則,不如學會善用他們來解決讓你撓頭的業(yè)務問題。

回歸正傳,這個時候,飯店認為推出的簡約套餐豪華套餐 銷量不錯,但是顧客覺得花樣太單一了,于是為了回應顧客新的業(yè)務需求,我們就需要修改一下當初的設(shè)計,乘著還沒有釀成大禍之前。

public class SimpleSet{
    public void eat(String type){
        System.out.println(type+": 簡單快捷.");
    }
}
public class DiffSet{
    public void eat(String type){
        System.out.println(type+": 奢華大氣.");
    }
}

我們將兩種套餐分成了兩個類,為了把他們的職責細分,不再像是以前全部的職責都放在了Food類中,避免了污染。

public static void main(String[] ars){
    DiffSet dset = new Diffset();
    dset.eat("奢華套餐");
    SimpleSet sset = new SimpleSet();
    sset.eat("簡約套餐");
}

但這樣感覺還是不夠好,因為之前依賴倒置中講過:高層模塊與底層模塊應該依賴抽象這一概念,所以我們使用接口來再次設(shè)計一下。

public interface ISet{
    void eat(String type);
}
public SimpleSetImpl implements ISet{
    //和之前一樣
}
public DiffSetImpl implements ISet{
    //和之前一樣
}
public static void main(String[] ars){
    ISet dset = new DiffsetImpl();
    dset.eat("奢華套餐");
    ISet sset = new SimpleSetImpl();
    sset.eat("簡約套餐");
}

再回到我們新的需求的問題,我們可以有三種選擇。

第一種,我們可以繼承簡約套餐,而重寫里面eat方法。

public SimpleSetImplA extends SimpleSetImpl{
    @Override
    public void eat(String type){
        System.out.println(type+": A套餐");//簡約的A套餐
    }
}
public SimpleSetImplB extends SimpleSetImpl{
    @Override
    public void eat(String type){
        System.out.println(type+": B套餐");//簡約的B套餐
    }
}

第二種,我們所使用的SimpleSetImpl不應該使用,而應該使用抽象類,讓所繼承他的子類自由實現(xiàn)自己的套餐內(nèi)容。也是我比較推薦的一種。

public abstract class DefaultSimpleSet implements ISet{
    //------------
    //*********** 以上是關(guān)于套餐的默認方法,表示一些固定的價錢和適用人群到底初始化
    public abstract void eat(String type);
    //讓簡單套餐的子類去具體實現(xiàn)吃的方法,繼承的子類將會自動成為簡約套餐的子項。
}
public SimpleSetImplA extends DefaultSimpleSet{
    @Override
    public void eat(String type){
        System.out.println(type+": A套餐");//簡約的A套餐
    }
}
public SimpleSetImplB extends DefaultSimpleSet{
    @Override
    public void eat(String type){
        System.out.println(type+": B套餐");//簡約的B套餐
    }
}

第三種,設(shè)計兩個接口,一個是ISimpleSet,一個是IDiffSet接口,實現(xiàn)方法我直接貼出來。

public interface ISimpleSet{
    void eat(String type);
}
public interface IDiffSet{
    void eat(String type);
}

//這里只實現(xiàn)簡約套餐
public class SimpleSetImpA implements ISimpleSet{
    //具體實現(xiàn) A 套餐的 eat
}
public class SimpleSetImpB implements ISimpleSet{
    //具體實現(xiàn) B 套餐的 eat
}

當然我想到了第四種。正好可以提前預熱以下接口隔離原則。

public interface ISimpleSet implements ISet{
    // eat 方法
    void simpleSetMethod();//簡約套餐獨有的方法
}
public interface IDiffSet implements ISet{
    // eat 方法
    void DiffSetMethod();//奢華套餐獨有的方法
}

后面就和第三種方法一樣。

總結(jié)一下單一職責,其實就是對功能的細分,并且要對將來的會發(fā)展成什么樣子做出比較良好的架構(gòu),對面接口,這將會對你的拓展有很大幫助。

接口隔離原則 (Interface Segregation Principle, ISP)

是指用多個專門的接口,而不使用單一的總接口,客戶端不應該依賴它不需要的接口。這個原則指導我們在設(shè)計接口時應當注意一下幾點:
1、一個類對一類的依賴應該建立在最小的接口之上。
2、建立單一接口,不要建立龐大臃腫的接口。
3、盡量細化接口,接口中的方法盡量少(不是越少越好,一定要適度)。

代碼我是我從別的地方粘貼過來的,這個大概的內(nèi)容我其實在上面的四種方法一樣,類應該只要依賴一個或者更少的接口。
并且每個都應該有明確的功能,用來區(qū)別接口的作用。

這里我就不再贅述了。

版權(quán)聲明:本文為CSDN博主「PopCandier」的原創(chuàng)文章,遵循CC 4.0 by-sa版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/CandyCCCation/article/details/88899480

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容