[原創]java WEB學習筆記27:深入理解面向接口編程


本博客為原創:綜合 尚硅谷(http://www.atguigu.com)的系統教程(深表感謝)和 網絡上的現有資源(博客,文檔,圖書等),資源的出處我會標明

本博客的目的:①總結自己的學習過程,相當於學習筆記 ②將自己的經驗分享給大家,相互學習,互相交流,不可商用

內容難免出現問題,歡迎指正,交流,探討,可以留言,也可以通過以下方式聯系。

本人互聯網技術愛好者,互聯網技術發燒友

微博:伊直都在0221

QQ:951226918

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.面向接口編程的優勢

  1)增加了程序的課擴展性,降低耦合度。即,只需要知道方法就好了,具體的實現不關注。如果需要新的功能,添加在接口中添加方法的聲明,還有具體的實現類,這就是可擴展性。

  2)程序的可配置性。通過一個配置的修改,就可以達到不同的實現的目的。

 

2.面向接口編程的實例。結合上mvc綜合實踐

  需求:通過MVC設計模式,實現對用戶的增刪改查操作。提供兩種實現方式:jdbc,xml ; 通過工場模式 和 MVC設計模式 實現對實現方式的切換。

  代碼:①  CustomerDAOFactory: 單例的 CustomerDAO 工場類。采用餓漢式,線程安全。返回一個CustomerDAO 對象的工廠。

     ②  InitServlet: 一個Servlet 類,實現了init() 方法,讀取  實現方式 配置文件  switch.properties , 獲取 設置的 type。

     ③  CustomerServlet2: 前台請求的Servlet, 其中有一個CutomerDAO 的私有屬性。可以由CustomerDAOFactory 創建。

       ④  CustomerDAOXMLImpl: CustomerDAO 接口的XML 形式的實現類。

     ⑤  CustomerDAOJdbcImpl: CustomerDAO 接口的JDBC實現類。

     ⑥  switch.properties: 實現方式 type 的配置文件。

       ⑦  customer.xml: customer 的xml 存儲文件

     ⑧  web.xml:  web的配置文件。此處只需配置 InitServlet的加載時間。而Servlet 的url-parttern 則由系統通過注解的方式實現配置

     ⑨  CustomerDAO : 操作 customer的 DAO接口

 

接口的關系圖:
  

 

3.具體代碼的實現:

 

  1)CustomerDAOFactory.java

 1 package com.jason.mvcapp.dao.factory;  2 
 3 import java.util.HashMap;  4 import java.util.Map;  5 
 6 import com.jason.mvcapp.dao.CustomerDAO;  7 import com.jason.mvcapp.dao.impl.CustomerDAOJdbcImpl;  8 import com.jason.mvcapp.dao.impl.CustomerDAOXMLImpl;  9 
10 /*** 11  * 12  * @author: jason 13  * @time:2016年5月28日下午5:37:39 14  * @description:單例的 CustomerDAO 工場類。采用餓漢式,線程安全 15  */
16 public class CustomerDAOFactory { 17 
18     private Map<String , CustomerDAO> daos = new HashMap<String, CustomerDAO>(); 19     
20     //1.私有化構造器
21     private CustomerDAOFactory(){ 22         
23         daos.put("jdbc", new CustomerDAOJdbcImpl()); 24         daos.put("xml", new CustomerDAOXMLImpl()); 25         
26  } 27     //2.創建一個靜態的實例
28     private static CustomerDAOFactory instance = new CustomerDAOFactory(); 29     //3.提供獲取實例的方法
30     public static CustomerDAOFactory getInstance() { 31         return instance; 32  } 33         
34     private static String type = null; 35     
36     public  void setType(String type) { 37         this.type = type; 38  } 39     
40     public static String getType() { 41         return type; 42  } 43     public CustomerDAO getCustomerDAO(){ 44         
45         return daos.get(type); 46  } 47     
48 }

 

 

    2)InitServlet.java

 1 package com.jason.mvcapp.servlet;  2 
 3 import java.io.IOException;  4 import java.io.InputStream;  5 import java.util.Properties;  6 
 7 import javax.servlet.ServletException;  8 import javax.servlet.annotation.WebServlet;  9 import javax.servlet.http.HttpServlet; 10 
