設計模式之工廠模式、建造者模式
準備找工作那會看到了一本神書,《Head First 設計模式》,從此對設計模式有了很深的親睞,但是因為自己的專案經驗少的可憐,所以也基本沒有用過這些神一樣的方法,時間一長也就都忘乾淨了。現在工作了,師兄給了一個500M的程式碼,讓我吃透它。這期間真的有很多問題,很迷惑。忽然想起了我之前看的書,於是重新拿出來溫習。
如果說設計模式是聖經,那麼這本書就是小人漫畫版的啟蒙聖經。入門看真的很好,但因為工作需要沒有這麼多時間,快餐式的是最合適的。於是在網上看到了一個網址,介紹23種設計模式很是靠譜。http://zz563143188.iteye.com/blog/1847029 這是這位大牛的網址。
以前看書的時候,感覺工廠模式種類繁多,根本就分不清楚,但是看了他的部落格之後,有種撥雲見月的感覺。於是乎就自己寫下了這幾個工廠模式的例子來練習,實現例項沒有自己設計是參照網上的。
寫完之後就感覺自己分清並掌握了這幾個模式,下面就總結一下。
工廠模式是三類設計模式中的建立式模式,工廠模式分為三種,簡單工廠方法,複雜工廠,還有抽象工廠
下面先看一下他們的實現
一,簡單工廠模式
首先定義一個Isend介面
public interface Isend {
public void sendMessage();
}
然後new幾個sender,實現Isend介面public class MailSender implements Isend { public void sendMessage() { // TODO Auto-generated method stub System.out.println("Use MailSender send the message!"); } }
public class PhoneSender implements Isend{
public void sendMessage() {
// TODO Auto-generated method stub
System.out.println("Use PhoneSender send the message!");
}
}
然後就是做一個工廠,讓工廠來生產這幾個sender
其中紅色部分,就是暴露出了簡單工廠的缺點,就是當type的型別和系統定義的步一樣時,有可能是輸入錯誤等,返回的就是一個空型別了,這是簡單工廠的天生缺點public class SenderFactory { public Isend productSender(String type) { if("Mail".equals(type)) { return new MailSender(); }else if("Phone".equals(type)) { return new PhoneSender(); }else <span style="color:#ff0000;">return new NullSender();</span> } }
看一下測試
public class Test {
public static void main(String[] args) {
SenderFactory factory = new SenderFactory();
Isend mailSender = factory.productSender("Mail");
mailSender.sendMessage();
Isend phoneSender = factory.productSender("Phone");
phoneSender.sendMessage();
Isend errorySender = factory.productSender("123");
errorySender.sendMessage();
}
}
測試結果:
Use MailSender send the message!
Use PhoneSender send the message!
No SenderFactory product sender!
因為這個工廠相當於單個生產線,所以每種產品都會從這條生產線中產出,所以如果輸入是本來生產線中沒有的,那麼就只能報錯了。根據這種情況,於是就想可以再多出幾條生產線啊。就是下面的複雜工廠該出場了。
二、複雜工廠:
其他的都一樣,就是在工廠中多加幾條生產線,所以直接看SenderFactory類就可以了
package com.designpattern.complexfactory.factory;
import com.designpattern.complexfactory.isend.Isend;
import com.designpattern.complexfactory.sender.MailSender;
import com.designpattern.complexfactory.sender.PhoneSender;
public class SenderFactory {
public Isend productMailSender() {
return new MailSender();
}
public Isend productPhoneSender() {
return new PhoneSender();
}
}
在這裡,我做了兩條生產線,每條生產線只負責生產一種產品,所以,這樣就沒有輸入錯誤的情況了,看看測試
public class Test {
public static void main(String[] args) {
SenderFactory factory = new SenderFactory();
Isend mailSender = factory.productMailSender();
mailSender.sendMessage();
Isend phoneSender = factory.productPhoneSender();
phoneSender.sendMessage();
}
}
解決了?好像發現了兩個問題。
1,工廠方法裡不需要建立例項,直接呼叫就行,那好辦就把它設定為靜態工廠,就實現了不需要例項化,直接建立。
public class SenderFactory {
public <span style="color:#ff0000;">static</span> Isend productMailSender() {
return new MailSender();
}
public <span style="color:#ff0000;">static</span> Isend productPhoneSender() {
return new PhoneSender();
}
}
下面看一下測試
public static void main(String[] args) {
Isend mailSender = SenderFactory.productMailSender();
mailSender.sendMessage();
Isend phoneSender = SenderFactory.productPhoneSender();
phoneSender.sendMessage();
}
2,設計模式崇尚的是對擴充套件開放,對修改關閉。當有新的需求有新的產品設計出來需要生產的時候,那麼就只能更改SenderFactory這個類了,那麼不就是違背這個設計原則了嗎。可以設想,把工廠也做成多個,當有新的產品時,就建一座工廠,這樣原來的工廠就不需要更改了,就實現了工廠之間的鬆耦合。
於是抽象工廠就這麼產生了
抽象工廠:
抽象工廠就是把處理工廠的方法和處理生產線的方法一樣
首先看一下IFactory介面
public interface IFactory {
public Isend productSender();
}
所有的工廠都實現此介面,也就意味著所有的工廠都可以生產產品,看一下這幾個工廠
public class MailSender implements Isend{
public void SendMessage() {
// TODO Auto-generated method stub
System.out.println("Use MailSender send the message!");
}
}
public class PhoneSender implements Isend {
public void SendMessage() {
// TODO Auto-generated method stub
System.out.println("Use PhoneSender send the message!");
}
}
這裡我又新建了一個qq工廠,來發送qq訊息
public class QQSender implements Isend {
public void SendMessage() {
// TODO Auto-generated method stub
System.out.println("User QQSender send the message!");
}
}
工廠看完了,看一下訊息傳送器
public class MailSender implements Isend{
public void SendMessage() {
// TODO Auto-generated method stub
System.out.println("Use MailSender send the message!");
}
}
public class PhoneSender implements Isend {
public void SendMessage() {
// TODO Auto-generated method stub
System.out.println("Use PhoneSender send the message!");
}
}
public class QQSender implements Isend {
public void SendMessage() {
// TODO Auto-generated method stub
System.out.println("User QQSender send the message!");
}
}
每一種傳送器都是由不同的工廠生產出來的,當然也可以一個工廠生產多種產品,你可以試著改一下,當練手。
下面看一下測試
public class Test {
public static void main(String[] args) {
IFactory mailFactory = new MailSenderFactory();
Isend mailSend = mailFactory.productSender();
mailSend.SendMessage();
IFactory phoneFactory = new PhoneSenderFactory();
Isend phoneSend = phoneFactory.productSender();
phoneSend.SendMessage();
IFactory qqFactory = new QQSenderFactory();
Isend qqSend = qqFactory.productSender();
qqSend.SendMessage();
}
}
在這個例子中,新加的qq傳送器是由qq工廠new出來的,不影響Mail 和 Phone工廠,實現了對擴充套件開放,對修改關閉的原則。
至此工廠模式就算是總結完了,還留了一個小題,就是在抽象工廠中,讓一個工廠生產多個產品。
這裡有一個坑,也同時給我自己挖了一個,下面晒一下我的答案:
首先我新建了一個WeiSender,想讓QQSenderFactory也同時能生產WeiSender
public class WeiSender implements Isend {
public void SendMessage() {
// TODO Auto-generated method stub
System.out.println("Use WeiSender send the message!");
}
}
把QQSenderFactory類做了一下調整
public class QQSenderFactory implements IFactory{
public Isend productSender() {
// TODO Auto-generated method stub
return new QQSender();
}
<span style="color:#ff0000;">public Isend productWeiSender() {
return new WeiSender();
}</span>
}
其中紅色部分是我加的方法
於是在測試的時候,我就想直接用
IFactory qqFactory = new QQSenderFactory();
生產出來的qqFactory來執行productWeiSender()方法,但是發現是錯誤的,這裡就是個坑,回頭看qqFactory是怎麼來的,是由IFactory來的,那麼就只能執行IFactory介面中帶有的方法啦。
所以如果還想執行其他的方法,那就得:
<span style="color:#ff0000;">QQSenderFactory qqf = new QQSenderFactory();</span>
Isend qqs = qqf.productWeiSender();
qqs.SendMessage();
使用這種方法來new一個qqFactory就可以執行QQSenderFactory中的所喲方法了。
看一下測試
Use MailSender send the message!
Use PhoneSender send the message!
User QQSender send the message!
Use WeiSender send the message!
建造者模式
看完了工廠模式,是不是覺得意猶未盡,還差點啥?
對了,工廠模式建立的是單個類的模式,工廠可是可以根據訂貨單來大批量生產的。
於是建造者模式就誕生了。
下面看一下他的程式碼,相信一看程式碼就很明確了
public interface ISend {
public void Send() ;
}
public class MailSender implements ISend {
public void Send() {
// TODO Auto-generated method stub
System.out.println("Use MailSender send the message!");
}
}
public interface IFactory {
public List<ISend> productSender(int count) ;
}
public class MailSenderFactory implements IFactory {
private List<ISend> list ;
public MailSenderFactory() {
list = new ArrayList();
}
public List<ISend> productSender(int count) {
for(int i = 0; i < count; i++) {
list.add(new MailSender());
}
return list;
}
}
public class Test {
public static void main(String[] args) {
MailSenderFactory mailFactory = new MailSenderFactory();
List list = mailFactory.productSender(3);
for(int i = 0; i < list.size(); i++) {
ISend sender = (ISend) list.get(i);
sender.Send();
}
}
}
不用多說了吧,我想應該一看就能明白
建造者模式是可以創造出很多複雜的東西,所以以後在用的時候可以考慮清楚,那種模式更適合
相關推薦
JAVA設計模式之簡單粗暴學建造者模式
.get 建造者模式 mybatis源碼 conf 模式 lan 分析 過程 程序 文章由淺入深,先用簡單例子說明建造者,然後分析模式的優缺點,最後結合優秀開源框架Mybatis,說明該模式的用處。 1、先定義一個機器人模型 package com.jstao.mo
設計模式之工廠模式、建造者模式
準備找工作那會看到了一本神書,《Head First 設計模式》,從此對設計模式有了很深的親睞,但是因為自己的專案經驗少的可憐,所以也基本沒有用過這些神一樣的方法,時間一長也就都忘乾淨了。現在工作了,師兄給了一個500M的程式碼,讓我吃透它。這期間真的有很多問題,很迷惑。忽
用最簡單的例子說明設計模式(三)之責任鏈、建造者、適配器、代理模式、享元模式
def dap CA 抽象 創建 tcl cte clas eth 責任鏈模式 一個請求有多個對象來處理,這些對象是一條鏈,但具體由哪個對象來處理,根據條件判斷來確定,如果不能處理會傳遞給該鏈中的下一個對象,直到有對象處理它為止 使用場景 1)有多個對象可以處理同
設計模式學習總結(2)單例模式、建造者模式、原型模式
單例模式(Singleton Pattern) 這種模式涉及到一個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要例項化該類的物件。 單例模式有以下三點注意: 1、單例類只能有一個例項。 2、單
對 橋接模式 的個人理解,以及與 工廠方法模式、建造者模式 的結合運用
學習了一段時間設計模式,就想分享一下自己的理解, 歡迎大家多多指點,指出不足之處哈 橋接模式:以商店與手機為例子來描述,先從簡單的依賴關係說起 public interface Phone { /** 充電 **/ void charge(); /** 解鎖 *
設計模式總結之Builder Pattern(建造者模式)
目錄 建立型設計模式: 結構型設計模式: 行為型設計模式: Builder Pattern(建造者模式) 意圖 將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。適用性 * 當建立複雜物件的演算法應該獨立於該物件的組成部分以及它們的裝配方式時。
java23種設計模式——五、建造者模式
原始碼在我的[github](https://github.com/witmy/JavaDesignPattern)和[gitee](https://gitee.com/witmy/JavaDesignPattern)中獲取 # 目錄 [java23種設計模式—— 一、設計模式介紹](https://www.
設計模式 #3 (原型模式、建造者模式)
# 設計模式 #3 (原型模式、建造者模式) --- **文章中所有工程程式碼和`UML`建模檔案都在我的這個`GitHub`的公開庫--->[DesignPattern](https://github.com/L1ng14/DesignPattern)。**`Star`來一個好嗎?秋梨膏! ---
設計模式解密(6) - 建造者模式
簡單的 對比 ide nbsp blog art 是把 部分 shp 1、簡介 定義:將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。 英文:Builder 類型:創建類模式 2、原理及組成 引:類圖 四個要素 產品類:
設計模式:學習筆記(4)——建造者模式
receiver temp pla his AI 技術 bubuko 電子 中一 設計模式:學習筆記(4)——建造者模式 概述 建造者模式 建造者模式是較為復雜的創建型模式,它將客戶端與包含多個組成部分(或部件)的復雜對象的創建過程分離,客戶端無須知道復雜對象的內部組成
23種設計模式(4):建造者模式
out 比較 組件 rec this 建造者 交互 變化 整體 定義:將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。 類型:創建類模式。 類圖: 四個要素: 1,產品類:一般是一個較為復雜的對象,也就是說創建對象的過程比較復雜,一般會有比
Java中的設計模式(八):建造者模式
伸縮 null clas 示例代碼 最簡 裝配 角色扮演 app 但是 介紹 今天我們將研究java中的Builder模式。Builder 設計模式是一種創造性的設計模式,如工廠模式和抽象工廠模式。 當Object包含許多屬性時,引入了Builder模式來解決Factory
設計模式總結篇系列:建造者模式(Builder)
關於建造者模式網上有很多文章,也有些不同的理解。在此結合網上其他文章對建造者模式進行總結。 總體說來,建造者模式適合於一個具有較多的零件(屬性)的產品(物件)的建立過程。根據產品建立過程中零件的構造是否具有一致的先後順序,可以將其分為如下兩種形式。 一、通過Client、Director、Builder和
Java 設計模式(六):建造者模式
參考連結:建造者模式-Builder Pattern 1. 模式概述 定義:將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。 建造者模式是較為複雜的建立型模式,它將客戶端與包含多個組成部分(或部件)的複雜物件的建立過程分離,客戶端無須知道複雜物件的內
設計模式(十一)建造者模式
用程式畫一個小人,這在遊戲程式裡非常常見。現在簡單一點,要求是小人要有頭、身體、兩手、兩腳就可以了。 第一版 Pen p = new Pen (Color.Yellow); Graphics gThin = pictureBox1.CreateGraphics();
Java中設計模式(八):建造者模式
介紹 今天我們將研究java中的Builder模式。Builder 設計模式是一種創造性的設計模式,如工廠模式和抽象工廠模式。 當Object包含許多屬性時,引入了Builder模式來解決Factory和Abstract Factory設計模式的一些問題。 當Object包含許多屬性時,Factory和Abs
設計模式學習筆記4:建造者模式
定義 將一個複雜的物件與它的表示分離,使得同樣的構建過程可以建立不同的表示。 使用者只需要指定需要建造的型別就可以得到它們,建造過程及細節不需要知道。 【就是如何一步步構建一個包含多個元件的物件,相同的構建過程可以建立不同的產品,比較適用於流程固定但是順序不一定固定】 型別 建立型 使用場
設計模式之(三)——裝飾者模式(Decorator Pattern)
裝飾者模式:動態將責任附加到物件上,要拓展功能,提供了比繼承更有彈性的方案。 很多文章也是拿了書上的例子來講,同時寫到,有的調料裝飾者都必須實現 getDescription() 大家可以先考慮下,稍後我們會說。最後都是沒說,還有思考的
JAVA設計模式(4):建造者模式
構建器(Builder)模式使用簡單物件並使用逐步方法構建複雜物件。 這種型別的設計模式屬於建立模式,因為此模式提供了建立物件的最佳方法之一。構建器(Builder)模式構建器逐步構建最終物件,此構建器獨立於其他物件。 實用例項 我們考慮了一家快餐店的商業案例,其中典型的餐點可能是漢堡和冷飲
建立類設計模式(5種)——建造者模式
建立類設計模式(5種)——建造者模式 一、快餐點餐系統 今天的例子,還是上一次談到的快餐點餐系統。只不過,今天我們從訂單的角度來構造這個系統。 最先還是有請上次的主角們: class Burger(): name="" price=0.0 def getPrice