设计模式开坑
設(shè)計模式(一)–工廠和單例模式
文章目錄
- 設(shè)計模式(一)--工廠和單例模式
- 其他筆記鏈接
- 1. 23種設(shè)計模式
- 2. OOP七大原則
- 3. 單例模式
- 六種實現(xiàn)方法
- 4.工廠模式
- 靜態(tài)工廠模式(簡單工廠模式)
- 工廠方法模式
- 5. 抽象工廠模式
其他筆記鏈接
JVM學習筆記(一)
JVM學習筆記(二)
JVM學習筆記(三)
JVM學習筆記(四)
(待更新…)
Java NIO
(待更新…)
設(shè)計模式(一)
設(shè)計模式(二)
設(shè)計模式(三)
設(shè)計模式(四)
(待更新…)
1. 23種設(shè)計模式
創(chuàng)建型模式
- 工廠模式(Factory Pattern)
- 抽象工廠模式(Abstract Factory Pattern)
- 單例模式(Singleton Pattern)
- 建造者模式(Builder Pattern)
- 原型模式(Prototype Pattern)
結(jié)構(gòu)型模式
- 適配器模式(Adapter Pattern)
- 橋接模式(Bridge Pattern)
- 過濾器模式(Filter、Criteria Pattern)
- 組合模式(Composite Pattern)
- 裝飾器模式(Decorator Pattern)
- 外觀模式(Facade Pattern)
- 享元模式(Flyweight Pattern)
- 代理模式(Proxy Pattern)
行為型模式
- 責任鏈模式(Chain of Responsibility Pattern)
- 命令模式(Command Pattern)
- 解釋器模式(Interpreter Pattern)
- 迭代器模式(Iterator Pattern)
- 中介者模式(Mediator Pattern)
- 備忘錄模式(Memento Pattern)
- 觀察者模式(Observer Pattern)
- 狀態(tài)模式(State Pattern)
- 空對象模式(Null Object Pattern)
- 策略模式(Strategy Pattern)
- 模板模式(Template Pattern)
- 訪問者模式(Visitor Pattern)
2. OOP七大原則
3. 單例模式
特點
單例類只能有一個實例,單例類必須自己創(chuàng)建自己的唯一實例,單例類必須給所有其他對象提供這一實例。
關(guān)鍵實現(xiàn)
構(gòu)造函數(shù)私有化(外界無法創(chuàng)建,只有在類內(nèi)部才能創(chuàng)建)
對象實例私有化,對外只提供get方法獲取這唯一實例。
六種實現(xiàn)方法
1.懶漢式一
初始化方式:懶加載(拿的時候才創(chuàng)建)
線程:不安全
public class singInstance{//不在類加載時創(chuàng)建private static singInstance instance;//構(gòu)造函數(shù)私有化private singInstance(){}//get方法獲取對象,并確保只創(chuàng)建一次public static singInstance getInstance(){if(instance == null){instance = new singInstance();}return instance;} }2.懶漢式二
初始化方式:懶加載(拿的時候才創(chuàng)建)
線程:安全
添加synchronized導致性能上的損失
public class singInstance{//不在類加載時創(chuàng)建private static singInstance instance;//構(gòu)造函數(shù)私有化private singInstance(){}//添加synchronized確保多線程安全public static synchronized singInstance getInstance(){if(instance == null){instance = new singInstance();}return instance;} }3.餓漢式
初始化方式:非懶加載
線程:安全
在類加載時就創(chuàng)建的對象,確保線程安全,沒有加synchronized性能上沒有收影響。但是非懶加載,會堆積垃圾對象。
public class singInstance{//在類加載時創(chuàng)建private static singInstance instance = new singInstance();//構(gòu)造函數(shù)私有化private singInstance(){}//直接放回已經(jīng)創(chuàng)建好的對象public static singInstance getInstance(){return instance;} }4.雙檢鎖/雙重校驗鎖(DCL)
初始化方式:懶加載
線程:安全
public class singInstance{//使用volatile確保線程可見性private volatile static singInstance instance;//構(gòu)造函數(shù)私有化private singInstance(){}//直接放回已經(jīng)創(chuàng)建好的對象public static singInstance getInstance(){if(instance == null){//使用synchronized把類鎖住,確保類對象使用的線程安全synchronized (singInstance.class){if(instance == null){instance = new singInstance();}}}} }5.登記式(靜態(tài)內(nèi)部類)
初始化方式:懶加載
線程:安全
利用靜態(tài)內(nèi)部類需要顯式調(diào)用才加載的機制,實現(xiàn)懶加載。因為 SingletonInter 類沒有被主動使用,只有通過顯式調(diào)用 getInstance 方法時,才會顯式裝載 SingletonInter 類,從而實例化 instance。
public class singInstance{//把對象放內(nèi)部內(nèi)里面private static class singInstanceInter(){private static final singInstance instance = new singInstance(); }//構(gòu)造函數(shù)私有化private singInstance(){}//直接放回已經(jīng)創(chuàng)建好的對象public static final singInstance getInstance(){return singInstanceInter.instance;} }6.枚舉法
初始化方式:非懶加載
線程:安全
public enum Singleton { INSTANCE; public void whateverMethod() { } }4.工廠模式
靜態(tài)工廠模式(簡單工廠模式)
靜態(tài)工廠模式,違背了開閉原則。想增加一個新的產(chǎn)品,就需要修改代碼。
就像下面這張圖片一樣,product需要實現(xiàn)對應的產(chǎn)品接口,而工廠類負責對實現(xiàn)該Iproduc接口的實現(xiàn)類的創(chuàng)建,如果我們需要創(chuàng)建一臺汽車只需通過工廠并告知其要建造哪種車即可。
為什么用工廠模式?
有人可能會想,為什么不直接NEW呢,要通過工廠創(chuàng)建。試想一下,假如某個產(chǎn)品的創(chuàng)建需要大量的初始化參數(shù),那么我們只能new的話,需要手寫大量參數(shù),這是好的,而且在你的應用程序的類里面直接通過new出來的對象,那么new出來的對象就直接跟你的應用程序中的類有直接關(guān)聯(lián),那么你下系統(tǒng)耦合性就會很高。假如某一天上百個produce中某幾個produce的構(gòu)造參數(shù)改變了,你是否需要去你應用程序中的類修改你原有new的那行代碼,這是很不好的。假如我們使用了工廠模式,我們只需去修改對應工廠類的代碼即可,無需去你那一大堆應用程序中的類找那段new的代碼。
代碼實現(xiàn)
這次代碼使用電腦做示范。
電腦產(chǎn)品接口
public Interface Computer {//電腦要會開機public void start(); }聯(lián)想電腦
public class HpComputer extends Computer{@Overridepublic void start() {System.out.println("惠普電腦啟動");} }華碩電腦
public class AsusComputer extends Computer {@Overridepublic void start() {System.out.println("華碩電腦啟動");} }英特爾電腦
public class InterComputer extends Computer {@Overridepublic void start() {System.out.println("英特爾電腦啟動");} }工廠
public class ComputerFactory {//只需告知工廠創(chuàng)建那種電腦即可public static Computer createComputer(String type){Computer mComputer=null;switch (type) {case "lenovo":mComputer=new LenovoComputer();break;case "Inter":mComputer=new InterComputer();break;case "asus":mComputer=new AsusComputer();break;}return mComputer;} }優(yōu)缺點
- 優(yōu)點:避免了直接實例化類,降低了耦合性。
- 缺點:違背了開放封閉原則,想增加一個新的產(chǎn)品,就需要修改代碼。
工廠方法模式
工廠方法模式是在靜態(tài)工廠上面做進一步的修改,原靜態(tài)工廠模式只有單一的工廠,而工廠方法模式有多個工廠,每個產(chǎn)品都有其實現(xiàn)創(chuàng)建的工廠,這樣增加一個新的產(chǎn)品時,我們只需要橫向擴展工廠類即可達成目標,就無需去修改那唯一工廠的代碼。弊端也挺明顯的,沒增加一個產(chǎn)品就需要創(chuàng)建其對應的工廠類,增加了系統(tǒng)的復雜度。
圖片來自狂神說:
代碼實現(xiàn)
產(chǎn)品接口
public Interface Car {public void drive(); }工廠接口
public Interface CarFactory{//工廠要會建造汽車public Car createCar(); }特斯拉車
public class Tesla implements Car{@Overridepublic void drive(){ System.out.println("特斯拉開車");} }特斯拉工廠
public class Tesla implements CarFactory{@Overridepublic Car createCar(){ return new Tesla();} }橫向擴展
想橫向擴展只需要添加對應的產(chǎn)品和其產(chǎn)品對應的工廠即可,雖然代碼量變多了,但符合開閉原則。
優(yōu)缺點
- 缺點:增加系統(tǒng)的復雜度,沒新建一個產(chǎn)品就需要新建一個對應的工廠。
- 優(yōu)點:擴展性高,如果想增加一個產(chǎn)品,只要擴展一個工廠類就可以。 屏蔽產(chǎn)品的具體實現(xiàn),調(diào)用者只關(guān)心產(chǎn)品的接口。
5. 抽象工廠模式
抽象工廠模式(Abstract Factory Pattern)是圍繞一個超級工廠創(chuàng)建其他工廠。該超級工廠又稱為其他工廠的工廠。
┌────────┐─ >│ProductA│ ┌────────┐ ┌─────────┐ │ └────────┘ │ Client │─ ─>│ Factory │─ ─ └────────┘ └─────────┘ │ ┌────────┐▲ ─ >│ProductB│┌───────┴───────┐ └────────┘│ │┌─────────┐ ┌─────────┐│Factory1 │ │Factory2 │└─────────┘ └─────────┘│ ┌─────────┐ │ ┌─────────┐─ >│ProductA1│ ─ >│ProductA2││ └─────────┘ │ └─────────┘┌─────────┐ ┌─────────┐└ ─>│ProductB1│ └ ─>│ProductB2│└─────────┘ └─────────┘代碼實現(xiàn)
這次代碼實現(xiàn)換成別的,有現(xiàn)實對入感一點。
手機產(chǎn)品接口
public Interface phone {public void open(); }WIFI產(chǎn)品接口
public Interface wifi {public void openwifi(); }抽象工廠接口
public Interface AbstractFactory {//工廠要回造手機public phone creatPhone();//會造wifipublic wifi creatWifi(); }小米工廠
public class MiniFactory {@Overridepublic phone creatPhone(){return new MiniPhone();}@Overridepublic wifi creatWifi(){return new Miniwifi();} }小米手機產(chǎn)品類
public class MiniPhone {@Overridepublic void open(){...} }小米WiFi產(chǎn)品類
public class Miniwifi {@Overridepublic void openwifi(){...} }華為手機工廠
public class HuaweiFactory {@Overridepublic phone creatPhone(){return new HuaweiPhone();}@Overridepublic wifi creatWifi(){return new Huaweiwifi();} }華為手機產(chǎn)品類
public class HuaweiPhone {@Overridepublic void open(){...} }華為WiFi產(chǎn)品類
public class Huaweiwifi {@Overridepublic void openwifi(){...} }優(yōu)缺點
- 優(yōu)點:當一個產(chǎn)品族中的多個對象被設(shè)計成一起工作時,它能保證客戶端始終只使用同一個產(chǎn)品族中的對象。
- 缺點:還是違背了開閉原則,產(chǎn)品族擴展非常困難,要增加一個系列的某一產(chǎn)品,既要在抽象的 Creator 里加代碼,又要在具體的里面加代碼。
總結(jié)
- 上一篇: JVM学习笔记(四)
- 下一篇: 设计模式(三)--适配器模式