成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

代碼復用神器,模板模式實操分享

開發 前端
模板模式,顧名思義,定義一個模板,將部分邏輯以具體方法或者具體構造函數的形式實現,在抽象類中聲明一些抽象方法來迫使子類實現剩余的邏輯。

 

[[336153]]

本文轉載自微信公眾號「 Java極客技術」,作者 鴨血粉絲。轉載本文請聯系 Java極客技術公眾號。

一、介紹

模板模式,顧名思義,定義一個模板,將部分邏輯以具體方法或者具體構造函數的形式實現,在抽象類中聲明一些抽象方法來迫使子類實現剩余的邏輯。

不同的子類可以以不同的方式實現這些抽象方法,從而對剩余的邏輯有不同的實現,這就是模板方法模式的用意。

模板模式涉及到三個角色:

  • 抽象類(AbstractClass):實現了模板方法,定義了算法的骨架;
  • 具體類(ConcreteClass):實現抽象類中的抽象方法,已完成完整的算法;
  • 客戶角色:客戶類提出使用具體類的請求;

二、示例

舉個例子,以早上起床到上班所需要的操作為例,大致流程可以分為以下幾步:穿衣服、刷牙、洗臉、吃早餐等。男生和女生的操作可能有些區別。

我們創建一個抽象的類,定義好大致的操作流程,如下:

  1. /** 
  2.  * 抽象類 
  3.  */ 
  4. public abstract class AbstractPerson { 
  5.  
  6.     /** 
  7.      * 定義操作流程 
  8.      */ 
  9.     public void prepareGoWorking(){ 
  10.         dressing();//穿衣服 
  11.         brushTeeth();//刷牙 
  12.         washFace();//洗臉 
  13.         eatBreakFast();//吃早餐 
  14.     } 
  15.  
  16.     /**穿衣服*/ 
  17.     protected abstract void dressing(); 
  18.  
  19.     /**刷牙*/ 
  20.     protected void brushTeeth(){ 
  21.         System.out.println("刷牙"); 
  22.     } 
  23.  
  24.     /**洗臉*/ 
  25.     protected void washFace(){ 
  26.         System.out.println("洗臉"); 
  27.     } 
  28.  
  29.     /**吃早餐*/ 
  30.     protected abstract void eatBreakFast(); 
  31.  

因為男生和女生的行為不一樣,我們分別創建兩個具體類,如下:

  1. /** 
  2.  * 男生 
  3.  * 具體實現類 
  4.  */ 
  5. public class ManPerson extends AbstractPerson{ 
  6.  
  7.     @Override 
  8.     protected void dressing() { 
  9.         System.out.println("穿西裝"); 
  10.     } 
  11.  
  12.     @Override 
  13.     protected void eatBreakFast() { 
  14.         System.out.println("直接在公司吃早餐"); 
  15.     } 
  1. /** 
  2.  * 女生 
  3.  * 具體實現類 
  4.  */ 
  5. public class WomanPerson extends AbstractPerson{ 
  6.  
  7.     @Override 
  8.     protected void dressing() { 
  9.         System.out.println("穿休閑衣服"); 
  10.     } 
  11.  
  12.     @Override 
  13.     protected void eatBreakFast() { 
  14.         System.out.println("在家弄點吃的,或者在外面買一點小吃"); 
  15.     } 

創建一個客戶端,實現如下:

  1. public class TemplateClient { 
  2.  
  3.     public static void main(String[] args) { 
  4.         //男生起床步驟 
  5.         ManPerson manPerson = new ManPerson(); 
  6.         System.out.println("-----男生起床步驟----"); 
  7.         manPerson.prepareGoWorking(); 
  8.         System.out.println("-----女生起床步驟----"); 
  9.         //女生起床步驟 
  10.         WomanPerson womanPerson = new WomanPerson(); 
  11.         womanPerson.prepareGoWorking(); 
  12.     } 

輸出結果:

  1. -----男生起床步驟---- 
  2. 穿西裝 
  3. 刷牙 
  4. 洗臉 
  5. 直接在公司吃早餐 
  6. -----女生起床步驟---- 
  7. 穿休閑衣服 
  8. 刷牙 
  9. 洗臉 
  10. 在家弄點吃的,或者在外面買一點小吃 

當然,模版模式的玩法,還不僅僅只有這些,還可以在模版模式中使用掛鉤(hook)。

什么是hook呢?存在一個空實現的方法,我們稱這種方法為hook。子類可以視情況來決定是否要覆蓋它。

還是以上面為例子,比如吃完早餐就要出門上班,選擇什么交通工具呢?

抽象類新增方法hook(),內容如下:

  1. /** 
  2.  * 抽象類 
  3.  */ 
  4. public abstract class AbstractPerson { 
  5.  
  6.     /** 
  7.      * 定義操作流程 
  8.      */ 
  9.     public void prepareGoWorking(){ 
  10.         dressing();//穿衣服 
  11.         brushTeeth();//刷牙 
  12.         washFace();//洗臉 
  13.         eatBreakFast();//吃早餐 
  14.         hook();//掛鉤 
  15.     } 
  16.  
  17.     /**穿衣服*/ 
  18.     protected abstract void dressing(); 
  19.  
  20.     /**刷牙*/ 
  21.     protected void brushTeeth(){ 
  22.         System.out.println("刷牙"); 
  23.     } 
  24.  
  25.     /**洗臉*/ 
  26.     protected void washFace(){ 
  27.         System.out.println("洗臉"); 
  28.     } 
  29.  
  30.     /**吃早餐*/ 
  31.     protected abstract void eatBreakFast(); 
  32.  
  33.     /**掛鉤*/ 
  34.     protected void hook(){}; 
  35.  

男生具體實現類,重寫hook()方法,內容如下:

  1. /** 
  2.  * 男生 
  3.  * 具體實現類 
  4.  */ 
  5. public class ManPerson extends AbstractPerson{ 
  6.  
  7.     @Override 
  8.     protected void dressing() { 
  9.         System.out.println("穿西裝"); 
  10.     } 
  11.  
  12.     @Override 
  13.     protected void eatBreakFast() { 
  14.         System.out.println("直接在公司吃早餐"); 
  15.     } 
  16.  
  17.     @Override 
  18.     protected void hook() { 
  19.         System.out.println("乘地鐵上班"); 
  20.     } 

運行測試類,男生具體實現類,輸出結果:

  1. -----男生起床步驟---- 
  2. 穿西裝 
  3. 刷牙 
  4. 洗臉 
  5. 直接在公司吃早餐 
  6. 乘地鐵上班 

當然,還有其他的玩法,比如女生洗完臉之后,可能需要化妝,我們再次將抽象類進行處理,內容如下:

  1. /** 
  2.  * 抽象類 
  3.  */ 
  4. public abstract class AbstractPerson { 
  5.  
  6.     /** 
  7.      * 定義操作流程 
  8.      */ 
  9.     public void prepareGoWorking(){ 
  10.         dressing();//穿衣服 
  11.         brushTeeth();//刷牙 
  12.         washFace();//洗臉 
  13.         //是否需要化妝,默認不化妝 
  14.         if(isMakeUp()){ 
  15.             System.out.println("進行化妝"); 
  16.         } 
  17.         eatBreakFast();//吃早餐 
  18.         hook();//掛鉤 
  19.     } 
  20.  
  21.     /**是否需要化妝方法*/ 
  22.     protected boolean isMakeUp(){ 
  23.         return false
  24.     } 
  25.  
  26.     /**穿衣服*/ 
  27.     protected abstract void dressing(); 
  28.  
  29.     /**刷牙*/ 
  30.     protected void brushTeeth(){ 
  31.         System.out.println("刷牙"); 
  32.     } 
  33.  
  34.     /**洗臉*/ 
  35.     protected void washFace(){ 
  36.         System.out.println("洗臉"); 
  37.     } 
  38.  
  39.     /**吃早餐*/ 
  40.     protected abstract void eatBreakFast(); 
  41.  
  42.     /**掛鉤*/ 
  43.     protected void hook(){}; 
  44.  

女生具體實現類,重寫isMakeUp()方法,內容如下:

  1. /** 
  2.  * 女生 
  3.  * 具體實現類 
  4.  */ 
  5. public class WomanPerson extends AbstractPerson{ 
  6.  
  7.     @Override 
  8.     protected void dressing() { 
  9.         System.out.println("穿休閑衣服"); 
  10.     } 
  11.  
  12.     @Override 
  13.     protected void eatBreakFast() { 
  14.         System.out.println("在家弄點吃的,或者在外面買一點小吃"); 
  15.     } 
  16.  
  17.     @Override 
  18.     protected boolean isMakeUp() { 
  19.         return true
  20.     } 

運行測試類,女生具體實現類,輸出結果:

  1. -----女生起床步驟---- 
  2. 穿休閑衣服 
  3. 刷牙 
  4. 洗臉 
  5. 進行化妝 
  6. 在家弄點吃的,或者在外面買一點小吃 

三、應用

模版設計模式,應用非常廣泛,比如javaEE中的servlet,當我們每創建一個servlet的時候,都會繼承HttpServlet,其實HttpServlet已經為我們提供一套操作流程,我們只需要重寫里面的方法即可!

 

HttpServlet 的部分源碼如下:

  1. public abstract class HttpServlet extends GenericServlet { 
  2.     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  3.         // ... 
  4.     } 
  5.     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  6.         // ... 
  7.     } 
  8.     protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  9.         // ... 
  10.     } 
  11.     protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  12.         // ... 
  13.     } 
  14.     protected void doDelete(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException { 
  15.         // ... 
  16.     } 
  17.     protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  18.         // ... 
  19.     } 
  20.     protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  21.         // ... 
  22.     } 
  23.      
  24.     protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  25.         String method = req.getMethod(); 
  26.  
  27.         if (method.equals(METHOD_GET)) { 
  28.             long lastModified = getLastModified(req); 
  29.             if (lastModified == -1) { 
  30.                 // servlet doesn't support if-modified-since, no reason 
  31.                 // to go through further expensive logic 
  32.                 doGet(req, resp); 
  33.             } else { 
  34.                 long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); 
  35.                 if (ifModifiedSince < lastModified) { 
  36.                     // If the servlet mod time is later, call doGet() 
  37.                     // Round down to the nearest second for a proper compare 
  38.                     // A ifModifiedSince of -1 will always be less 
  39.                     maybeSetLastModified(resp, lastModified); 
  40.                     doGet(req, resp); 
  41.                 } else { 
  42.                     resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); 
  43.                 } 
  44.             } 
  45.  
  46.         } else if (method.equals(METHOD_HEAD)) { 
  47.             long lastModified = getLastModified(req); 
  48.             maybeSetLastModified(resp, lastModified); 
  49.             doHead(req, resp); 
  50.  
  51.         } else if (method.equals(METHOD_POST)) { 
  52.             doPost(req, resp); 
  53.              
  54.         } else if (method.equals(METHOD_PUT)) { 
  55.             doPut(req, resp); 
  56.              
  57.         } else if (method.equals(METHOD_DELETE)) { 
  58.             doDelete(req, resp); 
  59.              
  60.         } else if (method.equals(METHOD_OPTIONS)) { 
  61.             doOptions(req,resp); 
  62.              
  63.         } else if (method.equals(METHOD_TRACE)) { 
  64.             doTrace(req,resp); 
  65.              
  66.         } else { 
  67.             // 
  68.             // Note that this means NO servlet supports whatever 
  69.             // method was requested, anywhere on this server. 
  70.             // 
  71.  
  72.             String errMsg = lStrings.getString("http.method_not_implemented"); 
  73.             Object[] errArgs = new Object[1]; 
  74.             errArgs[0] = method; 
  75.             errMsg = MessageFormat.format(errMsg, errArgs); 
  76.              
  77.             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); 
  78.         } 
  79.     } 
  80.      
  81.     // ...省略... 

