Java面試題2.0--設計模式

 

歡迎關注《Java面試題2.0》合集發佈頁,持續更新中!

 
設計模式有哪些類型?常用設計模式分別屬於什麼類型?
總體來說設計模式分爲三大類:
創建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。
 
結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。
 
行爲型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。
 
設計模式應該遵循哪些原則?
 
1、開閉原則(Open Close Principle)
 
開閉原則就是說對擴展開放,對修改關閉。在程序需要進行拓展的時候,不能去修改原有的代碼,實現一個熱插拔的效果。所以一句話概括就是:爲了使程序的擴展性好,易於維護和升級。想要達到這樣的效果,我們需要使用接口和抽象類,後面的具體設計中我們會提到這點。
 
2、里氏代換原則(Liskov Substitution Principle)
 
里氏代換原則(Liskov Substitution Principle LSP)面向對象設計的基本原則之一。 里氏代換原則中說,任何基類可以出現的地方,子類一定可以出現。 LSP是繼承複用的基石,只有當衍生類可以替換掉基類,軟件單位的功能不受到影響時,基類才能真正被複用,而衍生類也能夠在基類的基礎上增加新的行爲。里氏代換原則是對“開-閉”原則的補充。實現“開-閉”原則的關鍵步驟就是抽象化。而基類與子類的繼承關係就是抽象化的具體實現,所以里氏代換原則是對實現抽象化的具體步驟的規範。—— From Baidu 百科
 
3、依賴倒轉原則(Dependence Inversion Principle)
 
這個是開閉原則的基礎,具體內容:真對接口編程,依賴於抽象而不依賴於具體。
 
4、接口隔離原則(Interface Segregation Principle)
 
這個原則的意思是:使用多個隔離的接口,比使用單個接口要好。還是一個降低類之間的耦合度的意思,從這兒我們看出,其實設計模式就是一個軟件的設計思想,從大型軟件架構出發,爲了升級和維護方便。所以上文中多次出現:降低依賴,降低耦合。
 
5、迪米特法則(最少知道原則)(Demeter Principle)
 
爲什麼叫最少知道原則,就是說:一個實體應當儘量少的與其他實體之間發生相互作用,使得系統功能模塊相對獨立。
 
6、合成複用原則(Composite Reuse Principle)
 
原則是儘量使用合成/聚合的方式,而不是使用繼承。
 
工廠模式
 
原理:
 
建立一個工廠類,對實現了同一接口的一些類進行實例的創建
 
應用場景:
 
凡是出現了大量的產品需要創建,並且具有共同的接口時,可以通過工廠方法模式進行創建。
 
 
普通工廠方法、多種工廠方法、靜態工廠模式與抽象工廠模式的區別:
 
在普通工廠方法模式中,如果傳遞的字符串出錯,則不能正確創建對象,而多個工廠方法模式是提供多個工廠方法,分別創建對象。
靜態工廠模式相對於多個工廠方法模式,不需要實例化工廠類,
靜態工廠模式 有一個弊端:類的創建依賴工廠類,也就是說,如果想要拓展程序,必須對工廠類進行修改,這違背了閉包原則。
抽象工廠模式,創建多個工廠類,這樣一旦需要增加新的功能,直接增加新的工廠類就可以了,不需要修改之前的代碼。
 
優點:
 
發及時信息,則只需做一個實現類,實現Sender接口,同時做一個工廠類,實現Provider接口,就OK了,無需去改動現成的代碼。這樣做,拓展性較好!
 
示例代碼:
 
單例模式
 
原理:
 
單例對象能保證在一個JVM中,該對象只有一個實例存在。
 
優點:
 
1、某些類創建比較頻繁,對於一些大型的對象,這是一筆很大的系統開銷。
2、省去了new操作符,降低了系統內存的使用頻率,減輕GC壓力。
3、有些類如交易所的核心交易引擎,控制着交易流程,如果該類可以創建多個的話,系統完全亂了。
 
代碼:
 
