定義
工廠方法模式的作用就是封裝對象的創(chuàng)建攻柠,由子類決定要創(chuàng)建的對象是什么隔显。
適用范圍
工廠方法模式特別適合與需要創(chuàng)建復雜對象的場景
實現
首先可以看一下,工廠方法模式的UML類圖
這樣一個圖看起來可能有點暈躏惋,下面就結合時下最流行的共享單車泣懊,寫一個工廠方法模式的通用模式代碼。
/**
* 抽象單車產品
*簡單起見煤墙,單車的制造方式(外觀)和計費方式 作為單車類的兩個方法
*/
public interface Bicycle {
/**
* 單車生產方式
*/
String manufacture();
/**
* 單車計費方式
*/
String billing();
}
/**
* Bicycle 抽象單車生產工廠
*/
public interface BicycleFactory {
Bicycle makeBicycle();
}
public class Mobike implements Bicycle {
@Override
public String manufacture() {
System.out.print("摩拜單車---橙色---有定位功能");
return "摩拜單車---橙色---有定位功能";
}
@Override
public String billing() {
System.out.print("Mobike每30分鐘收費1元");
return "Mobike每30分鐘收費1元";
}
}
public class MobikeFactory implements BicycleFactory {
@Override
public Bicycle makeBicycle() {
return new Mobike();
}
}
public class Ofo implements Bicycle {
@Override
public String manufacture() {
System.out.print("ofo單車---黃色---密碼不變");
return "ofo單車---黃色---密碼不變";
}
@Override
public String billing() {
System.out.print("ofo單車: 師生認證用戶0.5元/小時梅惯,非師生用戶1元/小時");
return "ofo單車: 師生認證用戶0.5元/小時顾患,非師生用戶1元/小時";
}
}
public class OfoFactory implements BicycleFactory {
@Override
public Bicycle makeBicycle() {
return new Ofo();
}
}
在上面的代碼中:
- Bicycle 抽象產品
- Mobike 和 Ofo 具體產品
- BicycleFactory 抽象工廠
- MobikeFactory 和 OfoFactory 具體的工廠
這就是工廠模式。所有的產品(Mobike和Ofo)有共同的父類 Bicycle个唧,而每一個產品又有各自的工廠(MobikeFactory和
OfoFactory)去負責創(chuàng)建自己江解;當然這里所有的產品可以有公共的工廠,在公共的工廠里通過參數負責生成不同的產品徙歼。如下方式:
/**
* 所有產品共用一個工廠
*/
public class CommonFactory {
public static Bicycle makeBicycle(String type) {
switch (type) {
case "mobike":
return new Mobike();
case "ofo":
return new Ofo();
default:
return null;
}
}
}
個人感覺犁河,每個產品使用各自的工廠是一種更有設計模式的做法,也就是更符合開閉原則魄梯;如果有了新產品桨螺,就不必去修改原有的工廠,增加新的產品和工廠即可酿秸。
有個工廠灭翔,就非常方便我們去創(chuàng)建不同的對象了。
public class FactoryPatternActivity extends AppCompatActivity {
private TextView bike_result;
private BicycleFactory factory;
private Bicycle mBicycle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_factory_pattern);
bike_result = V.f(this, R.id.bike_result);
}
public void MobikeClick(View view) {
factory = new MobikeFactory();
mBicycle = factory.makeBicycle();
updateView(mBicycle);
}
public void OfoClick(View view) {
factory = new OfoFactory();
mBicycle = factory.makeBicycle();
updateView(mBicycle);
}
private void updateView(Bicycle mBicycle) {
bike_result.setText("");
StringBuilder sb = new StringBuilder();
sb.append(mBicycle.manufacture())
.append("\n")
.append(mBicycle.billing());
bike_result.setText(sb.toString());
}
}
在這里使用工廠模式辣苏,BicycleFactory 封裝了Bicycle 對象具體生成的過程肝箱;當需要具體的對象時,調用每個對象各自的工廠生成對象即可稀蟋。試想煌张,如果沒有使用工廠模式,那么這里FactoryPatternActivity 將包含大量的代碼去負責創(chuàng)建復雜的Bicycle對象退客,但是從MVP的角度來說骏融,這是完全不屬于Activity(View)的工作。
Android 中的Factory
BitmapFactory
在Android 系統(tǒng)中萌狂,說道Factory大家第一個想到的可能就是BitmapFactory了档玻。研究過Bitmap的同學應該清楚,BitmapFactory 為了方便開發(fā)者茫藏,提供了一系列的方法方便大家通過各種途徑創(chuàng)建Bitmap误趴。
這里可以看一下decodeStream(InputStream is) 方法:
public static Bitmap decodeStream(InputStream is) {
return decodeStream(is, null, null);
}
可以看到,這里又會去調用別的方法刷允;最終上述的所有方法冤留,殊途同歸都會調用到一些native的方法去真正的完成Bitmap的創(chuàng)建。其實按照上面的UML圖來說树灶,嚴格來說BitmapFactory 的實現并不是工廠方法模式;只能說是簡單工廠糯而。在BitmapFactory類中對于唯一的產品Bitmap只有唯一的工廠BitmapFactory天通,它所有的生產方法都是靜態(tài)的;如果要新增一種生產Bitmap的方式熄驼,就得修改唯一的工廠(BitmapFactory)像寒。因此烘豹,從設計模式的角度來說,完全不符合開閉原則诺祸。
這里并不是說BitmapFactory這個類的寫法不好携悯,只是剛好從工廠方法模式的角度找了一個大家熟悉的類做了一個分析,Android系統(tǒng)的代碼其實寫的很好筷笨。BitmapFactory 這個類里包含的方法已經夠大家使用憔鬼,因此它設計成這個樣子是完全合理的。
onCreate 方法
《Android 源碼設計模式解析于實戰(zhàn)》這本書中提到 onCreate 方法是的實現可以說是工廠模式胃夏,的確從廣義角度來說轴或,通過不同的參數(R.layout.acitity) 創(chuàng)建出了不同的View;的確是可以算是工廠模式仰禀。至于具體代碼的實現邏輯照雁,這里就不拾人牙慧了。
總結
總的來說答恶,工廠模式就是種瓜得瓜饺蚊,種豆得豆;根據不同的輸入創(chuàng)建不同類型的對象悬嗓。通過上面的實例其實可以總結出規(guī)律卸勺,當我們在代碼中寫了很多if-else或者是switch時,是不是可以考慮以下使用工廠模式烫扼,也許我們就是在創(chuàng)建不通過的對象曙求,也許只是自己沒有發(fā)現。
工廠方法模式真的感覺只能意會映企,不能言傳悟狱。看別人寫的東西總是忘掉堰氓,這樣自己寫一遍才算理解了挤渐。