11 import com.jason.mvcapp.dao.factory.CustomerDAOFactory; 12 
13 /**
14  * Servlet implementation class InitServlet 15  */
16 @WebServlet("/InitServlet") 17 public class InitServlet extends HttpServlet { 18 
19     private static final long serialVersionUID = 1L; 20 
21  @Override 22     public void init() throws ServletException { 23         CustomerDAOFactory.getInstance().setType("jdbc"); 24         
25         //1.讀取類路徑下的switch.properties 配置文件
26         InputStream is  =  getServletContext().getResourceAsStream("/WEB-INF/classes/switch.properties"); 27     
28         Properties properties = new Properties(); 29         try { 30  properties.load(is); 31             
32             //2.獲取switch.properties 的type 值
33             String type = properties.getProperty("type"); 34             
35             //3.賦值給CustomerDAOFactory 的type 屬性
36  CustomerDAOFactory.getInstance().setType(type); 37             
38         } catch (IOException e) { 39  e.printStackTrace(); 40  } 41  } 42 
43 }

 

 

  3)CustomerServlet2.java

 1 package com.jason.mvcapp.servlet;  2 
 3 import java.io.IOException;  4 import java.lang.reflect.Method;  5 import java.util.List;  6 
 7 import javax.servlet.ServletException;  8 import javax.servlet.annotation.WebServlet;  9 import javax.servlet.http.HttpServlet;  10 import javax.servlet.http.HttpServletRequest;  11 import javax.servlet.http.HttpServletResponse;  12 
 13 import com.jason.mvcapp.dao.CustomerDAO;  14 import com.jason.mvcapp.dao.factory.CustomerDAOFactory;  15 import com.jason.mvcapp.dao.impl.CustomerDAOJdbcImpl;  16 import com.jsaon.mvcapp.domain.CriteriaCustomer;  17 import com.jsaon.mvcapp.domain.Customer;  18 
 19 /**
 20  * Servlet implementation class CustomerServlet2  21  */
 22 @WebServlet("*.do")  23 public class CustomerServlet2 extends HttpServlet {  24     private static final long serialVersionUID = 1L;  25 
 26     // 創建一個CustomerDAO對象,多態 27 private CustomerDAO customerDAO = CustomerDAOFactory.getInstance().getCustomerDAO();  28 
 29     protected void doGet(HttpServletRequest request,  30             HttpServletResponse response) throws ServletException, IOException {  31  doPost(request, response);  32  }  33 
 34     protected void doPost(HttpServletRequest request,  35             HttpServletResponse response) throws ServletException, IOException {  36         // 1.獲取servletPath:/add.do 或者 query.do
 37         String serveltPath = request.getServletPath();  38 
 39         // System.out.println(serveltPath);  40         // 2.去除/ 和 .do 得到對應的方法,如 add query
 41         String methodName = serveltPath.substring(1);  42         methodName = methodName.substring(0, methodName.length() - 3);  43         // System.out.println(methodName);
 44 
 45         try {  46             // 3.利用反射獲取methodName對應的方法
 47             Method method = getClass().getDeclaredMethod(methodName,  48                     HttpServletRequest.class, HttpServletResponse.class);  49 
 50             // 4.利用反射調用方法
 51             method.invoke(this, request, response);  52         } catch (Exception e) {  53 
 54  e.printStackTrace();  55  }  56  }  57 
 58     private void updateCustomer(HttpServletRequest request, HttpServletResponse response)  59             throws ServletException, IOException {  60         System.out.println("update");  61         request.setCharacterEncoding("UTF-8");  62         
 63         //1.獲取請求信息:id,name,address,phone,oldName  64         
 65             //1.1 隱藏域的 值
 66             String  idStr = request.getParameter("id");  67             String  oldNameStr = request.getParameter("oldName");  68             
 69             //1.2 提交的值
 70             String  nameStr = request.getParameter("name");  71             String  addressStr = request.getParameter("address");  72             String  phoneStr = request.getParameter("phone");  73         
 74         //2.驗證name 是否可用  75             //通過equalsIgnoreCase() 方式 避免了 大小寫的問題。equals 方法區分大小寫, 而數據庫SQL 不區分大小寫
 76             if(!oldNameStr.equalsIgnoreCase(nameStr)){  77                 //2.1 先比較name 和 oldName 是否相同,若相同,說明name 可用  78                 //2.2 若不相同,則調用CustomerDAO 的getCostomerWithName(String name) 獲取 name 在數據庫中是否存在
 79                 long rel = customerDAO.getCountWithName(nameStr);  80                 //2.2.1 若存在,則返回值大於 0,則響應 updatecustomer.jsp 頁面:通過轉發的方式
 81                 if(rel > 0){  82                     // 進行回顯字符串,在request 中放入一個屬性 message:用戶名 name  83                     // 回顯:updatecustomer.jsp 的表單值可以回顯  84                     // value="<%= request.getParameter("name") == null ? "" : request.getParameter("name") %>" 進行回顯  85                     // 注意:name 顯示的是 oldName,而address 和 phone 顯示的是新的
 86                     request.setAttribute("message", "用戶名 " + nameStr + " 已經被占用了,請重新選擇!");  87                     //2.2.2 存在,要求在updatecustomer.jsp 頁面顯示一條消息:用戶名 name 已經被占用了,請重新選擇
 88                     request.getRequestDispatcher("/updatecustomer.jsp").forward(request,response);  89                     // 2.2.3 結束方法:return
 90                     return;  91  }  92  }  93         
 94         //3.通過驗證后,則將表單封裝為一個Customer 對象 customer
 95             Customer  customer = new Customer(nameStr, addressStr, phoneStr);  96  customer.setId(Integer.parseInt(idStr));  97             
 98         //4.調用CustomerDAO 的save(Customer customer) 執行更新操作
 99  customerDAO.update(customer); 100             
101         //5.重定向到 query.do 
102             response.sendRedirect("query.do"); 103 
104  } 105 
106     private void editeCustomer(HttpServletRequest request, 107             HttpServletResponse response) throws ServletException, IOException { 108         System.out.println("edit"); 109         String forwardPath = "/error.jsp"; 110         //1. 獲取請求參數id
111          String idStr = request.getParameter("id"); 112          try { 113              //2. 調用CustomerDAO 的get(id) 方法,獲取 和id 對應的Customer 對象
114              Customer customer = customerDAO.get(Integer.parseInt(idStr)); 115             if(customer != null){ 116                 forwardPath ="/updatecustomer.jsp"; 117                 //3. 將 customer 放入 request 中
118                 request.setAttribute("customer", customer); 119  } 120         } catch (Exception e) {} 121          //4. 響應updatecustomer.jsp 頁面: 轉發的形式
122  request.getRequestDispatcher(forwardPath).forward(request, response); 123         
124  } 125 
126     private void deleteCustomer(HttpServletRequest request, 127             HttpServletResponse response) throws ServletException, IOException { 128         // 1.獲取請求刪除的 id 為 String 類型
129         String idStr = request.getParameter("id"); 130         // try{}catch{} 的作用:方式idStr 不能轉化為 int 類型,若不能轉則 id = 0,無法進行任何刪除
131         int id = 0; 132         try { 133             // 2.將idStr 解析為int 型
134             id = Integer.parseInt(idStr); 135             // 3.調用dao方法 刪除數據
136  customerDAO.delete(id); 137         } catch (Exception e) { 138  e.printStackTrace(); 139  } 140         response.sendRedirect("query.do"); 141 
142  } 143 
144     private void query(HttpServletRequest request, HttpServletResponse response) 145             throws ServletException, IOException { 146         request.setCharacterEncoding("UTF-8"); 147         String name = request.getParameter("name"); 148         String address = request.getParameter("address"); 149         String phone = request.getParameter("phone"); 150 
151         CriteriaCustomer criteriaCustomer = new CriteriaCustomer(name, address, 152  phone); 153         List<Customer> lists = customerDAO 154  .getForListWithCriteriaCustomer(criteriaCustomer); 155 
156         // //1.調用CustomerDAO 的getAll()方法的到Customer 集合 157         // List<Customer> lists = customerDAO.getAll(); 158         // 2.把Customer 集合放入request
159         request.setAttribute("list", lists); 160         // 3.轉發頁面到index.jsp
161         request.getRequestDispatcher("/index.jsp").forward(request, response); 162 
163  } 164 
165     private void addCustomer(HttpServletRequest request, 166             HttpServletResponse response) throws ServletException, IOException { 167 
168         System.out.println("add function"); 169         request.setCharacterEncoding("UTF-8"); 170         // 1.獲取表單參數:name,address,phone
171         String name = request.getParameter("name"); 172         String address = request.getParameter("address"); 173         String phone = request.getParameter("phone"); 174 
175         // 2.檢驗 name 是否已經被占用 176         // 2.1調用 CustomerDAO 的 getCountWithName(String name) 獲取 name 在數據庫中是否存在
177 
178         long rel = customerDAO.getCountWithName(name); 179         // 2.2 若返回值大於0,則響應newcustomer.jsp 頁面:
180         if (rel > 0) { 181             // 2.2.1 要求在newcustomer.jsp 頁面顯示一條消息:用戶名 name 已經被占用了,請重新選擇 182             // 在request 中放入一個屬性 message:用戶名 name 183             // 已經被占用,請重新選擇!在頁面通過request.getAttribute("message") 的方式來顯示 184             // 2.2.2 newcustomer.jsp 的表單值可以回顯 185             // value="<%= request.getParameter("name") == null ? "" : request.getParameter("name") %>" 186             // 進行回顯
187             request.setAttribute("message", "用戶名 " + name + " 已經被占用了,請重新選擇!"); 188             // 通過轉發的方式來響應 newcustomer.jsp
189             request.getRequestDispatcher("/newcustomer.jsp").forward(request, 190  response); 191             // 2.2.3 結束方法:return
192             return; 193  } 194             // 3.把表單參數封裝為一個Customer 對象
195             Customer customer = new Customer(name, address, phone); 196 
197             // 4.調用 customerDAO 的 save(Customer customer) 方法執行保存
198  customerDAO.save(customer); 199 
200             // 5.重定向到success.jsp 頁面:使用重定向可以避免出現表單的重復提交
201             response.sendRedirect("success.jsp"); 202  } 203     }

 

 

 

  4)CustomerDAOXMLImpl.java

 1 package com.jason.mvcapp.dao.impl;  2 
 3 import java.util.List;  4 
 5 import com.jason.mvcapp.dao.CustomerDAO;  6 import com.jsaon.mvcapp.domain.CriteriaCustomer;  7 import com.jsaon.mvcapp.domain.Customer;  8 
 9 public class CustomerDAOXMLImpl implements CustomerDAO { 10 
11  @Override 12     public List<Customer> getForListWithCriteriaCustomer( 13  CriteriaCustomer criteriaCustomer) { 14         System.out.println("CustomerDAOXMLImpl's  getForListWithCriteriaCustomer"); 15         return null; 16  } 17 
18  @Override 19     public List<Customer> getAll() { 20         System.out.println("CustomerDAOXMLImpl's  getAll"); 21         return null; 22  } 23 
24  @Override 25     public void save(Customer coustomer) { 26         System.out.println("CustomerDAOXMLImpl's  save"); 27  } 28 
29  @Override 30     public Customer get(Integer id) { 31         System.out.println("CustomerDAOXMLImpl's  get"); 32         return null; 33  } 34 
35  @Override 36     public void delete(Integer id) { 37         System.out.println("CustomerDAOXMLImpl's  get"); 38         
39  } 40 
41  @Override 42     public long getCountWithName(String name) { 43         System.out.println("CustomerDAOXMLImpl's  getCountWithName"); 44         return 0; 45  } 46 
47  @Override 48     public void update(Customer customer) { 49         System.out.println("CustomerDAOXMLImpl's  update"); 50 
51  } 52 
53 }

 

 

  5)CustomerDAOJdbcImpl.java

 1 package com.jason.mvcapp.dao.impl;  2 
 3 import java.util.List;  4 
 5 import com.jason.mvcapp.dao.CustomerDAO;  6 import com.jason.mvcapp.dao.DAO;  7 import com.jsaon.mvcapp.domain.CriteriaCustomer;  8 import com.jsaon.mvcapp.domain.Customer;  9 