該示例實現了同步,解決了多線程問題,同時同步語句只修飾了創建實例語句,不會每次調用都控制同步,保證了性能
public class SingletonTest {
    private static SingletonTest instance = null;
    private SingletonTest() {
    }
    private static synchronized void syncInit() {
        if (instance == null) {
            instance = new SingletonTest();
        }
    }
    public static SingletonTest getInstance() {
        if (instance == null) {
            syncInit();
        }
        return instance;
    }
}
 
適配器模式
 
原理:
 
適配器模式將某個類的接口轉換成客戶端期望的另一個接口表示,目的是消除由於接口不匹配所造成的類的兼容性問題。
 
使用場景:
 
類的適配器模式:當希望將一個類轉換成滿足另一個新接口的類時,可以使用類的適配器模式,創建一個新類,繼承原有的類,實現新的接口即可。
對象的適配器模式:當希望將一個對象轉換成滿足另一個新接口的對象時,可以創建一個Wrapper類,持有原類的一個實例,在Wrapper類的方法中,調用實例的方法就行。
接口的適配器模式:當不希望實現一個接口中所有的方法時,可以創建一個抽象類Wrapper,實現所有方法,我們寫別的類的時候,繼承抽象類即可。
 
核心思想:
 
核心思想就是:有一個Source類,擁有一個方法,待適配,目標接口時Targetable,通過Adapter類,將Source的功能擴展到Targetable裏
 
裝飾模式
 
原理:
 
裝飾模式就是給一個對象增加一些新的功能,而且是動態的,要求裝飾對象和被裝飾對象實現同一個接口,裝飾對象持有被裝飾對象的實例
 
應用場景:
 
1、需要擴展一個類的功能。
2、動態的爲一個對象增加功能,而且還能動態撤銷。(繼承不能做到這一點,繼承的功能是靜態的,不能動態增刪。)
 
缺點:
 
產生過多相似的對象,不易排錯!
 
代理模式
 
原理:
 
代理模式就是多一個代理類出來,替原對象進行一些操作,比如我們在租房子的時候回去找中介,爲什麼呢?因爲你對該地區房屋的信息掌握的不夠全面,希望找一個更熟悉的人去幫你做,此處的代理就是這個意思。再如我們有的時候打官司,我們需要請律師,因爲律師在法律方面有專長,可以替我們進行操作,表達我們的想法。
 
應用場景:
 
如果已有的方法在使用的時候需要對原有的方法進行改進,此時有兩種辦法:
1、修改原有的方法來適應。這樣違反了“對擴展開放,對修改關閉”的原則。
2、就是採用一個代理類調用原有的方法,且對產生的結果進行控制。這種方法就是代理模式。
使用代理模式,可以將功能劃分的更加清晰,有助於後期維護!
 
靜態代理缺點:
 
1、 當需要代理多個類的時候,由於代理對象要實現與目標對象一致的接口,有兩種方式:
 
只維護一個代理類,由這個代理類實現多個接口,但是這樣就導致代理類過於龐大
新建多個代理類,每個目標對象對應一個代理類,但是這樣會產生過多的代理類
 
2、 當接口需要增加、刪除、修改方法的時候,目標對象與代理類都要同時修改,不易維護。
 
策略模式
 
原理:
 
策略模式定義了一系列算法,並將每個算法封裝起來,使他們可以相互替換,且算法的變化不會影響到使用算法的客戶。需要設計一個接口,爲一系列實現類提供統一的方法,多個實現類實現該接口,設計一個抽象類(可有可無,屬於輔助類),提供輔助函數
 
應用場景:
 
策略模式的決定權在用戶,系統本身提供不同算法的實現,新增或者刪除算法,對各種算法做封裝。因此,策略模式多用在算法決策系統中,外部用戶只需要決定用哪個算法即可。
 
觀察者模式
 
原理:
 
當一個對象變化時,其它依賴該對象的對象都會收到通知,並且隨着變化!對象之間是一種一對多的關係。
 
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章