整體來講設計模式分爲三大類:spring
建立型模式:數據庫
單例模式、工廠方法模式、抽象工廠模式、建造者模式、原型模式。設計模式
結構型模式:安全
適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。app
行爲型模式:iphone
策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。ide
單例模式測試
單例模式的八種寫法this
一、餓漢式(靜態常量)[可用]spa
二、餓漢式(靜態代碼塊)[可用]
三、懶漢式(線程不安全)[不可用]
四、懶漢式(線程安全,同步方法)[不推薦用]
五、懶漢式(線程安全,同步代碼塊)[不可用]
六、雙重檢查[推薦用]
七、靜態內部類[推薦用]
八、枚舉[推薦用]
簡單工廠
又叫作靜態工廠方法(StaticFactory Method)模式,但不屬於23種GOF設計模式之一。
簡單工廠模式的實質是由一個工廠類根據傳入的參數,動態決定應該建立哪個產品類。
Spring中的BeanFactory就是簡單工廠模式的體現,根據傳入一個惟一的標識來得到Bean對象,可是否是在傳入參數後建立仍是傳入參數前建立這個要根據具體狀況來定。
工廠方法模式
public abstract class AbstractDriverFactory { public abstract Animal createDriver();//這個方法是爲了它的子類重寫它的構造方法 } public class ZhangFactory extends AbstractDriverFactory { @Override public Driver createDriver() { return new Zhang();//返回一個具體的對象老張。 } } public static void main(String[] args) { ZhangFactory zf = new ZhangFactory();//建立老張的工廠對象 Driver driver = zf.createDriver();//再調用建立司機的方法 driver.driveCar();//司機去開車 }
不得不說,工廠方法模式雖然完美符合了ocp開閉原則(Open Closed Principle)原則,但卻使整個程序變得很沉重。就拿數據庫來講,若是有100個訪問數據庫的類,那麼就要建立100個這個類的工廠。
1.簡單工廠模式:最大的優勢就是在工廠中就包含了必要的判斷,使用時只須要根據客戶端的選擇來實例化便可,對於客戶端使用來講,去除了與具體產品的依賴。而缺點就是違背的ocp原則。假如將來要添加一個新的需求,則須要更改簡單工廠中的判斷語句。這對代碼自己就不利。
2.工廠方法模式:最大的優勢就是抽象化了簡單工廠模式。再有新的需求進來時,不須要更改工廠的內容,符合了ocp原則。而缺點是每增長一個產品就要新增長一個相應的實例化工廠,增長了額外的開發量。
3.抽象工廠模式:分離了具體的類。不會出如今客戶端代碼中,易於交換產品系列。並且具體的工廠類只在它初始化的時候纔會出現。這使得改變一個應用的具體工廠變得很容易~~缺點是,抽象工廠幾乎肯定了能夠建立的對象的集合。加入新的類型對象就須要擴展其接口,這將涉及到具體工廠及其子類的修改。
三種工廠模式雖然用法各不相同,但它們的最終目的都是一致的----解耦。spring容器就是個大型的抽象工廠,不只能夠建立普通的bean實例,也能夠建立bean工廠。
適配器模式
將一個類的接口轉換成客戶但願的另外一個接口。適配器模式讓那些接口不兼容的類能夠一塊兒工做,說白了就是爲了掛羊頭賣狗肉而專門設計的模式。也就是把一個類的接口變換成客戶端所期待的另外一種接口。
1 ,類的適配
(1)目標(Target)角色:這就是所期待獲得的接口。注意:因爲這裏討論的是類適配器模式,所以目標不能夠是類。
(2)源(Adapee)角色:如今須要適配的接口。
(3)適配器(Adaper)角色:適配器類是本模式的核心。適配器把源接口轉換成目標接口。顯然,這一角色不能夠是接口,而必須是具體類。
2, 對象的適配
對象的適配依賴於對象的組合,而不是類適配中的繼承。
仍是以手機爲例子,每一種機型都自帶有從電器,有一天自帶充電器壞了,並且市場沒有這類型充電器可買了,怎麼辦?萬能充電器就能夠解決,這個萬能充電器就是適配器。
首先來一個IPhone的充電器類(Adaptee角色):
public class IPhoneCharger { public void applePhoneCharge(){ System.out.println("The iPhone is charging ..."); } }
要對這個特殊的充電器進行適配,上個適配的接口(Target角色):
public interface ChargeAdapter { public void phoneCharge(); }
由於適配有兩種,因此先進行類的適配示例,建立類的適配器:
public class UniversalCharger extends IPhoneCharger implements ChargeAdapter{ @Override public void phoneCharge() { System.out.println("The phone is charging, but which kind of phone it is, who cares ..."); super.applePhoneCharge();//iphone charging } }
這就是萬能充電器了,咱們讓它來充個電,測試類準備:
public class AdapterClassTest { public static void main(String[] args) { ChargeAdapter charger = new UniversalCharger(); charger.phoneCharge(); } }
測試結果:
The phone is charging, but which kind of phone it is, who cares ... The iPhone is charging ...
以上是類的適配,咱們還有種對象的適配方式,建立對象的適配器:
public class UniversalCharger implements ChargeAdapter{ IPhoneCharger iphoneCharger; public UniversalCharger(IPhoneCharger iphoneCharger){ this.iphoneCharger = iphoneCharger; } @Override public void phoneCharge() { System.out.println("The phone is charging, but which kind of phone it is, who cares ..."); iphoneCharger.applePhoneCharge(); } }
對象適配器建立完畢,測一下:
public class AdapterObjectTest { public static void main(String[] args) { IPhoneCharger iphoneCharger = new IPhoneCharger(); ChargeAdapter charger = new UniversalCharger(iphoneCharger); charger.phoneCharge(); } }
測試結果:
The phone is charging, but which kind of phone it is, who cares ... The iPhone is charging ...
總結一下:
(1)類的適配器模式:當但願將一個類轉換成知足另外一個新接口的類時,可使用類的適配器模式,建立一個新類,繼承原有的類,實現新的接口便可。
(2)對象的適配器模式:當但願將一個對象轉換成知足另外一個新接口的對象時,能夠建立一個包裝類,持有原類的一個實例,在包裝類的方法中,調用實例的方法就行。