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

接口的关系图:
  [原创]java WEB学习笔记27:深入理解面向接口编程

3.具体代码的实现:

  1)CustomerDAOFactory.java

 package com.jason.mvcapp.dao.factory;

 import java.util.HashMap;
import java.util.Map; import com.jason.mvcapp.dao.CustomerDAO;
import com.jason.mvcapp.dao.impl.CustomerDAOJdbcImpl;
import com.jason.mvcapp.dao.impl.CustomerDAOXMLImpl; /***
*
* @author: jason
* @time:2016年5月28日下午5:37:39
* @description:单例的 CustomerDAO 工场类。采用饿汉式,线程安全
*/
public class CustomerDAOFactory { private Map<String , CustomerDAO> daos = new HashMap<String, CustomerDAO>(); //1.私有化构造器
private CustomerDAOFactory(){ daos.put("jdbc", new CustomerDAOJdbcImpl());
daos.put("xml", new CustomerDAOXMLImpl()); }
//2.创建一个静态的实例
private static CustomerDAOFactory instance = new CustomerDAOFactory();
//3.提供获取实例的方法
public static CustomerDAOFactory getInstance() {
return instance;
} private static String type = null; public void setType(String type) {
this.type = type;
} public static String getType() {
return type;
}
public CustomerDAO getCustomerDAO(){ return daos.get(type);
} }

    2)InitServlet.java

 package com.jason.mvcapp.servlet;

 import java.io.IOException;
import java.io.InputStream;
import java.util.Properties; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet; import com.jason.mvcapp.dao.factory.CustomerDAOFactory; /**
* Servlet implementation class InitServlet
*/
@WebServlet("/InitServlet")
public class InitServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override
public void init() throws ServletException {
CustomerDAOFactory.getInstance().setType("jdbc"); //1.读取类路径下的switch.properties 配置文件
InputStream is = getServletContext().getResourceAsStream("/WEB-INF/classes/switch.properties"); Properties properties = new Properties();
try {
properties.load(is); //2.获取switch.properties 的type 值
String type = properties.getProperty("type"); //3.赋值给CustomerDAOFactory 的type 属性
CustomerDAOFactory.getInstance().setType(type); } catch (IOException e) {
e.printStackTrace();
}
} }

  3)CustomerServlet2.java

 package com.jason.mvcapp.servlet;

 import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.jason.mvcapp.dao.CustomerDAO;
