- 👏作者簡介:大家好,我是卷心菜~~,在校大二學生一枚,Java領域新星創作者,
- 📝個人主頁:卷心菜的CSDN博客
- 📕系列專欄:本文寫在Java設計模式專欄:不就是Java設計模式嗎
- 📧如果文章知識點有錯誤的地方,請指正!和大家一起學習,一起進步👀
- 🔥如果感覺博主的文章還不錯的話,請👍三連支持👍一下博主哦
文章目錄
- 前言
- 一、使用傳統方法
- 類圖
- 步驟概括
- 步驟一:創建一個Pizza抽象類
- 步驟二:創建兩個披薩類
- 步驟三:制定訂購披薩類
- 步驟四:創建運行類
- 優缺點分析
- 二、使用簡單工廠
- 類圖
- 基本介紹
- 步驟概括
- 步驟一:創建簡單工廠
- 步驟二:制定訂購披薩類
- 優點分析
- 三、使用工廠方法
- 新的需求
- 類圖
- 基本介紹
- 步驟概括
- 步驟一:創建四個披薩類
- 步驟二:創建訂購披薩抽象類
- 步驟三:創建運行類
- 四、使用抽象工廠
- 類圖
- 基本介紹
- 步驟概括
- 步驟一:創建總工廠介面
- 步驟二:創建分工廠
- 步驟三:創建訂購類
- 步驟四:創建運行類
- 總結
前言
今天學習了Java設計模式中的工廠模式,整理了一下老師的筆記;文中的類圖(自己懶的畫了),可以供大家參考一下類與類之間的關系,希望大家喜歡,
一、使用傳統方法
類圖

步驟概括
步驟一:創建一個Pizza抽象類
public abstract class Pizza {
public 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;
}
}
分析: 這個類用來代表制作披薩的整個流程:準備階段prepare()、烘烤階段bake()、切割階段cut()和打包階段box() ,假設各個披薩的準備階段需要的材料不一樣,所以把準備階段定義為一個抽象方法 ,其它三個階段都一樣,
步驟二:創建兩個披薩類
public class CheesePizza extends Pizza{
@Override
public void prepare() {
System.out.println("奶酪披薩正在準備中");
}
}
分析: 這個類代表奶酪披薩,簡單重寫一下準備階段
public class BeefPizza extends Pizza{
@Override
public void prepare() {
System.out.println("牛肉披薩正在準備中");
}
}
分析: 這個類代表牛肉披薩,也簡單重寫一下準備階段
步驟三:制定訂購披薩類
public class OrderPizza {
public OrderPizza() {
Pizza pizza = null;
do {
String pizzaType = getType();
if ("cheese".equalsIgnoreCase(pizzaType)) {
pizza = new CheesePizza();
pizza.setName("cheese");
} else if ("beef".equalsIgnoreCase(pizzaType)) {
pizza = new BeefPizza();
pizza.setName("beef");
} 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 種類:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
分析: 慢慢看代碼,可以明白,訂購披薩的邏輯代碼寫在了該類的構造器中,getType()方法是用來獲取希望訂購的披薩種類,但是,如果我們需要添加新的披薩,就需要從這個類中繼續添加相應的邏輯陳述句,從而修改了訂購披薩的這個類,就違反了OCP原則
步驟四:創建運行類
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza();
}
}
運行結果:

優缺點分析
優點:比較好理解,簡單易操作缺點:違反了設計模式的ocp原則,即對擴展開放,對修改關閉,即當我們給類增加新功能的時候,盡量不修改代碼,或者盡可能少修改代碼
二、使用簡單工廠
類圖

基本介紹
簡單工廠模式是屬于創建型模式,是工廠模式的一種,簡單工廠模式是由一個工廠物件決定創建出哪一種產品類的實體,簡單工廠模式是工廠模式家族中最簡單實用的模式簡單工廠模式定義了一個創建物件的類,由這個類來封裝實體化物件的行為(代碼)在軟體開發中,當我們會用到大量的創建某種、某類或者某批物件時,就會使用到工廠模式
步驟概括
步驟一:創建簡單工廠
public class SimpleFactory {
public static Pizza createPizza2(String orderType) {
Pizza pizza = null;
if ("beef".equalsIgnoreCase(orderType)) {
pizza = new BeefPizza();
pizza.setName(" beef ");
} else if ("cheese".equalsIgnoreCase(orderType)) {
pizza = new CheesePizza();
pizza.setName("cheese");
}
return pizza;
}
}
分析: 簡單工廠又叫做靜態工廠,我們寫一個靜態方法,可以方便后面代碼的呼叫,這里用到的類,跟用傳統方法用到的類一樣,沒有改變
步驟二:制定訂購披薩類
public class OrderPizza2 {
public OrderPizza2() {
do {
String orderType = getType();
Pizza pizza = SimpleFactory.createPizza2(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("input pizza 種類:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
分析: 該類的構造器中用到了簡單工廠類SimpleFactory,這樣,我們就不需要在訂購披薩這一行為中去寫增加新的披薩的代碼了,而是從工廠中寫添加新的披薩的代碼,就不用再改動這個類,
運行結果:

優點分析
使用簡單工廠模式來創建物件,更加的方便靈活,不需要修改訂購披薩的邏輯
三、使用工廠方法
新的需求
客戶在點披薩時,可以點不同口味的披薩,比如 北京的奶酪pizza、北京的胡椒pizza 或者是倫敦的奶酪pizza、倫敦的胡椒pizza
類圖

基本介紹
工廠方法模式設計方案:將披薩專案的實體化功能抽象成抽象方法,在不同的口味點餐子類中具體實作,工廠方法模式:定義了一個創建物件的抽象方法,由子類決定要實體化的類,工廠方法模式將物件的實體化推遲到子類,
步驟概括
步驟一:創建四個披薩類
public class BJCheesePizza extends Pizza {
@Override
public void prepare() {
setName("北京的奶酪pizza");
System.out.println("北京的奶酪pizza 準備原材料");
}
}
分析: Pizza類跟上面的代碼一樣,我就沒有再次寫了,此類是用來創建北京的奶酪口味的披薩
public class BJPepperPizza extends Pizza{
@Override
public void prepare() {
setName("北京的胡椒pizza");
System.out.println("北京的胡椒pizza 準備原材料");
}
}
分析: 此類是用來創建北京的辣椒口味的披薩
public class LDCheesePizza extends Pizza {
@Override
public void prepare() {
setName("倫敦的奶酪pizza");
System.out.println("倫敦的奶酪pizza 準備原材料");
}
}
分析: 此類是用來創建倫敦的奶酪口味的披薩
public class LDPepperPizza extends Pizza {
@Override
public void prepare() {
setName("倫敦的胡椒pizza");
System.out.println("倫敦的胡椒pizza 準備原材料");
}
}
分析: 此類是用來創建倫敦的辣椒口味的披薩
步驟二:創建訂購披薩抽象類
public abstract class OrderPizza {
abstract Pizza createPizza(String orderType);
public OrderPizza() {
do {
String orderType = getType();
Pizza pizza = createPizza(orderType); //抽象方法,由工廠子類完成
if (pizza == null){
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("input pizza 種類:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
分析: 此類中定義一個抽象方法createPizza(), 讓各個工廠子類自己實作,構造器中寫訂購披薩的代碼邏輯;getType()方法跟原來的沒有區別,
public class BJOrderPizza extends OrderPizza {
@Override
Pizza createPizza(String orderType) {
Pizza pizza = null;
if(orderType.equals("cheese")) {
pizza = new BJCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new BJPepperPizza();
}
return pizza;
}
}
分析: 此類用來繼承OrderPizza類,成為北京地區的訂購披薩分銷商
public class LDOrderPizza extends OrderPizza {
@Override
Pizza createPizza(String orderType) {
Pizza pizza = null;
if(orderType.equals("cheese")) {
pizza = new LDCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new LDPepperPizza();
}
return pizza;
}
}
分析: 此類也用來繼承OrderPizza類,成為倫敦地區的訂購披薩分銷商
步驟三:創建運行類
public class PizzaStore {
public static void main(String[] args) {
String loc = "beijing";
if (loc.equals("beijing")) {
new BJOrderPizza();
} else {
new LDOrderPizza();
}
}
}
分析: 假設就是買北京地區的披薩
運行結果:

四、使用抽象工廠
類圖

基本介紹
抽象工廠模式定義了一個interface用于創建相關或有依賴關系的物件簇,而無需指明具體的類抽象工廠模式可以將簡單工廠模式和工廠方法模式進行整合從設計層面看,抽象工廠模式就是對簡單工廠模式的改進(或者稱為進一步的抽象)將工廠抽象成兩層,AbsFactory(抽象工廠) 和 具體實作的工廠子類,程式員可以根據創建物件型別使用對應的工廠子類,這樣將單個的簡單工廠類變成了工廠簇,更利于代碼的維護和擴展,
步驟概括
步驟一:創建總工廠介面
public interface AbsFactory {
public Pizza createPizza(String orderType);
}
分析: 此類是用來讓下面的工廠子類來具體實作
步驟二:創建分工廠
public class BJFactory implements AbsFactory {
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if(orderType.equals("cheese")) {
pizza = new BJCheesePizza();
} else if (orderType.equals("pepper")){
pizza = new BJPepperPizza();
}
return pizza;
}
}
分析: 這是工廠子類,用來制作北京的披薩
public class LDFactory implements AbsFactory {
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if (orderType.equals("cheese")) {
pizza = new LDCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new LDPepperPizza();
}
return pizza;
}
}
分析: 這是工廠子類,用來制作倫敦的披薩
步驟三:創建訂購類
public class OrderPizza {
private AbsFactory factory;
public OrderPizza(AbsFactory factory) {
setFactory(factory);
}
private void setFactory(AbsFactory factory) {
do {
this.factory = factory;
String orderType = getType();
// factory 可能是北京的工廠子類,也可能是倫敦的工廠子類
Pizza pizza = factory.createPizza(orderType);
if (pizza == null) {
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("input pizza 種類:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
分析: Pizza pizza = factory.createPizza(orderType);這一陳述句主要運用的是java基礎里面的多型,具體的實作功能交給實作其介面的子類
步驟四:創建運行類
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza(new LDFactory());
}
}
分析: 假設買的是倫敦地區的披薩
運行結果:

總結
1、工廠模式的意義:
將實體化物件的代碼提取出來,放到一個類中統一管理和維護,達到和主專案的依賴關系的解耦,從而提高專案的擴展和維護性,
2、三種工廠模式 (簡單工廠模式、工廠方法模式、抽象工廠模式)
3、設計模式的依賴抽象原則
創建物件實體時,不要直接 new 類, 而是把這個new 類的動作放在一個工廠的方法中,并回傳
不要讓類繼承具體類,而是繼承抽象類或者是實作interface(介面)
不要覆寫基類中已經實作的方法,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/413392.html
標籤:java
