[原创]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