Android Factory pattern (工廠模式)

James pond’s Blog
7 min readMay 7, 2019

--

Photo by Lai Man Nung on Unsplash

學校教導我們Main function裡面不要寫太多程式碼,要越精簡越好,所以工程師們常常會分成很多個Class來實作

例如 :

GetWeather getWeather = new GetWeather(); 
String wind = getWeather.getWind();
String rain = getWeather.getRain();
GetUV getUV = new GetUV();
String uv_value = getUV.getData();

這是以前很常會寫的模式,隨著離開學校畢業後沒有人告訴你外面的世界是多麼大,業界程式碼更是不比學校作業單純,且對於系統程式效能要求也是更高水準。

隨著技術的精進,學習到了工廠模式(Factory pattern)以及其帶來的好處,慢慢改進寫程式的『藝術』。

MainActivity.java

public class MainActivity extends AppCompatActivity {
String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CarFactory factory = new CarFactory();
Car redCar = factory.createCarFromColor("RED", 5);
Car blueCar = factory.createCarFromColor("BLUE", 6);


Log.d(TAG, "Red Tire " + redCar.getAirBags());
//Red car Tire 4
Log.d(TAG, "Blue Tire " + blueCar.getAirBags());
//Blue Car Tire 8

Log.d(TAG, "Red metal size : " + redCar.getMetal());
//Red metal size : 35
Log.d(TAG, "Blue metal size : " + blueCar.getMetal());
//Blue metal size : 14
}
}

CarFactory.java (負責生產Objects)

public class CarFactory {

public Car createCarFromColor(String color, int metal_size){
switch (color){
case "RED" :
return new RedCar(metal_size);
case "BLUE" :
return new BlueCar(metal_size);
}
return null;
}
}

Car.java (定義我們Objects裡面的Method有哪些)

public interface Car {
Car CreateCar();
String getColor();
String getTires();
String getWindows();
String getAirBags();
int getMetal();
}

BlueCar.java

public class BlueCar implements Car {
int metal_size, result;

public BlueCar(int metal){
metal = metal * 2 + 2;
result = Math.round(metal); //四捨五入
}
@Override
public Car CreateCar() {
return new BlueCar(metal_size);
}

@Override
public String getColor() {
return "Blue Car";
}

@Override
public String getTires() {
return "4";
}

@Override
public String getWindows() {
return "2";
}

@Override
public String getAirBags() {
return "8";
}

@Override
public int getMetal() {
return result;
}
}

RedCar.java

public class RedCar implements Car {
int metal_size;
int result;
public RedCar(int metal){
metal = metal * 5 + 10;
result = Math.round(metal); //四捨五入
}

@Override
public Car CreateCar() {
return new RedCar(metal_size);
}

@Override
public String getColor() {
return "Red car";
}

@Override
public String getTires() {
return "4";
}

@Override
public String getWindows() {
return "2";
}

@Override
public String getAirBags() {
return "4";
}

@Override
public int getMetal() {
return result;
}

}

看到差異了嗎? Main function 裡面 我們統一使用Car factory 來產生Object。

但腦中有個問題 ?

這樣有帶來什麼好處嗎?還不是一樣呼叫各個Object的Method,只差在New object不再Main主程式裡面而已呀!!?

好處在於今天我要請工廠生產一台車只需要給他兩個參數(藍色,6個金屬單位)

剩下來的全部都會自動再BlueCar 裡面自動跑流程精準的計算出此款車所需的總金屬大小用量 (自訂公式 : metal = metal * 2 + 2)。

對應到常用的第三方Restful函式庫 HttpClient

StringEntity se = new StringEntity(json);
HttpClient client = new DefaultHttpClient();
HttpPut put = new HttpPut(url);
put.setEntity(se);
put.addHeader("Cookie",cookie);
HttpResponse response = client.execute(put);
HttpEntity entity = response.getEntity();

在一個Http Put 之前會有一些冗長前置作業,會需要先new HttpClient,還需要new HttpPut並帶入url參數,new出來的put物件裡面再放入名為se的json format,有些需要認證的還要加入cookie,最後再經由HttpResponse去執行。

以上這一串全部都可以在工廠模式內處理完畢,可以想像的到我們僅僅需要在MainActivity中呼叫代入一些參數後就會自動跑完以上的流程,得到我們要的Http response了,是不是很方便呢?

結論:

當有Class種類類似,方法都大同小異的功能時,可以使用工廠模式來設計,有時間再多介紹其他設計模式囉

可以參考MVP Link

Mvp : https://medium.com/@weizuju/android-login-form-for-mvp-%E8%A8%AD%E8%A8%88%E6%9E%B6%E6%A7%8B-3b513ad9db4e

Github : https://github.com/empirejames/factoryPattern.git

--

--