Java程式員的日常 —— 註冊工廠的妙用

来源:http://www.cnblogs.com/xing901022/archive/2016/06/14/5585532.html
-Advertisement-
Play Games

註冊工廠是一種很常用的框架書寫方法,它適合於快速創建相同類型的對象。 舉個慄子 比如一個傢具工廠,有沙發、椅子、茶几等等,正常的編程模式是這樣的: 如果想要擴展,就需要繼續定義class,然後new對象。 但是其實沙發的製作與使用時解耦的,使用者並不需要知道沙發、茶几是怎麼製作出來的,只是想使用它而 ...


註冊工廠是一種很常用的框架書寫方法,它適合於快速創建相同類型的對象。

舉個慄子

比如一個傢具工廠,有沙發、椅子、茶几等等,正常的編程模式是這樣的:

//創建
class 沙發{}
class 椅子{}
class 茶几{}

//使用
new 沙發();
new 椅子();
new 椅子();
new 茶几();

如果想要擴展,就需要繼續定義class,然後new對象。

但是其實沙發的製作與使用時解耦的,使用者並不需要知道沙發、茶几是怎麼製作出來的,只是想使用它而已。

使用註冊工廠,相當於沙發、茶几、椅子都統一了一套創建方法,用戶只需要去使用就行了。

參考下麵的偽碼:

//定義創建工廠
interface Factory<T>{ 
    T create();
}

//對象繼承這個工廠
class 沙發 extends 傢具{
    public static class Factory implements a.b.c.Factory<沙發>{
    public 沙發 create(){ return new 沙發()}
    }
}
class 茶几 extends 傢具{
    public static class Factory implements a.b.c.Factory<茶几>{
    public 茶几 create(){ return new 茶几()}
    }
}
class 椅子 extends 傢具{
    public static class Factory implements a.b.c.Factory<椅子>{
    public 椅子 create(){ return new 椅子()}
    }
}

//註冊到工廠Map中
Map<String,Factory<? extends 傢具>> map = new HashMap<>();
map.put("沙發",new 沙發.Factory());
map.put("椅子",new 椅子.Factory());
map.put("茶几",new 茶几.Factory());

//這樣在使用的時候,就可以直接用它創建對象了
map.get("沙發").create()

詳細代碼

Factory.class

package xing.test.thinking.chap14;

public interface Factory<T> {
    T create();
}

RegisteredFactories.class

package xing.test.thinking.chap14;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

class Part {
    public String toString(){
        return getClass().getSimpleName();
    }
    static List<Factory<? extends Part>> partFactories = new ArrayList<Factory<? extends Part>>();//存放所有的對象工廠
    //在靜態塊中添加對象工廠
    static{
        partFactories.add(new FuelFilter.Factory());
        partFactories.add(new AirFilter.Factory());
        partFactories.add(new CabinAirFilter.Factory());
        partFactories.add(new OilFilter.Factory());
        partFactories.add(new FanBelt.Factory());
        partFactories.add(new PowerSteeringBelt.Factory());
        partFactories.add(new GeneratorBelt.Factory());
    }
    private static Random rand = new Random(47);
    public static Part createRandom(){
        int n = rand.nextInt(partFactories.size());
        return partFactories.get(n).create();
    }
}
class Filter extends Part{}
class FuelFilter extends Filter {
    public static class Factory implements xing.test.thinking.chap14.Factory<FuelFilter> {
        public FuelFilter create(){
            return new FuelFilter();
        }
    }
}
class AirFilter extends Filter {
    public static class Factory implements xing.test.thinking.chap14.Factory<AirFilter> {
        public AirFilter create(){
            return new AirFilter();
        }
    }
}
class CabinAirFilter extends Filter {
    public static class Factory implements xing.test.thinking.chap14.Factory<CabinAirFilter> {
        public CabinAirFilter create(){
            return new CabinAirFilter();
        }
    }
}
class OilFilter extends Filter {
    public static class Factory implements xing.test.thinking.chap14.Factory<OilFilter> {
        public OilFilter create(){
            return new OilFilter();
        }
    }
}
class Belt extends Part{};
class FanBelt extends Belt {
    public static class Factory implements xing.test.thinking.chap14.Factory<FanBelt> {
        public FanBelt create(){
            return new FanBelt();
        }
    }
}
class GeneratorBelt extends Belt {
    public static class Factory implements xing.test.thinking.chap14.Factory<GeneratorBelt> {
        public GeneratorBelt create(){
            return new GeneratorBelt();
        }
    }
}
class PowerSteeringBelt extends Belt {
    public static class Factory implements xing.test.thinking.chap14.Factory<PowerSteeringBelt> {
        public PowerSteeringBelt create(){
            return new PowerSteeringBelt();
        }
    }
}
public class RegisteredFactories {
    public static void main(String[] args) {
        for(int i=0 ; i<10 ; i++){
            System.out.println(Part.createRandom());
        }
    }
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我之前想寫路由器的密碼暴力破解器,我手上只有極路由,發現極路由有安全限制,只能允許連續10次密碼錯誤,所以我改拿博客園練手。 博客園的博客有個功能是給博文設置一個密碼,輸入正確的密碼才能看到文章的內容。經過測試發現這個密碼驗證功能,既沒有驗證碼也沒有提交頻率的限制, 要寫這個針對博客園的密碼暴力破解 ...
  • 本文適用於所有鍵盤類職業,比如程式員,比如作家,比如編輯,比如水軍,等等... 程式員買得起鍵盤嗎?買得起。 程式員買得起好的機械鍵盤嗎?也買得起。 不過大部分of他們是不會很快決定買的,包括我。因為打從一開始接觸電腦,不管是家裡還是學校甚至網吧,我們用的鍵盤也就是隨便玩玩的,並不會多在意,而等到自 ...
  • 1. download cas 4.2.2 from https://github.com/apereo/cas/releases 2. eclipse import cas 4.2.2 eclipse install SpringSource Update Site for Gradle Inte ...
  • 前段時間因為寫一個業務,對mysql的插入量非常大,在idea開發環境,使得idea一直爆出outofmemry提示,並導致old 區一直漲。使用Mongodb 作為存儲後,不僅插入速度大大提升,idea會卡死的頑疾也解決了。 Mongodb 能夠非常簡單的整合進項目 下麵是我的整合過程 ...
  • 單例模式 概念相關 單例模式 在程式運行過程,一個類只有一個實例 使用場合 在整個應用程式中,共用一份資源(這份資源只需要創建初始化1次) static static關鍵字會在聲明變數的時候分配記憶體,在程式運行期間只分配一次記憶體。之後再訪問時,實際都是在訪問原先分配的記憶體 如果使用static來修飾 ...
  • 對話框不能單獨存在,依賴於窗體,有顯示標題,有模式 獲取Dialog對象,new出來,構造參數:Frame對象,String的標題,模式 窗體內部的內容,Label對象,Button對象,調用Dialog對象的add()方法,把這兩個添加進去 Dialog也是一個普通的窗體,需要設置尺寸和位置 這個 ...
  • 現如今,智能手機是人手一份。每天我們都通過手機與外界溝通交流,手機作為必不可少的媒介,無形中記錄著我們日常生活中的點點滴滴。這些信息主要包括個人位置信息、通信信息、賬號密碼信息、存儲文件信息等四大類。由於Android是開源的,軟體用戶可自行對軟體進行修改、複製及再分發,直接進行信息交換。有些用戶還... ...
  • 本次講述項目背景: 創建Service類,Service下用到dao類。通過在Spring中配置bean,實現在項目啟動時,自動載入這個類 本次只講述配置bean的註意事項,故只給出簡單實例: 創建Service: 在applicationContext.xml下配置bean: 當配置結束後,系統一 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...