【design pattern】工廠方法模式和抽象工廠模式

前言

設計模式分為三大類:

創建型模式:工廠方法模式抽象工廠模式、單例模式、建造者模式、原型模式;

結構型模式:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式;

行為型模式:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式;

簡單工廠

首先要明確的是,簡單工廠模式不屬于23種設計模式,它引入了創建者的概念,將實例化的代碼從應用代碼中抽離,在工廠類的靜態方法中只處理被創建的對象,如果業

務需要變更則需要在工廠類中添加具體的實現類,因此維護性較差。以"工廠創建咖啡"為例說明,如下:

1. 物品標識類Coffee和已有的類

package com.oxygen.bean;/*** * 咖啡則作為一種抽象概念:拿鐵、美式咖啡、卡布奇諾等均為咖啡家族的一種產品* @author Oxygen**/
public abstract class Coffee {public abstract String desc(); //獲取coffee名稱

}class Americano extends Coffee { // 美式咖啡
@Overridepublic String desc() {return "美式咖啡";}}class Cappuccino extends Coffee { //卡布奇諾
@Overridepublic String desc() {return "卡布奇諾";}}class Latte extends Coffee { //拿鐵
@Overridepublic String desc() {return "拿鐵";}}
View Code

2. 簡單工廠

package com.oxygen.bean;/*** 創建材料的工廠類* @author Oxygen *    @date 2018年10月16日*/
public class SimpleFactory {/*** * @param type 材料類型* @return*/public static Coffee createInstance(String type) {if ("Americano".equals(type)) {return new Americano();} else if ("Cappuccino".equals(type)) {return new Cappuccino();} else if ("Latte".equals(type)) {return new Latte();} else {throw new RuntimeException("type[" + type + "]類型不可識別,沒有匹配到可實例化的對象!");}}public static void main(String[] args) {System.out.println(SimpleFactory.createInstance("Americano").desc());System.out.println(SimpleFactory.createInstance("Cappuccino").desc());System.out.println(SimpleFactory.createInstance("Latte").desc());}
}
View Code

3. 輸出結果

美式咖啡
卡布奇諾
拿鐵

工廠方法

?工廠方法模式其定義了一個創建對象的接口,由子類決定要實例化的類是哪一個,工廠方法讓類把實例化推遲到了子類,也就是說一個工廠只能生成特定的Coffee

1. 工廠類

package com.oxygen.bean;/*** Coffee工廠* @author Oxygen *    @date 2018年10月16日*/
public abstract interface CoffeeFactory {public abstract Coffee[] createCoffee();public static void main(String[] args) {CoffeeFactory chinaCoffeeFactory = new ChinaCoffeeFactory();Coffee[] chinaCoffees = chinaCoffeeFactory.createCoffee();System.out.print("中國咖啡工廠可以生產的咖啡有:");print(chinaCoffees);CoffeeFactory americaCoffeeFactory = new AmericaCoffeeFactory();Coffee[] americaCoffees = americaCoffeeFactory.createCoffee();System.out.print("美國咖啡工廠可以生產的咖啡有:");print(americaCoffees);}public static void print(Coffee[] c) {for (Coffee coffee : c) {System.out.print(coffee.desc() + " ");}System.out.println();}
}class ChinaCoffeeFactory implements CoffeeFactory { //中國咖啡工廠
@Overridepublic Coffee[] createCoffee() {return new Coffee[] { new Cappuccino(), new Latte() };}}class AmericaCoffeeFactory implements CoffeeFactory { //美國咖啡工廠
@Overridepublic Coffee[] createCoffee() {return new Coffee[] { new Americano(), new Latte() };}}
View Code

2. 輸出結果

中國咖啡工廠可以生產的咖啡有:卡布奇諾 拿鐵 
美國咖啡工廠可以生產的咖啡有:美式咖啡 拿鐵 

抽象工廠

提供一個接口,用于創建相關或依賴對象的家族,而不需要明確指定具體類,在上述的場景上繼續延伸:咖啡工廠做大做強,引入了新的飲品種類:茶、 碳酸飲

料。中國工廠只能制造咖啡和茶,美國工廠只能制造咖啡和碳酸飲料,如果繼續使用上述工廠方法方式,除去對應的產品實體類還需要新增2個抽象工廠(茶制造

工廠、碳酸飲料制造工廠),4個具體工廠實現。

隨著產品的增多,會導致類爆炸,這顯然是不能接受的。所以這里引出一個概念產品家族,在此例子中,不同的飲品就組成我們的飲品家族, 飲品家族開始承擔

創建者的責任,負責制造不同的產品。如下:

package com.oxygen.bean;public interface AbstractDrinksFactory {Coffee createCoffee(); //制造咖啡
Tea createTea(); //制造茶
Sodas createSodas();//制造碳酸飲料
}/*** 中國飲品工廠:制造咖啡與茶*/
class ChinaDrinksFactory implements AbstractDrinksFactory {@Overridepublic Coffee createCoffee() {return new Latte();}@Overridepublic Tea createTea() {return new MilkTea();}@Overridepublic Sodas createSodas() {// TODO Auto-generated method stubreturn null;}
}/*** 美國飲品制造工廠:制造咖啡和碳酸飲料*/
class AmericaDrinksFactory implements AbstractDrinksFactory {@Overridepublic Coffee createCoffee() {// TODO Auto-generated method stubreturn new Latte();}@Overridepublic Tea createTea() {// TODO Auto-generated method stubreturn null;}@Overridepublic Sodas createSodas() {// TODO Auto-generated method stubreturn new CocaCola();}}
View Code

總結

工廠模式可以幫助我們針對抽象接口編程,而不是針對具體類編程,在不同的場景下按具體情況來

1. 簡單工廠:不能算是真正意義上的設計模式,但可以將客戶程序從具體類解耦;

2. 工廠方法:使用繼承,把對象的創建委托給子類,由子類來實現創建方法,可以看作是抽象工廠模式中只有單一產品的情況;

3. 抽象工廠:使對象的創建被實現在工廠接口所暴露出來的方法中;

轉載于:https://www.cnblogs.com/oxygenG/p/9797254.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/396486.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396486.shtml
英文地址,請注明出處:http://en.pswp.cn/news/396486.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux中使用隨機數

(1)單純使用rand重復調用n次,就會得到一個0-RAND_MAX之間的偽隨機數,如果需要調整范圍,可以得到隨機數序列后再進行計算。(2)單純使用rand來得到偽隨機數序列有缺陷,每次執行程序得到的偽隨機序列是同一個序列,沒法得到…

mysql 異地備份工具_異地備份簡單實現(mysql)

該腳本只適用于MYISAM引擎,如果需要適用于innodb,請修改備份命令即可。#!/bin/bash#該腳本只能用來備份myisam引擎數據庫#author:vaedit#date:2017/9/18#備份過程function beifen(){BACKDIRdate "%Y-%m-%d-%H"mkdir /backup/$BACKD…

python管理數據庫設計_Pycharm+Django+Python+MySQL開發 后臺管理數據庫

Django框架十分簡單易用,適合搭建個人博客網站。網上有很多教程,大多是關于命令行操作Django,這里分享一些用最新工具進行Django開發過程,主要是PyCharm太強大,不用有點可惜。第一次寫技術開發類的博文,可能…

你鼓舞了我是世界杯主題曲嗎_選擇方法和鼓舞人心的網站列表

你鼓舞了我是世界杯主題曲嗎by Kristoffer Andreasen通過克里斯托弗安德烈森 選擇方法和鼓舞人心的網站列表 (The pick and choose approach and a list of inspirational websites) In the past couple of years I have created quite a few websites. In the beginning, I h…

共享程序集GAC

原文標題: 原文地址:https://www.cnblogs.com/1996V/p/9037603.html 共享程序集GAC 我上面說了這么多有關CLR加載程序集的細節和規則,事實上,類似于mscorlib.dll、System.dll這樣的FCL類庫被引用的如此頻繁,它已經是我…

彈簧觸摸開關原理圖_10年老電工經驗之談:常見的開關電源那些事兒

隨著電控系統中對控制回路安全性要求提高,控制回路的工作電壓是越來越趨于直流低壓化。由此,控制回路內各種使用直流電源的傳感器、中小微型直流繼電器等電器裝置是日益增多。也正因如此,電控系統內不同品牌的開關電源也相應地多了起來。因牽…

erlang mysql連接超時_Erlang數據庫-(一)Erlang與Mysql的連接

下載:http://download.csdn.net/detail/hjhjava/7088277把該文件的東西全部編譯好,然后根據下面的解釋就可以操作Mysql的。很簡單~-record(row,{a1 0, a20}).%% 第一個參數是該鏈接的名字(根據它來操作Mysql),第二參數是本機號(ip地址)%% &a…

SQL SERVER 中 GO 的用法2

具體不廢話了&#xff0c;請看下文詳解。 12345678910use db_CSharpgoselect *,備注casewhen Grade>90 then 成績優秀when Grade<90 and Grade>80 then 成績良好when Grade<80 and Grade>70 then 成績及格else 不及格endfrom tb_Grade如果只是執行一條語句&…

js中判斷值不等于undefined

文章&#xff1a;JS 中判斷空值 undefined 和 null轉載于:https://www.cnblogs.com/Tpf386/p/9804496.html

reddit_我在3天內瘋狂地審查了Reddit上的50個投資組合,從中學到了什么。

redditI’ve always enjoyed critiquing applicants’ portfolios at the design studio where I work. And I also often ask for feedback on my own designs on Reddit’s webdev subreddit.我一直都很喜歡在我工作的設計工作室里評估申請人的作品集。 我也經常在Reddit的we…

【BZOJ1001】[BeiJing2006]狼抓兔子

挺簡單一個題&#xff0c;最小割模板 我的感覺就是可能建圖的時候會比較麻煩吧&#xff0c;畢竟三個方向。 #include <cctype> #include <climits> #include <cstdio> #include <cstring> #include <iostream>#define debug(x) std::cout <&l…

管理活動目錄域服務實訓_管理學院學生黨支部開展實踐教育基地服務活動

紅星E校有態度 有溫度 可關注為進一步加強黨的建設&#xff0c;深化管理學院學生黨支部與實踐基地的互動性&#xff0c;2020年9月11至12日&#xff0c;管理學院學生黨支部協助白鶴村村委實踐基地完成第七次人口普查相關工作&#xff0c;共計6名預備黨員參與。工作開始前的培訓會…

mysql 漢編碼 的選_peewee連接mysql漢語言數據編碼_mysql

peewee連接mysql中文數據編碼系統是win7 x64python 2.7.6的site.py里面編碼設定為 utf-8py文件首行指定 #coding:utf-8mysql 5.5.38安裝時指定代碼為utf-8peewee的連接數據庫代碼為&#xff1a;db MySQLDatabase(host 127.0.0.1, user root, passwd 1, database mz, chars…

配置windows失敗,還原更新,請勿關機

最近給同事裝系統&#xff0c;偶爾會出現如下問題&#xff1a; 如果是這種情況&#xff0c;只能耐心等待了&#xff0c;因為關機也沒用&#xff01; 轉載于:https://www.cnblogs.com/lijy/p/5327844.html

使用Express和MongoDB構建簡單的CRUD應用程序

by Zell Liew由Zell Liew 使用Express和MongoDB構建簡單的CRUD應用程序 (Building a Simple CRUD Application with Express and MongoDB) For a long time, I didn’t dare venture into back end development. I felt intimidated because of my lack of an academic backgr…

python元類的使用_python中元類用法實例

本文實例講述了python中元類用法&#xff0c;分享給大家供大家參考。具體方法分析如下&#xff1a;1.元類(metaclass)是用來創建類的類2.type(object):返回一個對象的類型&#xff0c;與object.__class__的值相同&#xff0c;type(name,bases,dict):創建一個新的type類型&#…

使用uicollectionView時需要注意的問題

1.UICollectionView使用流水布局——UICollectionViewFlowLayout時&#xff0c;需要滿足條件&#xff1a; 每個item(即cell)的大小是一樣的&#xff0c;不僅是寬度&#xff0c;還有高度。這樣&#xff0c;當collectionview的寬度發生變化時&#xff0c;item能將其動態填充。ite…

hiveql函數筆記(二)

1、數據查詢 //提高聚合的性能 SET hive.map.aggrtrue; SELECT count(*),avg(salary) FROM employees; //木匾不允許在一個查詢語句中使用多于一個的函數&#xff08;DISTINCT。。。&#xff09;表達式 SELECT count(DISTINCT symbol) FROM stocks; 表生成函數&#xff1a; exp…

jQuery 常用的方法

<!DOCTYPE html><html lang"en"><head> <meta charset"utf-8"/> <title>品牌列表案例</title> <script src"js/jquery-2.1.1.min.js" rel"script"></script> <script…

swift 從手機選照片_19元起!定制專屬手機殼!還可免費打印照片...

△劇透&#xff1a;文末有福利現在的年輕人體內涌動的都是追求有趣有特色的靈魂希望自己是這條gai最獨一無二的仔撞衫撞包撞手機殼可以說是當代年輕人三大時尚忌諱尤其是手機殼極為重要畢竟換殼≈換機只需要幾十元買新殼就可以擁有換新機般的儀式感不過作為手機殼老手都知道在某…