设计模式 —— 工厂模式

工厂模式

2.1、什么是工厂模式

2.2.1、概念

概念:通过工厂类,创建对象

传统创建工厂的方式:

User user = new User();

2.2.2、好处

好处:解耦合。

耦合:指定是代码间的强关联关系,⼀方的改变会影响到另⼀方;
耦合问题:不利于代码维护;
简单理解:把接⼝的实现类,硬编码在程序中;

2.3、工厂模式使用

2.3.1、使用前

  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 + '\'' +
                    '}';
        }
    }
    
  2. 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);
          }
      }
      
  3. 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);
          }
      }
      
  4. 测试类

    @Test
    public void userTest(){
        UserService userService = new UserServiceImpl();
        User user = new User("zhangsan","123456");
        userService.register(user);
        userService.login("zhangsan","123456");
    }
    
  5. 运行结果

    insert into user = User{name='zhangsan', password='123456'}
    query User name = zhangsan ; password = 123456
    

问题:存在代码耦合

测试类中的:

UserService userService = new UserServiceImpl();

在修改UserServiceImpl()类后需要修改原测试类代码,不利于代码维护。

2.3.2、简单工厂

增加工厂类

  1. 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();
        }
    }
    
  2. 修改测试类

    @Test
    public void userTest(){
        UserService userService = BeanFactory.getUserService();
        User user = new User("zhangsan","123456");
        userService.register(user);
        userService.login("zhangsan","123456");
    }
    
  3. 运行结果

    insert into user = User{name='zhangsan', password='123456'}
    query User name = zhangsan ; password = 123456
    

解决了测试类中的 UserService userService = new UserServiceImpl(); 的代码耦合。

问题:但是增加了工程类中的 return new UserServiceImpl(); 的代码耦合。

2.3.3、反射工厂

对象的创建方式:

  1. 直接调用构造方法 创建对象 UserService userService = new UserServiceImpl();

  2. 通过反射的形式 创建对象 解耦合

    Class clazz = Class.forName(“cn.edu.hziee.service.UserServiceImpl”);
    userService = (UserService) clazz.newInstance();

  3. 修改工厂类

    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;
        }
    }
    
  4. 测试类

    @Test
    public void userTest(){
        UserService userService = BeanFactory.getUserService();
        User user = new User("zhangsan","123456");
        userService.register(user);
        userService.login("zhangsan","123456");
    }
    
  5. 运行结果

    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"); 的代码耦合。

解决方案:

  1. 增加applicationContext.properties

    userService = cn.edu.hziee.service.UserServiceImpl
    
  2. 修改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;
        }
    }
    
  3. 测试类

    @Test
    public void userTest(){
        UserService userService = BeanFactory.getUserService();
        User user = new User("zhangsan","123456");
        userService.register(user);
        userService.login("zhangsan","123456");
    }
    
  4. 运行结果

    insert into user = User{name='zhangsan', password='123456'}
    query User name = zhangsan ; password = 123456
    

解除UserServiceImpl中 private UserDAO userDAO = new UserDAOImpl(); 的代码耦合。同理:

  1. 增加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;
        }
    }
    
  2. 增加applicationContext.properties数据

    userService = cn.edu.hziee.service.UserServiceImpl
    userDAO = cn.edu.hziee.dao.UserDAOImpl
    
  3. 修改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);
        }
    }
    
  4. 测试类

    @Test
    public void userTest(){
        UserService userService = BeanFactory.getUserService();
        User user = new User("zhangsan","123456");
        userService.register(user);
        userService.login("zhangsan","123456");
    }
    
  5. 运行结果

    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)]

  1. 修改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;
        }
    }
    
  2. 修改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);
        }
    }
    
  3. 修改测试类

    @Test
    public void userTest(){
        UserService userService = (UserService) BeanFactory.getBean("userService");
        User user = new User("zhangsan","123456");
        userService.register(user);
        userService.login("zhangsan","123456");
    }
    
  4. 运行结果

    insert into user = User{name='zhangsan', password='123456'}
    query User name = zhangsan ; password = 123456
    

Spring本质:工厂 ApplicationContext (applicationContext.xml)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bit-apk-code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值