文章目錄
- 1 用執行個體引出問題
-
- 1.1 執行個體需求
- 2 傳統方法完成執行個體
-
- 2.1 使用傳統方法的類圖
- 2.2 代碼實作
- 2.3 分析傳統的方式的優缺點
- 3 簡單工廠模式的介紹
- 4 使用簡單工廠模式
-
- 4.1 改進類圖
- 4.2 代碼實作
1 用執行個體引出問題
首先我們先用一個執行個體來引出問題.
1.1 執行個體需求
看一個披薩的項目:要便于披薩種類的擴充,要便于維護.
- 披薩的種類很多(比如 GreekPizz、CheesePizz 等)
- 披薩的制作有 prepare(準備原材料),bake(烘烤), cut(切割), box(打包)
- 完成披薩店訂購功能。
2 傳統方法完成執行個體
2.1 使用傳統方法的類圖
類圖說明:
有一個抽象類Pizza的類,裡面有制作pizza的各種方法,而CheessPizza(奶酪披薩)和GreekPizza(希臘披薩)都繼承于Pizza類.OrderPizza是用來完成Pizza訂單的,它依賴于(用到)GreekPizza和CheessPizza.
2.2 代碼實作
Pizza 類
package com.andy.factory.simplefactory.pizza;
//将pizza類做成抽象類
public abstract class Pizza {
protected String name;
//準備原材料,不同的披薩用到的原材料不同,是以我們做成抽象方法.
public abstract void prepare();
public void bake() {
System.out.println(name + " baking;");
}
public void cut() {
System.out.println(name + " cutting ");
}
public void box() {
System.out.println(name + " boxing;");
}
public void setName(String name) {
this.name = name;
}
}
CheesePizza 類
package com.andy.factory.simplefactory.pizza;
public class CheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println(" 給制作奶酪披薩 準備原材料 ");
}
}
GreekPizza 類
package com.andy.factory.simplefactory.pizza;
public class GreekPizza extends Pizza {
@Override
public void prepare() {
System.out.println(" 給希臘披薩 準備原材料 ");
}
}
OrderPizza 類
package com.andy.factory.simplefactory.order;
import com.andy.factory.simplefactory.pizza.CheesePizza;
import com.andy.factory.simplefactory.pizza.GreekPizza;
import com.andy.factory.simplefactory.pizza.Pizza;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OrderPizza {
public OrderPizza() {
Pizza pizza = null;
String orderType;
do {
orderType = getType();
if ("greek".equals(orderType)){
pizza = new GreekPizza();
pizza.setName(" 希臘披薩 ");
}else if ("cheess".equals(orderType)){
pizza = new CheesePizza();
pizza.setName("奶酪披薩");
}else{
System.out.println(" 訂購披薩失敗 ");
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("請輸入披薩的種類: ");
String str = strin.readLine();
return str;
}catch (IOException e){
e.printStackTrace();
return "";
}
}
}
PizzaStory 類
package com.andy.factory.simplefactory.order;
public class PizzaStory {
public static void main(String[] args) {
new OrderPizza();
}
}
2.3 分析傳統的方式的優缺點
- 優點是比較好了解,簡單易操作。
- 缺點是違反了設計模式的ocp原則,即對擴充開放,對修改關閉。即當我們給類增加新功能的時候,盡量不修改代碼,或者盡可能少修改代碼.
-
比如我們這時要新增加一個Pizza的種類(Pepper披薩),我們需要做如下修改.
3-1. 增加一個PepperPizza 類
package com.andy.factory.simplefactory.pizza;
public class PepperPizza extends Pizza {
@Override
public void prepare() {
System.out.println(" 給胡椒披薩準備原材料 ");
}
}
3-2. 更改OrderPizza類的構造函數如下(違反開閉原則)
public OrderPizza() {
Pizza pizza = null;
String orderType;
do {
orderType = getType();
if ("greek".equals(orderType)){
pizza = new GreekPizza();
pizza.setName(" 希臘披薩 ");
}else if ("cheess".equals(orderType)){
pizza = new CheesePizza();
pizza.setName("奶酪披薩");
}else if ("pepper".equals(orderType)){//增加胡椒披薩的處理
pizza = new PepperPizza();
pizza.setName("胡椒披薩");
}else{
System.out.println(" 訂購披薩失敗 ");
break;
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}while (true);
}
-
改進的思路分析
分析:修改代碼可以接受,但是如果我們在其它的地方也有建立Pizza的代碼,就意味着,也需要修改,而建立Pizza的代碼,往往有多處。
思路:把建立Pizza對象封裝到一個類中,這樣我們有新的Pizza種類時,隻需要修改該類就可,其它有建立到Pizza對象的代碼就不需要修改了.這就是我們要介紹的 簡單工廠模式.
3 簡單工廠模式的介紹
- 簡單工廠模式是屬于建立型模式,是工廠模式的一種。簡單工廠模式是由一個工廠對象決定建立出哪一種産品類的執行個體。簡單工廠模式是工廠模式家族中最簡單實用的模式
- 簡單工廠模式:定義了一個建立對象的類,由這個類來封裝執行個體化對象的行為(代碼)
- 在軟體開發中,當我們會用到大量的建立某種、某類或者某批對象時,就會使用到工廠模式.
4 使用簡單工廠模式
簡單工廠模式的設計方案: 定義一個可以執行個體化Pizaa對象的類,封裝建立對象的代碼。
4.1 改進類圖
分析:
如上圖所示我們在原來的基礎上增加一個SimpleFactory類 用它來聚合所有的訂單,并且它依賴于所有種類的Pizza類.這樣如果增加一個種類的pizza就不用改orderpizza類,隻需要改動SimpleFactory類就可以了.
4.2 代碼實作
改動的地方隻有增加一個SimplePizza 類和改動OderPizza類,其他地方都不用動.
SimplePizza 類:
package com.andy.factory.simplefactory.order;
import com.andy.factory.simplefactory.pizza.CheesePizza;
import com.andy.factory.simplefactory.pizza.GreekPizza;
import com.andy.factory.simplefactory.pizza.PepperPizza;
import com.andy.factory.simplefactory.pizza.Pizza;
public class SimplePizza {
public static Pizza createPizza(String orderType){
Pizza pizza = null;
System.out.println("使用簡單工廠模式");
if ("greek".equals(orderType)){
pizza = new GreekPizza();
pizza.setName(" 希臘披薩 ");
}else if ("cheess".equals(orderType)){
pizza = new CheesePizza();
pizza.setName("奶酪披薩");
}else if ("pepper".equals(orderType)){//增加胡椒披薩的處理
pizza = new PepperPizza();
pizza.setName("胡椒披薩");
}
return pizza;
}
}
OrderPizza 類:
package com.andy.factory.simplefactory.order;
import com.andy.factory.simplefactory.pizza.CheesePizza;
import com.andy.factory.simplefactory.pizza.GreekPizza;
import com.andy.factory.simplefactory.pizza.PepperPizza;
import com.andy.factory.simplefactory.pizza.Pizza;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OrderPizza {
public OrderPizza() {
Pizza pizza = null;
String orderType;
do {
orderType = getType();
pizza = SimplePizza.createPizza(orderType);
if(pizza != null){
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
else{
System.out.println("訂購披薩失敗!");
break;
}
}while (true);
}
private String getType(){
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("請輸入披薩的種類: ");
String str = strin.readLine();
return str;
}catch (IOException e){
e.printStackTrace();
return "";
}
}
}
分析:
就像上面的改動一樣,增加SimplePizza類,這樣增加新的Pizza種類的時候就可以在SimplePizza類的createPizza方法中增加對應的判斷語句就可以了,不用去帶動OrderPizza類(假如有很多的OrderPizza類,這樣改動就會很多).這就是簡單工廠模式.