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