import com.jason.mvcapp.dao.factory.CustomerDAOFactory;
import com.jason.mvcapp.dao.impl.CustomerDAOJdbcImpl;
import com.jsaon.mvcapp.domain.CriteriaCustomer;
import com.jsaon.mvcapp.domain.Customer; /**
* Servlet implementation class CustomerServlet2
*/
@WebServlet("*.do")
public class CustomerServlet2 extends HttpServlet {
private static final long serialVersionUID = 1L; // 创建一个CustomerDAO对象,多态
27 private CustomerDAO customerDAO = CustomerDAOFactory.getInstance().getCustomerDAO();

protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
} protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 1.获取servletPath:/add.do 或者 query.do
String serveltPath = request.getServletPath(); // System.out.println(serveltPath);
// 2.去除/ 和 .do 得到对应的方法,如 add query
String methodName = serveltPath.substring(1);
methodName = methodName.substring(0, methodName.length() - 3);
// System.out.println(methodName); try {
// 3.利用反射获取methodName对应的方法
Method method = getClass().getDeclaredMethod(methodName,
HttpServletRequest.class, HttpServletResponse.class); // 4.利用反射调用方法
method.invoke(this, request, response);
} catch (Exception e) { e.printStackTrace();
}
} private void updateCustomer(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("update");
request.setCharacterEncoding("UTF-8"); //1.获取请求信息:id,name,address,phone,oldName //1.1 隐藏域的 值
String idStr = request.getParameter("id");
String oldNameStr = request.getParameter("oldName"); //1.2 提交的值
String nameStr = request.getParameter("name");
String addressStr = request.getParameter("address");
String phoneStr = request.getParameter("phone"); //2.验证name 是否可用
//通过equalsIgnoreCase() 方式 避免了 大小写的问题。equals 方法区分大小写, 而数据库SQL 不区分大小写
if(!oldNameStr.equalsIgnoreCase(nameStr)){
//2.1 先比较name 和 oldName 是否相同,若相同,说明name 可用
//2.2 若不相同,则调用CustomerDAO 的getCostomerWithName(String name) 获取 name 在数据库中是否存在
long rel = customerDAO.getCountWithName(nameStr);
//2.2.1 若存在,则返回值大于 0,则响应 updatecustomer.jsp 页面:通过转发的方式
if(rel > 0){
// 进行回显字符串,在request 中放入一个属性 message:用户名 name
// 回显:updatecustomer.jsp 的表单值可以回显
// value="<%= request.getParameter("name") == null ? "" : request.getParameter("name") %>" 进行回显
// 注意:name 显示的是 oldName,而address 和 phone 显示的是新的
request.setAttribute("message", "用户名 " + nameStr + " 已经被占用了,请重新选择!");
//2.2.2 存在,要求在updatecustomer.jsp 页面显示一条消息:用户名 name 已经被占用了,请重新选择
request.getRequestDispatcher("/updatecustomer.jsp").forward(request,response);
// 2.2.3 结束方法:return
return;
}
} //3.通过验证后,则将表单封装为一个Customer 对象 customer
Customer customer = new Customer(nameStr, addressStr, phoneStr);
customer.setId(Integer.parseInt(idStr)); //4.调用CustomerDAO 的save(Customer customer) 执行更新操作
customerDAO.update(customer); //5.重定向到 query.do
response.sendRedirect("query.do"); } private void editeCustomer(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("edit");
String forwardPath = "/error.jsp";
//1. 获取请求参数id
String idStr = request.getParameter("id");
try {
//2. 调用CustomerDAO 的get(id) 方法,获取 和id 对应的Customer 对象
Customer customer = customerDAO.get(Integer.parseInt(idStr));
if(customer != null){
forwardPath ="/updatecustomer.jsp";
//3. 将 customer 放入 request 中
request.setAttribute("customer", customer);
}
} catch (Exception e) {}
//4. 响应updatecustomer.jsp 页面: 转发的形式
request.getRequestDispatcher(forwardPath).forward(request, response); } private void deleteCustomer(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 1.获取请求删除的 id 为 String 类型
String idStr = request.getParameter("id");
// try{}catch{} 的作用:方式idStr 不能转化为 int 类型,若不能转则 id = 0,无法进行任何删除
int id = 0;
try {
// 2.将idStr 解析为int 型
id = Integer.parseInt(idStr);
// 3.调用dao方法 删除数据
customerDAO.delete(id);
} catch (Exception e) {
e.printStackTrace();
}
response.sendRedirect("query.do"); } private void query(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String address = request.getParameter("address");
String phone = request.getParameter("phone"); CriteriaCustomer criteriaCustomer = new CriteriaCustomer(name, address,
phone);
List<Customer> lists = customerDAO
.getForListWithCriteriaCustomer(criteriaCustomer); // //1.调用CustomerDAO 的getAll()方法的到Customer 集合
// List<Customer> lists = customerDAO.getAll();
// 2.把Customer 集合放入request
request.setAttribute("list", lists);
// 3.转发页面到index.jsp
request.getRequestDispatcher("/index.jsp").forward(request, response); } private void addCustomer(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException { System.out.println("add function");
request.setCharacterEncoding("UTF-8");
// 1.获取表单参数:name,address,phone
String name = request.getParameter("name");
String address = request.getParameter("address");
String phone = request.getParameter("phone"); // 2.检验 name 是否已经被占用
// 2.1调用 CustomerDAO 的 getCountWithName(String name) 获取 name 在数据库中是否存在 long rel = customerDAO.getCountWithName(name);
// 2.2 若返回值大于0,则响应newcustomer.jsp 页面:
if (rel > 0) {
// 2.2.1 要求在newcustomer.jsp 页面显示一条消息:用户名 name 已经被占用了,请重新选择
// 在request 中放入一个属性 message:用户名 name
// 已经被占用,请重新选择!在页面通过request.getAttribute("message") 的方式来显示
// 2.2.2 newcustomer.jsp 的表单值可以回显
// value="<%= request.getParameter("name") == null ? "" : request.getParameter("name") %>"
// 进行回显
request.setAttribute("message", "用户名 " + name + " 已经被占用了,请重新选择!");
// 通过转发的方式来响应 newcustomer.jsp
request.getRequestDispatcher("/newcustomer.jsp").forward(request,
response);
// 2.2.3 结束方法:return
return;
}
// 3.把表单参数封装为一个Customer 对象
Customer customer = new Customer(name, address, phone); // 4.调用 customerDAO 的 save(Customer customer) 方法执行保存
customerDAO.save(customer); // 5.重定向到success.jsp 页面:使用重定向可以避免出现表单的重复提交
response.sendRedirect("success.jsp");
}
}

  4)CustomerDAOXMLImpl.java

 package com.jason.mvcapp.dao.impl;

 import java.util.List;

 import com.jason.mvcapp.dao.CustomerDAO;