10 /**
11  * @author: jason 12  * @time:2016年5月25日下午3:45:06 13  * @description:對CustomerDAO 的實現 14  */
15 public class CustomerDAOJdbcImpl extends DAO<Customer> implements CustomerDAO { 16 
17  @Override 18     public List<Customer> getAll() { 19         String sql = "SELECT * FROM customers"; 20         return getForList(sql); 21  } 22 
23  @Override 24     public void save(Customer customer) { 25         String sql = "INSERT INTO customers(name, address, phone) VALUES(?,?,? )"; 26  update(sql,customer.getName(),customer.getAddress(),customer.getPhone()); 27  } 28 
29 
30  @Override 31     public Customer get(Integer id) { 32         String sql = "SELECT id, name, address, phone FROM customers WHERE id = ?"; 33         return get(sql,id); 34         
35  } 36 
37  @Override 38     public void delete(Integer id) { 39         String sql = "DELETE FROM customers WHERE id = ?"; 40  update(sql, id); 41  } 42 
43  @Override 44     public long getCountWithName(String name) { 45         String sql = "SELECT count(id) FROM customers WHERE name = ?"; 46         return getForValue(sql, name); 47  } 48 
49  @Override 50     public List<Customer> getForListWithCriteriaCustomer( 51  CriteriaCustomer criteriaCustomer) { 52         //sql語句
53         String sql = "SELECT id,name,address,phone FROM customers WHERE name LIKE ? AND  address LIKE ? AND phone LIKE ?"; 54         //調用DAO<T> 中的方法getForList(),並且為占位符設置
55         return getForList(sql, criteriaCustomer.getName(),criteriaCustomer.getAddress(),criteriaCustomer.getPhone()); 56  } 57 
58  @Override 59     public void update(Customer customer) { 60         String sql = "UPDATE customers  SET name = ?, address = ?, phone = ? WHERE id = ?"; 61  update(sql, customer.getName(), customer.getAddress(), customer.getPhone(), customer.getId()); 62  } 63 
64 }

 

 

  6)switch.properties

