以Java代碼為例講解設(shè)計模式中的簡單工廠模式
1. 簡單工廠模式簡介
簡單工廠模式(Simple Factory),又被稱為"靜態(tài)工廠方法模式"。它屬于"創(chuàng)建模式"(創(chuàng)建對象的模式),并且是"工廠方法"模式的一種特殊實現(xiàn)。
通常,我們利用簡單工廠模式來進(jìn)行類的創(chuàng)建。例如,獲取線程池對象,就是通過簡單工廠模式來實現(xiàn)的。它的結(jié)構(gòu)圖如下所示:
工廠:工廠是簡單工廠模式的核心,提供了對外接口。客戶端或其它程序要獲取Product對象,都是通過Factory的接口來獲取的。
抽象產(chǎn)品:抽象產(chǎn)品是(許多)不同產(chǎn)品抽象出來的。Product可以是接口或者抽象類。
具體產(chǎn)品:工廠中返回的產(chǎn)品對象,實際上是通過ConcreteProduct來創(chuàng)建的。
2. 簡單工廠模式代碼模型
public class Factory { public static Product newInstance() { return new ConcreteProduct(); } } public abstract Product { } public class ConcreteProduct extends Product { public ConcreteProduct() {} }
模型的類圖
3.簡單工廠模式的實際應(yīng)用
我們在寫一個Servlet處理客戶端請求的時候, 往往會一個Servlet處理多個業(yè)務(wù)邏輯, 比如:
protected void doPost(HttpServletRequest request, HttpServletResponse response) { String flag = request.getParameter("flag"); if(flag.equals("service1")) { service1(); }else if(flag.equals("service2")) { service2(); } ... }
以上是我們的Servlet處理多業(yè)務(wù)邏輯的常規(guī)方法, 寫一坨if else語句。一種比較好的辦法就是, 將請求的分發(fā)與Servlet分離, 讓Servlet只處理業(yè)務(wù)邏輯。我們把各種請求的Servlet看做產(chǎn)品類, javax.servlet.HttpServlet是產(chǎn)品父類, javax.servlet.Servlet是產(chǎn)品接口, 這樣我們定義一個ServletFactory, 在過濾器里解析url請求并交給ServletFactory來處理就可以了。 這就是一個典型的簡單工廠應(yīng)用。
@WebFilter("/TransRequest") public class TransRequest implements Filter{ private String servletName; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest myRequest = (HttpServletRequest)request; //拿到請求的servlet名字, 這里我們約定請求都是/servletName形式 String names[] = myRequest.getRequestURI().trim().split("/"); servletName = names[2]; if( servletName != null) { //以下是最典型的兩句簡單工廠的例子 Servlet servlet = ServletFactory.createServlet(servletName); servlet.service(request, response); }else chain.doFilter(request, response); }
每次來一個請求我們用工廠生產(chǎn)一個servlet, 這樣可以免去在xml配置大量的servlet路徑信息比較方便。而且這樣也會使邏輯更加清晰, servlet僅僅就是在業(yè)務(wù)層處理業(yè)務(wù)。
工廠類如下:
public class ServletFactory { public static Servlet createServlet(String servletName) throws ServletException { if(servletName.equals("servletName1")) { return new Service1(); }else if(servletName.equals("servletName2")){ return new Service2(); }else{ throw new ServletException("No such servlet"); } } }
上面的工廠類雖然沒有拋開繁瑣的if else, 但是利用簡單工廠的思想仍然解決了一些問題。簡單工廠是非常簡單的一種算不上設(shè)計模式的設(shè)計模式, 解決的問題也很有限。 以上請求分發(fā)各大javaEE 框架都已實現(xiàn), 例如Struts2, 當(dāng)然框架不是用的簡單工廠。
4.總結(jié)
簡單工廠模式, 總結(jié)起來就是一個工廠類,一個產(chǎn)品接口(其實也可以是一個抽象類,甚至一個普通的父類)和一群實現(xiàn)了產(chǎn)品接口的具體產(chǎn)品,而這個工廠類,根據(jù)傳入的參數(shù)去創(chuàng)造一個具體的實現(xiàn)類,并向上轉(zhuǎn)型為接口作為結(jié)果返回。
相關(guān)文章
java中Map、Set、List的簡單使用教程(快速入門)
這篇文章主要給大家介紹了關(guān)于java中Map、Set、List簡單使用教程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01Mybatis-plus設(shè)置某個字段值為null的方法總結(jié)
mybatis-plus以下簡稱mp,目前應(yīng)該也算是主流的一款數(shù)據(jù)訪問層應(yīng)用框架,下面這篇文章主要給大家介紹了關(guān)于Mybatis-plus設(shè)置某個字段值為null的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07SpringMVC異步處理操作(Callable和DeferredResult)
這篇文章主要介紹了SpringMVC異步處理操作(Callable和DeferredResult),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01Java17中record替代Lombok部分功能使用場景探究
這篇文章主要介紹了使用Java17中的record替代Lombok的部分功能,本文來為大家小小的總結(jié)下,我們可以在哪些地方,利用record來替換Lombok2024-01-01Mybatis Plus整合PageHelper分頁的實現(xiàn)示例
這篇文章主要介紹了Mybatis Plus整合PageHelper分頁的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09在Action中以Struts2的方式輸出JSON數(shù)據(jù)的實例
下面小編就為大家?guī)硪黄贏ction中以Struts2的方式輸出JSON數(shù)據(jù)的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11Java分布式鎖、分布式ID和分布式事務(wù)的實現(xiàn)方案
在分布式系統(tǒng)中,分布式鎖、分布式ID和分布式事務(wù)是常用的組件,用于解決并發(fā)控制、唯一標(biāo)識和數(shù)據(jù)一致性的問題,本文將介紹Java中常用的分布式鎖、分布式ID和分布式事務(wù)的實現(xiàn)方案,并通過具體的示例代碼演示它們的用法和應(yīng)用場景2023-06-06Java入門基礎(chǔ)之Java的基本語法與Java所支持的數(shù)據(jù)類型
這篇文章主要介紹了Java入門基礎(chǔ)之Java的基本語法與Java所支持的數(shù)據(jù)類型,熟悉語法和數(shù)據(jù)類型通常是了解一種編程語言的開始,需要的朋友可以參考下2016-02-02