您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么使用java模板模式”,在日常操作中,相信很多人在怎么使用java模板模式問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么使用java模板模式”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
一、介紹
模板模式,顧名思義,定義一個模板,將部分邏輯以具體方法或者具體構(gòu)造函數(shù)的形式實現(xiàn),在抽象類中聲明一些抽象方法來迫使子類實現(xiàn)剩余的邏輯。
不同的子類可以以不同的方式實現(xiàn)這些抽象方法,從而對剩余的邏輯有不同的實現(xiàn),這就是模板方法模式的用意。
模板模式涉及到三個角色:
抽象類(AbstractClass):實現(xiàn)了模板方法,定義了算法的骨架;
具體類(ConcreteClass):實現(xiàn)抽象類中的抽象方法,已完成完整的算法;
客戶角色:客戶類提出使用具體類的請求;
二、示例
舉個例子,以早上起床到上班所需要的操作為例,大致流程可以分為以下幾步:穿衣服、刷牙、洗臉、吃早餐等。男生和女生的操作可能有些區(qū)別。
我們創(chuàng)建一個抽象的類,定義好大致的操作流程,如下:
/** * 抽象類 */ public abstract class AbstractPerson { /** * 定義操作流程 */ public void prepareGoWorking(){ dressing();//穿衣服 brushTeeth();//刷牙 washFace();//洗臉 eatBreakFast();//吃早餐 } /**穿衣服*/ protected abstract void dressing(); /**刷牙*/ protected void brushTeeth(){ System.out.println("刷牙"); } /**洗臉*/ protected void washFace(){ System.out.println("洗臉"); } /**吃早餐*/ protected abstract void eatBreakFast(); }
因為男生和女生的行為不一樣,我們分別創(chuàng)建兩個具體類,如下:
/** * 男生 * 具體實現(xiàn)類 */ public class ManPerson extends AbstractPerson{ @Override protected void dressing() { System.out.println("穿西裝"); } @Override protected void eatBreakFast() { System.out.println("直接在公司吃早餐"); } }
/** * 女生 * 具體實現(xiàn)類 */ public class WomanPerson extends AbstractPerson{ @Override protected void dressing() { System.out.println("穿休閑衣服"); } @Override protected void eatBreakFast() { System.out.println("在家弄點吃的,或者在外面買一點小吃"); } }
創(chuàng)建一個客戶端,實現(xiàn)如下:
public class TemplateClient { public static void main(String[] args) { //男生起床步驟 ManPerson manPerson = new ManPerson(); System.out.println("-----男生起床步驟----"); manPerson.prepareGoWorking(); System.out.println("-----女生起床步驟----"); //女生起床步驟 WomanPerson womanPerson = new WomanPerson(); womanPerson.prepareGoWorking(); } }
輸出結(jié)果:
-----男生起床步驟---- 穿西裝 刷牙 洗臉 直接在公司吃早餐 -----女生起床步驟---- 穿休閑衣服 刷牙 洗臉 在家弄點吃的,或者在外面買一點小吃
當(dāng)然,模版模式的玩法,還不僅僅只有這些,還可以在模版模式中使用掛鉤(hook)。
什么是hook呢?存在一個空實現(xiàn)的方法,我們稱這種方法為hook。子類可以視情況來決定是否要覆蓋它。
還是以上面為例子,比如吃完早餐就要出門上班,選擇什么交通工具呢?
抽象類新增方法hook(),內(nèi)容如下:
/** * 抽象類 */ public abstract class AbstractPerson { /** * 定義操作流程 */ public void prepareGoWorking(){ dressing();//穿衣服 brushTeeth();//刷牙 washFace();//洗臉 eatBreakFast();//吃早餐 hook();//掛鉤 } /**穿衣服*/ protected abstract void dressing(); /**刷牙*/ protected void brushTeeth(){ System.out.println("刷牙"); } /**洗臉*/ protected void washFace(){ System.out.println("洗臉"); } /**吃早餐*/ protected abstract void eatBreakFast(); /**掛鉤*/ protected void hook(){}; }
男生具體實現(xiàn)類,重寫hook()方法,內(nèi)容如下:
/** * 男生 * 具體實現(xiàn)類 */ public class ManPerson extends AbstractPerson{ @Override protected void dressing() { System.out.println("穿西裝"); } @Override protected void eatBreakFast() { System.out.println("直接在公司吃早餐"); } @Override protected void hook() { System.out.println("乘地鐵上班"); } }
運行測試類,男生具體實現(xiàn)類,輸出結(jié)果:
-----男生起床步驟---- 穿西裝 刷牙 洗臉 直接在公司吃早餐 乘地鐵上班
當(dāng)然,還有其他的玩法,比如女生洗完臉之后,可能需要化妝,我們再次將抽象類進(jìn)行處理,內(nèi)容如下:
/** * 抽象類 */ public abstract class AbstractPerson { /** * 定義操作流程 */ public void prepareGoWorking(){ dressing();//穿衣服 brushTeeth();//刷牙 washFace();//洗臉 //是否需要化妝,默認(rèn)不化妝 if(isMakeUp()){ System.out.println("進(jìn)行化妝"); } eatBreakFast();//吃早餐 hook();//掛鉤 } /**是否需要化妝方法*/ protected boolean isMakeUp(){ return false; } /**穿衣服*/ protected abstract void dressing(); /**刷牙*/ protected void brushTeeth(){ System.out.println("刷牙"); } /**洗臉*/ protected void washFace(){ System.out.println("洗臉"); } /**吃早餐*/ protected abstract void eatBreakFast(); /**掛鉤*/ protected void hook(){}; }
女生具體實現(xiàn)類,重寫isMakeUp()方法,內(nèi)容如下:
/** * 女生 * 具體實現(xiàn)類 */ public class WomanPerson extends AbstractPerson{ @Override protected void dressing() { System.out.println("穿休閑衣服"); } @Override protected void eatBreakFast() { System.out.println("在家弄點吃的,或者在外面買一點小吃"); } @Override protected boolean isMakeUp() { return true; } }
運行測試類,女生具體實現(xiàn)類,輸出結(jié)果:
-----女生起床步驟---- 穿休閑衣服 刷牙 洗臉 進(jìn)行化妝 在家弄點吃的,或者在外面買一點小吃
三、應(yīng)用
模版設(shè)計模式,應(yīng)用非常廣泛,比如javaEE中的servlet,當(dāng)我們每創(chuàng)建一個servlet的時候,都會繼承HttpServlet,其實HttpServlet已經(jīng)為我們提供一套操作流程,我們只需要重寫里面的方法即可!
HttpServlet 的部分源碼如下:
public abstract class HttpServlet extends GenericServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); if (method.equals(METHOD_GET)) { long lastModified = getLastModified(req); if (lastModified == -1) { // servlet doesn't support if-modified-since, no reason // to go through further expensive logic doGet(req, resp); } else { long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); if (ifModifiedSince < lastModified) { // If the servlet mod time is later, call doGet() // Round down to the nearest second for a proper compare // A ifModifiedSince of -1 will always be less maybeSetLastModified(resp, lastModified); doGet(req, resp); } else { resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } } } else if (method.equals(METHOD_HEAD)) { long lastModified = getLastModified(req); maybeSetLastModified(resp, lastModified); doHead(req, resp); } else if (method.equals(METHOD_POST)) { doPost(req, resp); } else if (method.equals(METHOD_PUT)) { doPut(req, resp); } else if (method.equals(METHOD_DELETE)) { doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) { doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) { doTrace(req,resp); } else { // // Note that this means NO servlet supports whatever // method was requested, anywhere on this server. // String errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[1]; errArgs[0] = method; errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); } } // ...省略... }
自定義一個 HelloWorld 的 Servlet 類,如下:
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { public void init() throws ServletException { // ... } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<h2>Hello World!</h2>"); } public void destroy() { // ... } }
到此,關(guān)于“怎么使用java模板模式”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。