工厂模式
2.1、什么是工厂模式
2.2.1、概念
概念:通过工厂类,创建对象
传统创建工厂的方式:
User user = new User();
2.2.2、好处
好处:解耦合。
耦合:指定是代码间的强关联关系,⼀方的改变会影响到另⼀方;
耦合问题:不利于代码维护;
简单理解:把接⼝的实现类,硬编码在程序中;
2.3、工厂模式使用
2.3.1、使用前
-
实体类
package cn.edu.hziee.pojo; public class User { private String name; private String password; public User() { } public User(String name, String password) { this.name = name; this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", password='" + password + '\'' + '}'; } }
-
dao层
-
UserDAO
package cn.edu.hziee.dao; import cn.edu.hziee.pojo.User; public interface UserDAO { public void save(User user); public void queryUserByNameAndPassword(String name, String password); }
-
UserDAOImpl
package cn.edu.hziee.dao; import cn.edu.hziee.pojo.User; public class UserDAOImpl implements UserDAO { @Override public void save(User user) { System.out.println("insert into user = " + user); } @Override public void queryUserByNameAndPassword(String name, String password) { System.out.println("query User name = " + name + " ; password = " + password); } }
-
-
Service层
-
UserService
package cn.edu.hziee.service; import cn.edu.hziee.pojo.User; public interface UserService { public void register(User user); public void login(String name, String password); }
-
UserServiceImpl
package cn.edu.hziee.service; import cn.edu.hziee.dao.UserDAO; import cn.edu.hziee.dao.UserDAOImpl; import cn.edu.hziee.pojo.User; public class UserServiceImpl implements UserService { private UserDAO userDAO = new UserDAOImpl(); @Override public void register(User user) { userDAO.save(user); } @Override public void login(String name, String password) { userDAO.queryUserByNameAndPassword(name,password); } }
-
-
测试类
@Test public void userTest(){ UserService userService = new UserServiceImpl(); User user = new User("zhangsan","123456"); userService.register(user); userService.login("zhangsan","123456"); }
-
运行结果
insert into user = User{name='zhangsan', password='123456'} query User name = zhangsan ; password = 123456
问题:存在代码耦合
测试类中的:
UserService userService = new UserServiceImpl();
在修改UserServiceImpl()类后需要修改原测试类代码,不利于代码维护。
2.3.2、简单工厂
增加工厂类
-
BeanFactoty
package cn.edu.hziee.factory; import cn.edu.hziee.service.UserService; import cn.edu.hziee.service.UserServiceImpl; public class BeanFactory { public static UserService getUserService(){ return new UserServiceImpl(); } }
-
修改测试类
@Test public void userTest(){ UserService userService = BeanFactory.getUserService(); User user = new User("zhangsan","123456"); userService.register(user); userService.login("zhangsan","123456"); }
-
运行结果
insert into user = User{name='zhangsan', password='123456'} query User name = zhangsan ; password = 123456
解决了测试类中的 UserService userService = new UserServiceImpl();
的代码耦合。
问题:但是增加了工程类中的 return new UserServiceImpl();
的代码耦合。
2.3.3、反射工厂
对象的创建方式:
-
直接调用构造方法 创建对象 UserService userService = new UserServiceImpl();
-
通过反射的形式 创建对象 解耦合
Class clazz = Class.forName(“cn.edu.hziee.service.UserServiceImpl”);
userService = (UserService) clazz.newInstance(); -
修改工厂类
BeanFactory
package cn.edu.hziee.factory; import cn.edu.hziee.service.UserService; public class BeanFactory { public static UserService getUserService(){ UserService userService = null; try { Class clazz = Class.forName("cn.edu.hziee.service.UserServiceImpl"); userService = (UserService) clazz.newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } return userService; } }
-
测试类
@Test public void userTest(){ UserService userService = BeanFactory.getUserService(); User user = new User("zhangsan","123456"); userService.register(user); userService.login("zhangsan","123456"); }
-
运行结果
insert into user = User{name='zhangsan', password='123456'} query User name = zhangsan ; password = 123456
解决了工程类中的 return new UserServiceImpl();
的代码耦合。
问题:但是增加了 Class clazz = Class.forName("cn.edu.hziee.service.UserServiceImpl");
的代码耦合。
解决方案:
-
增加applicationContext.properties
userService = cn.edu.hziee.service.UserServiceImpl
-
修改BeanFactory工厂类
package cn.edu.hziee.factory; import cn.edu.hziee.service.UserService; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class BeanFactory { private static Properties env = new Properties(); static { try { InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties"); env.load(inputStream); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } public static UserService getUserService(){ UserService userService = null; try { Class clazz = Class.forName(env.getProperty("userService")); userService = (UserService) clazz.newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } return userService; } }
-
测试类
@Test public void userTest(){ UserService userService = BeanFactory.getUserService(); User user = new User("zhangsan","123456"); userService.register(user); userService.login("zhangsan","123456"); }
-
运行结果
insert into user = User{name='zhangsan', password='123456'} query User name = zhangsan ; password = 123456
解除UserServiceImpl中 private UserDAO userDAO = new UserDAOImpl();
的代码耦合。同理:
-
增加BeanFactoty中getUserDAO()方法
package cn.edu.hziee.factory; import cn.edu.hziee.dao.UserDAO; import cn.edu.hziee.service.UserService; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class BeanFactory { private static Properties env = new Properties(); static { try { InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties"); env.load(inputStream); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } public static UserService getUserService(){ UserService userService = null; try { Class clazz = Class.forName(env.getProperty("userService")); userService = (UserService) clazz.newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } return userService; } public static UserDAO getUserDAO(){ UserDAO userDAO = null; try { Class clazz = Class.forName(env.getProperty("userDAO")); userDAO = (UserDAO) clazz.newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } return userDAO; } }
-
增加applicationContext.properties数据
userService = cn.edu.hziee.service.UserServiceImpl userDAO = cn.edu.hziee.dao.UserDAOImpl
-
修改UserServiceImpl
package cn.edu.hziee.service; import cn.edu.hziee.dao.UserDAO; import cn.edu.hziee.factory.BeanFactory; import cn.edu.hziee.pojo.User; public class UserServiceImpl implements UserService { private UserDAO userDAO = BeanFactory.getUserDAO(); @Override public void register(User user) { userDAO.save(user); } @Override public void login(String name, String password) { userDAO.queryUserByNameAndPassword(name,password); } }
-
测试类
@Test public void userTest(){ UserService userService = BeanFactory.getUserService(); User user = new User("zhangsan","123456"); userService.register(user); userService.login("zhangsan","123456"); }
-
运行结果
insert into user = User{name='zhangsan', password='123456'} query User name = zhangsan ; password = 123456
2.3.4、通用工厂
反射工厂的问题:BeanFactory中的大量代码结构相同,造成大量的代码冗余
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XJIcZQUB-1649665500206)(D:\Typora\Typora\Typora\typora-user-images\image-20210725183509690.png)]
-
修改BeanFactory工厂类
package cn.edu.hziee.factory; import cn.edu.hziee.dao.UserDAO; import cn.edu.hziee.service.UserService; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class BeanFactory { private static Properties env = new Properties(); static { try { InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties"); env.load(inputStream); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } public static Object getBean(String className){ Object bean = null; try { Class clazz = Class.forName(env.getProperty(className)); bean = clazz.newInstance(); } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { e.printStackTrace(); } return bean; } }
-
修改UserServiceImpl
package cn.edu.hziee.service; import cn.edu.hziee.dao.UserDAO; import cn.edu.hziee.factory.BeanFactory; import cn.edu.hziee.pojo.User; public class UserServiceImpl implements UserService { private UserDAO userDAO = (UserDAO) BeanFactory.getBean("userDAO"); @Override public void register(User user) { userDAO.save(user); } @Override public void login(String name, String password) { userDAO.queryUserByNameAndPassword(name,password); } }
-
修改测试类
@Test public void userTest(){ UserService userService = (UserService) BeanFactory.getBean("userService"); User user = new User("zhangsan","123456"); userService.register(user); userService.login("zhangsan","123456"); }
-
运行结果
insert into user = User{name='zhangsan', password='123456'} query User name = zhangsan ; password = 123456
Spring本质:工厂 ApplicationContext (applicationContext.xml)