java設計模式學習隨筆
阿新 • • 發佈:2018-09-17
內部 效應 generate 地方 溢出 ... 代碼優化 問題 可擴展
設計模式入門 1:設計模式是人們在面對同類型軟件工程設計問題所總結出的一些有用經驗。模式不是代碼,而是某類問題的通用設計解決方案。 2:怎麽來的,前人總結的 3:設計模式的郵件和用途 4:學習設計模式的方式:在你的設計和以往的工程裏尋找何處可以使用它們 5:學習設計模式的本質目的是使軟件工程在維護性、拓展性、變化性、復雜度方面稱0(N) 6:OO原則,設計模式是具體方法、工具 策略模式: 定義:分別封裝行為為接口,實現算法族,超類裏放行為接口對象,在子類裏具體設定行為對象。原則就是:分離變化部分,封住接口,基於接口編程各種功能。該模式讓行為算法的變化獨立於算法的使用者。 ps自我理解: 1:從原始的OO角度設計,抽象出對象的共性,提取至基類 public abstract class Duck { public void Quack() { System.out.println("~~gaga~~"); } public abstract void display(); public void swim() { System.out.println("~~im swim~~"); } } 2:相應的各個實現類只需要繼承基類就可以使用到基類裏面有的方法和重寫自己想要的方法 public class GreenHeadDuck extends Duck { @Override public void display() { System.out.println("**GreenHead**"); } } 3:後來來了新需求 應對新的需求,看看這個設計的可擴展性 添加會飛的鴨子 4:OO思維裏的繼承方式解決方案是: public abstract class Duck { ...; public void Fly() { System.out.println("~~im fly~~"); } }; 問題來了,這個Fly讓所有子類都會飛了,這是不科學的。 繼承的問題:對類的局部改動,尤其超類的局部改動,會影響其他部分。影響會有溢出效應 5:為了正確性那麽你是不是需要去重寫所有的實現,這次是所有的鴨子都會飛,下次再來個所有的鴨子都會上樹了你咋辦? 超類挖的一個坑,每個子類都要來填,增加工作量,復雜度O(N^2)。不是好的設計方式 6:用策略模式來新需求解決 //行為接口 public interface FlyBehavior { void fly(); } //基類 public abstract class Duck { //基類 FlyBehavior mFlyBehavior; //行為接口對象 也就是容易變化的地方 QuackBehavior mQuackBehavior; //行為接口對象 public Duck() { } public void Fly() { mFlyBehavior.fly(); //行為接口對象的方法 不做具體實現 } public void Quack() { mQuackBehavior.quack(); } public abstract void display(); //共同的地方也就不需要再做什麽手腳了 沒啥意義 public void SetQuackBehavoir(QuackBehavior qb) { mQuackBehavior = qb; } public void SetFlyBehavoir(FlyBehavior fb) { mFlyBehavior = fb; } public void swim() { System.out.println("~~im swim~~"); } } //行為接口實現 public class BadFlyBehavior implements FlyBehavior { @Override public void fly() { // TODO Auto-generated method stub System.out.println("--BadFly--"); } } //基類的具體實現類 public class GreenHeadDuck extends Duck { public GreenHeadDuck() { mFlyBehavior = new GoodFlyBehavior(); mQuackBehavior = new GaGaQuackBehavior(); } @Override public void display() { // TODO Auto-generated method stub System.out.println("**GreenHead**"); } } 策略模式總結: 1:分析項目中變化和不變化的部分。 2:多用組合少用繼承,用行為類組合,也不是行為的繼承。更有彈性。 裝飾者模式: 裝飾者模式原理: 1:裝飾者模式就像打包一個快遞 1)主體:陶瓷、衣服 2)包裝:報紙、套末班、紙板 2:Component:主體(超類) 3:ConcreteComponent(具體實現類)和Decortor(實現類的裝飾) 4:裝飾者模式: 動態的將新功能附加到對象上。在對象功能擴展方面,它比繼承更有彈性。 單例模式: 經典單例模式原理: 單例模式的意義: 有些對象我們只需要一個:線程池、緩存、硬件設備等,如果多個實例會造成沖突、結果的不一致性等問題。 是否可以用靜態變量方式來實現? 或者協商一個全局變量? 單例模式的概念: 確保一個類最多只有一個實例,並提供一個全局訪問點。 單例模式類圖: ----------------------- | Singleton | ----------------------- |static uniqueInstance| //靜態變量 |//其他 | ----------------------- |private Singletom() | //構造函數私有 封閉類在外部new的方式 |static getInstance | //在類的內部使用靜態函數構造一個對象 |//其他 | ----------------------- 經典單例模式代碼示例: 單例類java代碼: public class Singleton{ private static Singleton uniqueInstance = null; //用於存放自己的實例 private Singleton(){}; //構造函數私有 public static Singletom getInstance(){ if(null == uniqueInstance){ uniqueInstance = new Singleton(); } return uniqueInstance; } } 經典代理模式代碼優化: 多線程問題:會出現兩個或多個線程獲取到兩個或多個不同的對象。 優化方式1:創建方法枷鎖 public class Singleton{ private static Singleton uniqueInstance = null; //用於存放自己的實例 private Singleton(){}; //構造函數私有 public static synchronized Singletom getInstance(){ //最粗暴的方式 synchronized會多次 if(null == uniqueInstance){ uniqueInstance = new Singleton(); } return uniqueInstance; } } 優化方式2:‘急切’創建實例 public class Singleton{ private static Singleton uniqueInstance = new Singleton(); //用於存放自己的實例 程序啟動時就創建好對象 private Singleton(){}; //構造函數私有 public static Singletom getInstance(){ if(null == uniqueInstance){ uniqueInstance = new Singleton(); } return uniqueInstance; } } 優化方式3:雙重檢查加鎖 public class Singleton{ private static volatile Singleton uniqueInstance = null; //用於存放自己的實例 private Singleton(){}; //構造函數私有 public static Singletom getInstance(){ if(null == uniqueInstance){ synchronized (Singleton.class){ //這樣也就是再上面內個方法的基礎上 優化了加鎖的次數 只會有一次 synchronized if(null == uniqueInstance){ uniqueInstance = new Singleton(); } } } return uniqueInstance; } } 工廠模式: 簡單工廠模式的設計方案: 定義一個實例化對象的類,由這個類封裝創建對象的行為。 工廠方法模式的設計方案: 將對象的實例化功能抽象成抽象方法,在不同實例裏面實現具體功能, 也就是定義一個創建對象的抽象方法,由子類決定要實例化的類。工廠方法模式將對象實例化推遲到子類。 抽象工廠模式定義: 定義一個接口用於創建相關有依賴關系的對象族,而無需指明具體類。 工廠模式關鍵點: 1:工廠模式的意義 將對象實例化動作提取,和項目的主動和依賴進行解耦 2:三種工廠模式 3:依賴抽象原則 變量不要持有具體類的引用,不可以強依賴 不要讓類繼承自具體類,要繼承自抽象類或接口 不要覆蓋基類中已經實現的方法 適配器模式: 原理:將一個類的接口轉換成另一種接口,讓原本接口不兼容的類可以兼容。 目標 <--- 適配器 <--- 被適配者 從用戶角度看不到被適配者,是解耦的 用戶調用適配器轉換出來的目標接口方法 適配器再調用被適配者的相關接口方法 對象適配器與類適配器: 類適配器:通過多重繼承目標接口和被適配者類方式來實現適配 目標<--| |適配器 被適配者<--| 多重繼承,其中繼承的目標接口部門達到適配目的,而繼承被適配者類的部分達到通過調用適配者類裏面的方法實現目標接口的功能 對象適配器與類適配器的差異: 對象適配器與類適配器使用了不同的方法實現適配,對象適配器使用組合,類適配器使用繼承
java設計模式學習隨筆