自定義一個 HelloWorld 的 Servlet 類,如下:

  1. import java.io.*; 
  2. import javax.servlet.*; 
  3. import javax.servlet.http.*; 
  4.  
  5. public class HelloWorld extends HttpServlet { 
  6.  
  7.   public void init() throws ServletException { 
  8.     // ... 
  9.   } 
  10.  
  11.   public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
  12.       response.setContentType("text/html"); 
  13.       PrintWriter out = response.getWriter(); 
  14.       out.println("<h1>Hello World!</h1>"); 
  15.   } 
  16.    
  17.   public void destroy() { 
  18.       // ... 
  19.   } 

四、總結

模版模式有著許多的優點:

1、模板方法模式通過把不變的行為搬移到超類,去除了子類中的重復代碼;2、子類實現算法的某些細節,有助于算法的擴展;3、通過一個父類調用子類實現的操作,通過子類擴展增加新的行為,符合開放-封閉原則;

也有些缺點:1、每個不同的實現都需要定義一個子類,這會導致類的個數的增加,設計更加抽象

 

如果某些類有一些共同的行為,可以使用模版設計模式,創建一個抽象類,將共同的行為定義在抽象類中,可以有效的減少子類重復的代碼。

 

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2021-07-09 07:21:40

SpringBootRedisLUA