import com.jsaon.mvcapp.domain.CriteriaCustomer;
import com.jsaon.mvcapp.domain.Customer; public class CustomerDAOXMLImpl implements CustomerDAO { @Override
public List<Customer> getForListWithCriteriaCustomer(
CriteriaCustomer criteriaCustomer) {
System.out.println("CustomerDAOXMLImpl's getForListWithCriteriaCustomer");
return null;
} @Override
public List<Customer> getAll() {
System.out.println("CustomerDAOXMLImpl's getAll");
return null;
} @Override
public void save(Customer coustomer) {
System.out.println("CustomerDAOXMLImpl's save");
} @Override
public Customer get(Integer id) {
System.out.println("CustomerDAOXMLImpl's get");
return null;
} @Override
public void delete(Integer id) {
System.out.println("CustomerDAOXMLImpl's get"); } @Override
public long getCountWithName(String name) {
System.out.println("CustomerDAOXMLImpl's getCountWithName");
return 0;
} @Override
public void update(Customer customer) {
System.out.println("CustomerDAOXMLImpl's update"); } }

  5)CustomerDAOJdbcImpl.java

 package com.jason.mvcapp.dao.impl;

 import java.util.List;

 import com.jason.mvcapp.dao.CustomerDAO;
import com.jason.mvcapp.dao.DAO;
import com.jsaon.mvcapp.domain.CriteriaCustomer;
import com.jsaon.mvcapp.domain.Customer; /**
* @author: jason
* @time:2016年5月25日下午3:45:06
* @description:对CustomerDAO 的实现
*/
public class CustomerDAOJdbcImpl extends DAO<Customer> implements CustomerDAO { @Override
public List<Customer> getAll() {
String sql = "SELECT * FROM customers";
return getForList(sql);
} @Override
public void save(Customer customer) {
String sql = "INSERT INTO customers(name, address, phone) VALUES(?,?,? )";
update(sql,customer.getName(),customer.getAddress(),customer.getPhone());
} @Override
public Customer get(Integer id) {
String sql = "SELECT id, name, address, phone FROM customers WHERE id = ?";
return get(sql,id); } @Override
public void delete(Integer id) {
String sql = "DELETE FROM customers WHERE id = ?";
update(sql, id);
} @Override
public long getCountWithName(String name) {
String sql = "SELECT count(id) FROM customers WHERE name = ?";
return getForValue(sql, name);
} @Override
public List<Customer> getForListWithCriteriaCustomer(
CriteriaCustomer criteriaCustomer) {
//sql语句
String sql = "SELECT id,name,address,phone FROM customers WHERE name LIKE ? AND address LIKE ? AND phone LIKE ?";
//调用DAO<T> 中的方法getForList(),并且为占位符设置
return getForList(sql, criteriaCustomer.getName(),criteriaCustomer.getAddress(),criteriaCustomer.getPhone());
} @Override
public void update(Customer customer) {
String sql = "UPDATE customers SET name = ?, address = ?, phone = ? WHERE id = ?";
update(sql, customer.getName(), customer.getAddress(), customer.getPhone(), customer.getId());
} }

  6)switch.properties

 type=jdbc
#type=xml

  7)customer.xml

 <?xml version="1.0" encoding="UTF-8"?>

 <customers>
<customer id ="1001">
<name>tom</name>
<address>beijing</address>
<phone>123156456</phone>
</customer> </customers>

  8)web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<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">
<display-name>mvc</display-name> <servlet>
<servlet-name>InitServlet</servlet-name>
<servlet-class>com.jason.mvcapp.servlet.InitServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet> </web-app>

  ⑨)CustomerDAO.java

 package com.jason.mvcapp.dao;

 import java.util.List;

 import com.jsaon.mvcapp.domain.CriteriaCustomer;
import com.jsaon.mvcapp.domain.Customer; /**
* @author: jason
* @time:2016年5月25日下午3:28:00
* @description:
*/ public interface CustomerDAO { //带参数的模糊查询
public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer criteriaCustomer);
//查询所有
public List<Customer> getAll(); //保存操作
public void save(Customer coustomer); //更新前,先查询
public Customer get(Integer id); //删除用户
public void delete(Integer id); //查看与参数相同的名字有多少个记录数
public long getCountWithName(String name); //更新操作
public void update(Customer customer); }

  3.总结:

  1)从代码层次理解面向接口编程的优势

上一篇:基于HTML5的Drag and Drop生成图片Base64信息


下一篇:zw版【转发·*nvp系列Delphi例程】HALCON EdgesImage