Simple Factory

Prerequisites:

未優化前

以下是一個訂購Pizza與制作Pizza的流程。

制作Pizza

Pizza

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public abstract class Pizza {
  private String name;
  public void setName(String name) {
    this.name = name;
  }
  public String getName() {
    return name;
  }
  // 不同的pizza準備的材料不同,由不同的pizza去覆寫
  public abstract void prepare();
  // 相同的作法就統一寫
  public void bake() {
    System.out.println("放進烤箱");
  }
  public void cut() {
    System.out.println("把pizza切片");
  }
  public void box() {
    System.out.println("pizza裝進盒子");
  }
}

CheesePizza

1
2
3
4
5
6
public class CheesePizza extends Pizza{
  @Override
  public void prepare() {
    System.out.println(getName() + "有:起士");
  }
}

TomatoPizza

1
2
3
4
5
6
public class TomatoPizza extends Pizza{
  @Override
  public void prepare() {
    System.out.println(getName() + "有:蕃茄");
  }
}

訂購pizza

OrderPizza

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OrderPizza {
  public OrderPizza() {
    Pizza pizza = null;
    String pizzaType;
    do {
      pizzaType = getType();
      if (pizzaType.equals("tomato")) {
        pizza = new TomatoPizza();
        pizza.setName("瑪格麗特pizza");
      } else if (pizzaType.equals("cheese")) {
        pizza = new CheesePizza();
        pizza.setName("起士pizza");
      } else {
        // 輸入其它的字就離開迴圈
        break;
      }
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
    } while (true);
  }
  private String getType() {
    try {
      BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type:");
      String str = strin.readLine();
      return str;
    } catch (IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}

main 主程式

1
2
3
4
5
public class PizzaStore {
  public static void main(String[] args) {
    OrderPizza orderPizza = new OrderPizza();
  }
}
input pizza type:
cheese
起士pizza有:起士
放進烤箱
把pizza切片
pizza裝進盒子
input pizza type:
tomato
瑪格麗特pizza有:蕃茄
放進烤箱
把pizza切片
pizza裝進盒子
input pizza type:
a

優化

以上的問題是,為什麼產生pizza的程式碼在訂購的流程中?

1
2
3
4
5
6
7
8
9
10
  if (pizzaType.equals("tomato")) {
    pizza = new TomatoPizza();
    pizza.setName("瑪格麗特pizza");
  } else if (pizzaType.equals("cheese")) {
    pizza = new CheesePizza();
    pizza.setName("起士pizza");
  } else {
    // 輸入其它的字就離開迴圈
    break;
  }

把產生pizza的程式碼放入工廠的類別中,由Pizza工廠來生產pizza,只需要給它pizzaType的參數。

SimpleFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
public class SimpleFactory {
  public Pizza createPizza(String pizzaType) {
    Pizza pizza = null;
    if (pizzaType.equals("tomato")) {
      pizza = new TomatoPizza();
      pizza.setName("瑪格麗特pizza");
    } else if (pizzaType.equals("cheese")) {
      pizza = new CheesePizza();
      pizza.setName("起士pizza");
    }
    return pizza;
  }
}

OrderPizza類別增加設置Pizza工廠

1
2
3
4
  private SimpleFactory factory;
  public void setFactory(SimpleFactory factory) {
    this.factory = factory;
  }

OrderPizza增加order()的方法,只負責取得pizza的種類、事前準備prepare()、烤、切、裝盒子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void order() {
  Pizza pizza = null;
  String pizzaType;
  do {
    pizzaType = getType();
    // 產生pizza
    pizza = factory.createPizza(pizzaType);
    // 跳離迴圈
    if (pizza == null) break;
    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();
  } while (true);
}

類別圖如下:

setFactory是聚合的關係,所以是用空白菱型,請見類別圖文章。

img

完整的OrderPizza

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OrderPizza {
  private SimpleFactory factory;
  public void setFactory(SimpleFactory factory) {
    this.factory = factory;
  }
  public void order() {
    Pizza pizza = null;
    String pizzaType;
    do {
      pizzaType = getType();
      pizza = factory.createPizza(pizzaType);
      if (pizza == null) break;
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
    } while (true);
  }
  public OrderPizza() {
  }
  private String getType() {
    try {
      BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type:");
      String str = strin.readLine();
      return str;
    } catch (IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}

results matching ""

    No results matching ""