2010-01-06 10:38:16

Linux安裝JDK

2010-04-12 09:36:29

Oacle merge

2022-12-15 17:50:14

2022-07-04 07:37:51

模板模式重構

2010-04-09 10:13:13

Oracle數據字典

2010-04-13 14:00:00

Oracle inse

2010-04-15 14:18:30

Oracle創建

2010-05-10 17:00:53

Oracle死鎖進程

2021-09-22 15:36:31

勒索軟件攻擊數據泄露

2024-04-28 10:52:25

CentOS系統RHEL系統

2009-12-01 18:03:56

Linux版本

2010-04-27 10:25:28

Oracle Subs

2010-05-18 12:24:16

MySQL binlo

2010-05-18 18:19:40

MySQL修改表結構

2010-05-20 15:53:15

配置MySQL

2009-11-30 13:05:00

Suse防火墻

2018-10-15 10:15:30

STM32Linux經驗

2009-11-30 08:56:44

配置Linux服務器

2010-04-13 16:30:13

Oracle權限
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品久久久久久中文字幕 | 欧美一区二区免费视频 | 99亚洲精品| 在线中文视频 | 欧美成人a∨高清免费观看 欧美日韩中 | 一区二区在线看 | 亚洲天堂精品久久 | 亚洲成人高清 | 中文字幕亚洲免费 | 波多野吉衣在线播放 | 欧美精品一区在线发布 | 99久久免费精品国产男女高不卡 | 欧美日韩在线免费 | 特黄小视频| 亚洲综合视频 | 亚洲网在线 | 一区二区福利视频 | av网址在线播放 | 午夜精品影院 | 看一级毛片 | 日本免费视频在线观看 | 在线一区二区三区 | av一区二区三区四区 | 在线视频 欧美日韩 | 久久小视频 | 一区二区视频 | 青青久草 | 不卡一区| 国产一区二区三区免费 | 国产精品成人品 | 国产视频一区二区 | av超碰| 狠狠爱综合 | 久久精品小视频 | 日韩视频在线免费观看 | 日韩中文在线视频 | 高清一区二区三区 | 一区免费视频 | 欧美成年人网站 | av中文在线观看 | 亚洲国产aⅴ成人精品无吗 综合国产在线 |