Java技術_每天掌握一種設計模式(003)_使用場景及簡單例項(建立型:工廠方法)
1.模式描述
提供一個用於建立物件的介面(工廠介面),讓其實現類(工廠實現類)決定例項化哪一個類(產品類),並且由該實現類建立對應類的例項。
2.模式作用
可以一定程度上解耦,消費者和產品實現類隔離開,只依賴產品介面(抽象產品),產品實現類如何改動與消費者完全無關。
可以一定程度增加擴充套件性,若增加一個產品實現,只需要實現產品介面,修改工廠建立產品的方法,消費者可以無感知(若消費者不關心具體產品是什麼的情況)。
可以一定程度增加程式碼的封裝性、可讀性。清楚的程式碼結構,對於消費者來說很少的程式碼量就可以完成很多工作。
等等。//TODO
另外,抽象工廠才是實際意義的工廠模式,工廠方法只是抽象工廠的一個比較常見的情況。
3.適用場景
消費者不關心它所要建立物件的類(產品類)的時候。
消費者知道它所要建立物件的類(產品類),但不關心如何建立的時候。
等等。//TODO
例如:hibernate裡通過sessionFactory建立session、通過代理方式生成ws客戶端時,通過工廠構建報文中格式化資料的物件。
4.模式要素
提供一個產品類的介面。產品類均要實現這個介面(也可以是abstract類,即抽象產品)。
提供一個工廠類的介面。工廠類均要實現這個介面(即抽象工廠)。
由工廠實現類建立產品類的例項。工廠實現類應有一個方法,用來例項化產品類。
5.類圖
6.模式例項程式碼
工廠:
package com.demoFound.factoryMethod.factory; import com.demoFound.factoryMethod.message.IMyMessage; /** * 工廠方法模式_工廠介面 * * @author popkidorc * */ public interface IMyMessageFactory { public IMyMessage createMessage(String messageType); }
package com.demoFound.factoryMethod.factory;
import java.util.HashMap;
import java.util.Map;
import com.demoFound.factoryMethod.message.IMyMessage;
import com.demoFound.factoryMethod.message.MyMessageEmail;
import com.demoFound.factoryMethod.message.MyMessageOaTodo;
import com.demoFound.factoryMethod.message.MyMessageSms;
/**
* 工廠方法模式_工廠實現
*
* @author popkidorc
*
*/
public class MyMessageFactory implements IMyMessageFactory {
@Override
public IMyMessage createMessage(String messageType) {
// 這裡的方式是:消費者知道自己想要什麼產品;若生產何種產品完全由工廠決定,則這裡不應該傳入控制生產的引數。
IMyMessage myMessage;
Map<String, Object> messageParam = new HashMap<String, Object>();
// 根據某些條件去選擇究竟建立哪一個具體的實現物件,條件可以傳入的,也可以從其它途徑獲取。
// sms
if ("SMS".equals(messageType)) {
myMessage = new MyMessageSms();
messageParam.put("PHONENUM", "123456789");
} else
// OA待辦
if ("OA".equals(messageType)) {
myMessage = new MyMessageOaTodo();
messageParam.put("OAUSERNAME", "testUser");
} else
// email
if ("EMAIL".equals(messageType)) {
myMessage = new MyMessageEmail();
messageParam.put("EMAIL", " [email protected]");
} else
// 預設生產email這個產品
{
myMessage = new MyMessageEmail();
messageParam.put("EMAIL", "[email protected]");
}
myMessage.setMessageParam(messageParam);
return myMessage;
}
}
產品:
package com.demoFound.factoryMethod.message;
import java.util.Map;
/**
* 工廠方法模式_產品介面
*
* @author popkidorc
*
*/
public interface IMyMessage {
public Map<String, Object> getMessageParam();
public void setMessageParam(Map<String, Object> messageParam);
public void sendMesage() throws Exception;// 傳送通知/訊息
}
package com.demoFound.factoryMethod.message;
import java.util.Map;
/**
* 工廠方法模式_虛擬產品類
*
* @author popkidorc
*
*/
public abstract class MyAbstractMessage implements IMyMessage {
private Map<String, Object> messageParam;// 這裡可以理解為生產產品所需要的原材料庫。最好是個自定義的物件,這裡為了不引起誤解使用Map。
@Override
public Map<String, Object> getMessageParam() {
return messageParam;
}
@Override
public void setMessageParam(Map<String, Object> messageParam) {
this.messageParam = messageParam;
}
}
package com.demoFound.factoryMethod.message;
/**
* 工廠方法模式_email產品
*
* @author popkidorc
*
*/
public class MyMessageEmail extends MyAbstractMessage {
@Override
public void sendMesage() throws Exception {
// TODO Auto-generated method stub
if (null == getMessageParam() || null == getMessageParam().get("EMAIL")
|| "".equals(getMessageParam().get("EMAIL"))) {
throw new Exception("傳送簡訊,需要傳入EMAIL引數");// 為了簡單起見異常也不自定義了
}// 另外郵件內容,以及其他各種協議引數等等都要處理
System.out.println("我是郵件,傳送通知給" + getMessageParam().get("EMAIL"));
}
}
package com.demoFound.factoryMethod.message;
/**
* 工廠方法模式_oa待辦產品
*
* @author popkidorc
*
*/
public class MyMessageOaTodo extends MyAbstractMessage {
@Override
public void sendMesage() throws Exception {
// TODO Auto-generated method stub
if (null == getMessageParam()
|| null == getMessageParam().get("OAUSERNAME")
|| "".equals(getMessageParam().get("OAUSERNAME"))) {
throw new Exception("傳送OA待辦,需要傳入OAUSERNAME引數");// 為了簡單起見異常也不自定義了
}// 這裡的引數需求就比較多了不一一處理了
System.out
.println("我是OA待辦,傳送通知給" + getMessageParam().get("OAUSERNAME"));
}
}
package com.demoFound.factoryMethod.message;
/**
* 工廠方法模式_sms產品
*
* @author popkidorc
*
*/
public class MyMessageSms extends MyAbstractMessage {
@Override
public void sendMesage() throws Exception {
// TODO Auto-generated method stub
if (null == getMessageParam()
|| null == getMessageParam().get("PHONENUM")
|| "".equals(getMessageParam().get("PHONENUM"))) {
throw new Exception("傳送簡訊,需要傳入PHONENUM引數");// 為了簡單起見異常也不自定義了
}// 另外簡訊資訊,以及其他各種協議引數等等都要處理
System.out.println("我是簡訊,傳送通知給" + getMessageParam().get("PHONENUM"));
}
}
消費者:
package com.demoFound.factoryMethod;
import com.demoFound.factoryMethod.factory.IMyMessageFactory;
import com.demoFound.factoryMethod.factory.MyMessageFactory;
import com.demoFound.factoryMethod.message.IMyMessage;
/**
* 工廠方法模式_消費者類
*
* @author popkidorc
*
*/
public class MyFactoryMethodMain {
public static void main(String[] args) {
IMyMessageFactory myMessageFactory = new MyMessageFactory();
IMyMessage myMessage;
// 對於這個消費者來說,不用知道如何生產message這個產品,耦合度降低
try {
// 先來一個簡訊通知
myMessage = myMessageFactory.createMessage("SMS");
myMessage.sendMesage();
// 來一個oa待辦
myMessage = myMessageFactory.createMessage("OA");
myMessage.sendMesage();
// 來一個郵件通知
myMessage = myMessageFactory.createMessage("EMAIL");
myMessage.sendMesage();
} catch (Exception e) {
e.printStackTrace();
}
}
}
點選進入ooppookid的部落格
相關推薦
Java技術_每天掌握一種設計模式(002)_使用場景及簡單例項(建立型:單例模式)
1.模式描述 一個類有且僅有一個例項,並且自行例項化並向整個系統提供。 2.模式作用 保證某個類在系統中只有一個例項物件,對於特殊需求來說非常必要。 限制了例項個數有利於GC的回收。
Java技術_每天掌握一種設計模式(006)_使用場景及簡單例項(建立型:原型模式)
1.模式描述 用原型例項指定建立物件的種類,並且通過拷貝來建立新的物件。 2.模式作用 可以一定程度上解耦,消費者和物件的構造過程隔離開,物件如何構造與消費者完全無關。 可以一定程度提升效率,複雜物件的構造往往需要較長的時間(中間可能會進行復雜運算或者資料庫
Java技術_每天掌握一種設計模式(003)_使用場景及簡單例項(建立型:工廠方法)
1.模式描述 提供一個用於建立物件的介面(工廠介面),讓其實現類(工廠實現類)決定例項化哪一個類(產品類),並且由該實現類建立對應類的例項。 2.模式作用 可以一定程度上解耦,消費者和
php 十一種設計模式
&nbs
SOA只不過是一種設計模式而已
文章中以麥當勞的服務系統舉例,稱之為“以人力為基礎的面向服務的架構(a human-based SOA)”,非常有意思。大家都知道在國外,你可以駕著車享受麥當勞的服務。不用離開車,首先你開到一個卡通人前對對講機說出你要幾號套餐,然後向前開到下一個視窗付款並拿你的食物。這個簡單的系統基本上包含了兩個服務:接受訂
為什麼MVC不是一種設計模式? ---比較Backbone和Ext4.x在MVC實現上的差異
為什麼MVC不是一種設計模式? ---比較Backbone和Ext4.x在MVC實現上的差異 轉載:http://damoqiongqiu.iteye.com/blog/1949256 大漠窮秋 前言 聖人云:不想做媽咪的小姐不是好碼農。 每一個碼
Java設計模式(創建型:工廠方法模式)
out nbsp 操作 短信發送 ora print temp ati ural (該文內容為原創,有不足之處望多多指教!) 設計模式根據目的準則可以分為三類: 創建型:creational 創建型的設計模式與對象的創建有關。 結構型:Structural 處理類和
《UML面向物件建模與設計》第2章——建模是一種設計技術
雖然寫這個部落格主要目的是為了給我自己做一個思路記憶錄,但是如果你恰好點了進來,那麼先對你說一聲歡迎。我並不是什麼大觸,只是一個菜菜的學生,如果您發現了什麼錯誤或者您對於某些地方有更好的意見,非常歡迎您的斧正! 2.1建模 ·在構建物理實體之前先測試 ·與客戶交流 ·
Java經典23種設計模式之行為型模式(一)
行為型設計模式有11種,分別是Chain of Responsibility ( 責任鏈模式 )、Command ( 命令模式 )、Interpreter ( 直譯器模式 ) 、Iterator ( 迭代器模式 )、Mediator ( 中介者模式 ) 、Memento (
JAVA的23種設計模式---代理模式(一)
概要: 該文章參考了《設計模式之禪》一書及一些前輩的部落格文章 1.該文章闡述了代理模式的基礎原理及示例程式碼; 2.該文章適合初學設計模式的技術人員研習; 3.該文章有許多不足之處,請各位大咖
Java中的24種設計模式與7大原則
工廠模式 職責 需要 占位符 ati gre template 層次 cto 一、創建型模式 1、抽象工廠模式(Abstract factory pattern): 提供一個接口, 用於創建相關或依賴對象的家族, 而不需要指定具體類.2、生成器模式(Builder pat
23種設計模式介紹(一)---- 創建型模式
接口 ret static 深復制 return 對象 相互 object c png 由於設計模式篇幅比較大,如果在一篇文章講完所有的設計模式的話不利於閱讀。於是我把它分為三篇文章 23種設計模式介紹(一)---- 創建型模式 23種設計模式介紹(二)---- 結構型模
java 23種設計模式
代理 建造者 學習 article 適配器 htm ava arc 叠代 備註這是別人總結的本來想轉載可惜不會怎麽轉載(感謝) 以下是學習過程中查詢的資料,別人總結的資料,比較容易理解(站在各位巨人的肩膀上,望博主勿究) 創建型抽象工廠模式 http://www.cnblo
java常見的幾種設計模式
設計模式 單例 餓漢式 懶漢式 設計模式 1、概述 1)設計模式(Design pattern):是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結; 2)分類: 創建型模式(創建對象的): 單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。 行為型模式(對象
Java開發23種設計模式
熱插拔 開發 每一個 設計模式 為什麽 之間 des 單位 行為型 設計模式(Design Patterns) -- -- -- 可復用面向對象軟件的基礎 設計模式(Design Patterns)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的
【python+selenium搭建自動化框架】框架設計中的一種設計思想--POM
例如 了解 思想 對象 業務 class a 如果 對象模型 模型 POM,中文:頁面對象模型,POM是近幾年非常流行的自動化測試模型,或者思想,POM不是框架,是解決問題的一種思想。 采用POM目的:為了解決前端中UI變化頻繁,從而造成測試自動化腳本維護的成本越來越大 P
java 常用十種設計模式示例歸納 | 已打包請帶走
java 設計模式 程序員 程序人生 互聯網 設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。 GitHub地址DesignPattern 文章說明一個Demo,集合常用的十種設計模式,每個模式使用易被人們接受的案例講述,按模式分
JAVA開發的23種設計模式之 --- 橋接模式
橋接模式 概述:將抽象部分與他的實現部分分離,這樣抽象化與實現化解耦,使他們可以獨立的變化.如何實現解耦的呢,就是通過提供抽象化和實現化之間的橋接結構. 應用場景 &n
Java中23種設計模式(附代碼樣例)
體會 如何解決 熱插拔 原型 原型模式 strac println template sendmai 一、設計模式分類總體來說設計模式分為三大類:創建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。結構型模式,共七種:適配器模式、裝飾器模式、代理
java的23種設計模式之裝飾者模式
這裡給大家推薦一篇文章裡面介紹了23種設計模式https://www.aliyun.com/jiaocheng/811770.html; 下面則是我學習裝飾者的見解: 關於裝飾者模式運用的地方其實有很多,我第一次接觸到就是io流中,比如像這樣的: new InputStreamRea