點擊閱讀原文更好的閱讀體驗web
前言
在項目中常常會碰到工廠模式,不光在項目中有在閱讀源碼的時候也必定少不了工廠模式。在咱們上上一篇文章分佈式定時任務Quartz中建立觸發器也是經過Quartz所提供的工廠來建立實例。可見工廠模式有多方便多經常使用。本文主要講解簡單工廠模式。設計模式
工廠模式[1](Factory Pattern)是 Java 中最經常使用的設計模式之一。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。微信
在工廠模式中,咱們在建立對象時不會對客戶端暴露建立邏輯,而且是經過使用一個共同的接口來指向新建立的對象。app
介紹
工廠模式有三種分爲簡單工廠模式、廠方法模式、抽象工廠模式其中簡單工廠模式並不屬於GOF[2]所提出的23種設計模式之中,簡單工廠模式其實更像是一種習慣。在設計模式之中工廠模式是屬於建立型。框架
簡單工廠模式
定義
簡單工廠模式到底啥時候使用,還有就是爲何要使用簡單工廠模式呢?
首先在上面咱們說了工廠模式是建立型,在介紹的時候也說了它提供了一種建立對象的最佳方式
也就是說簡單工廠模式的定義就是由一個工廠對象來決定建立那種產品實例。其次就是何時使用簡單工廠模式,首先如今有這樣一個場景。小明決定去賣車,一種是奔馳一種是奧迪:編輯器
/**
* 小明要賣車
*/
/**
* 先生產奧迪
*/
AudiCar audiCar = new AudiCar();
/**
* 在生產奔馳
*/
MercedesCar mercedesCar = new MercedesCar();
而後發現本身生產成本過高,小明還要本身盯着各類細節。這並非小明想要的他只想賺個差價。這個時候就可使用簡單工廠模式來幫助小明由於建立的對象比較少,而後工廠只須要知道須要什麼就返回什麼而後也不須要關心關鍵邏輯的時候就可使用簡單工廠模式
這就是簡單工廠模式的使用場景,那我使用了簡單工廠模式有啥優勢呢?從上面簡單的例子就能夠知道客戶端能夠免除建立對象的責任直接交給工廠進行建立
而後就是只須要知道傳入的參數就能夠獲取到所須要的參數並且無需知道建立細節
這不正是小明想要的嗎?hahaha。注意:在強調一下簡單工廠模式並不屬於23種設計模式,它只是一種編碼風格和實現分佈式
案例
看完上面你就已經知道何時用簡單工廠模式還有就是知道了它的優勢和使用場景,那麼如今就開始實戰。在建立以前要知道簡單工廠模式有如下幾種角色。而後定義一個抽象產品接口。ide
/**
* @Author :luomengsun.
* @Date :Created in 13:26 2020/1/5
* @Description:
*/
public interface Car {
/**
* 輸出簡單信息
*/
void printInfo();
}
一開始定義的Audi和Mercedes就是咱們的具體產品,改造一下測試
public class AudiCar implements Car {
@Override
public void printInfo() {
System.out.println("生產了奧迪");
}
}
public class MercedesCar implements Car{
@Override
public void printInfo() {
System.out.println("生產了奔馳");
}
}
它們都實現了咱們的抽象產品接口(也可使用抽象類,可是儘可能使用面向接口),如今定義工廠類。flex
public class CarFactory {
public Car getCarFactory(String str){
Car car = null;
if("audi".endsWith(str)){
car = new AudiCar();
}else if("mercedes".equals(str)){
car = new MercedesCar();
}else {
System.out.println("沒有定義產品");
}
return car;
}
}
而後咱們就在測試客戶端裏面經過工廠類來建立汽車。
public class TestClient {
public static void main(String[] args) {
/**
* 小明經過汽車工廠生產車
*/
CarFactory carFactory = new CarFactory();
/**
* 先生產奧迪
*/
Car car = carFactory.getCarFactory("audi");
car.printInfo();
}
}
這個時候控制檯輸出生產了奧迪
。UML類圖:
對比
上面就實現了簡單工廠模式,咱們對比一下最開始的實現,在引入簡單工廠模式以後客戶端須要什麼就直接告訴工廠就行,根本不須要咱們關心具體的細,實質上也就是對建立對象進行了封裝。若是在舉一個例子的話就好比咱們去肯德基去吃飯,咱們想要吃薯條直接在前臺點就行,你會關心薯條是怎麼生產的嗎?並且在你點薯條以前你確定是知道有這個產品的,否則你怎麼去下單?
缺點
上面把簡單工廠模式誇了一大堆,那它都有啥缺點呢?你別說缺點還真的有,首先看一下咱們的工廠類。
public class CarFactory {
public Car getCarFactory(String str){
Car car = null;
if("audi".endsWith(str)){
car = new AudiCar();
}else if("mercedes".equals(str)){
car = new MercedesCar();
}else {
System.out.println("沒有定義產品");
}
return car;
}
}
若是這個時候我想要增長寶馬怎麼辦,確定要先建立一個具體產品,而後在修改工廠類的判斷邏輯,這樣就違反了開閉原則。並且工廠類集中了全部實例的建立邏輯,違反了高內聚低耦合的原則。
那麼有沒有一種方法能夠不修改工廠類裏面的邏輯的方法嗎?這個確定是有的,咱們可使用反射來建立具體的產品。修改一下工廠類:
public class CarFactory {
public Car getCarFactory(Class c){
Car car = null;
try {
car = (Car) Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return car;
}
}
代碼實例
上面清楚了簡單工廠模式接下來看一下簡單工廠模式實際的運用。
在JDK中處理時間不光有Date這個類還有Calendar類,在Calendar類中就使用了簡單工廠模式。看一下getInstance()方法裏面的實現
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
它在裏面調用了createCalendar
方法而後在createCalendar
方法裏面有如下實現,是否是很熟悉這裏就是運用咱們一開始實現的簡單工廠模式
總結
簡單工廠模式類型是建立型,可是它不屬於23種設計模式,它只是一種實現方法。運用場景建立的對象比較少,而後工廠只須要知道須要什麼就返回什麼而後也不須要關心關鍵邏輯的時候就可使用簡單工廠模式,優勢:客戶端能夠免除建立對象的責任直接交給工廠進行建立還有就是 只須要知道傳入的參數就能夠獲取到所須要的參數並且無需知道建立細節。缺點就是違背了開閉原則還違反了高內聚低耦合的原則。
最後
開胃小菜已經奉上,下一篇來看工廠模式更高級的實現。歡迎關注轉發,最後在附一個簡單工廠模式的邏輯導圖
參考資料
工廠模式介紹: 參考菜鳥教程
[2]GOF: https://baike.baidu.com/item/GoF
推薦閱讀
![](http://static.javashuo.com/static/loading.gif)
點擊閱讀原文,得到更多精彩內容
本文分享自微信公衆號 - 亂敲代碼(lqcoder)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。