1 type=jdbc 2 #type=xml

 

 

  7)customer.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <customers>
 4     <customer id ="1001">
 5         <name>tom</name>
 6         <address>beijing</address>
 7         <phone>123156456</phone>
 8     </customer>
 9     
10 </customers>

 

 

  8)web.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
 3   <display-name>mvc</display-name>
 4 
 5 <servlet>
 6     <servlet-name>InitServlet</servlet-name>
 7     <servlet-class>com.jason.mvcapp.servlet.InitServlet</servlet-class>
 8     <load-on-startup>1</load-on-startup>
 9 </servlet>
10   
11   
12   
13 </web-app>

 

 

   ⑨)CustomerDAO.java

 1 package com.jason.mvcapp.dao;  2 
 3 import java.util.List;  4 
 5 import com.jsaon.mvcapp.domain.CriteriaCustomer;  6 import com.jsaon.mvcapp.domain.Customer;  7 
 8 
 9 /**
10  * @author: jason 11  * @time:2016年5月25日下午3:28:00 12  * @description: 13  */
14 
15 public interface CustomerDAO { 16 
17     //帶參數的模糊查詢
18     public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer criteriaCustomer); 19       //查詢所有
20     public List<Customer> getAll(); 21     
22     //保存操作
23     public void save(Customer coustomer); 24     
25     //更新前,先查詢
26     public Customer get(Integer id); 27     
28     //刪除用戶
29     public void delete(Integer id); 30     
31     //查看與參數相同的名字有多少個記錄數
32     public long getCountWithName(String name); 33     
34     //更新操作
35     public void update(Customer customer); 36     
37 }

 

 

 

  3.總結:

  1)從代碼層次理解面向接口編程的優勢

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM