前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring5深入浅出篇:Spring工厂设计模式拓展应用

Spring5深入浅出篇:Spring工厂设计模式拓展应用

原创
作者头像
全干程序员demo
发布2024-01-26 15:26:20
1390
发布2024-01-26 15:26:20
举报
文章被收录于专栏:Spring5深入浅出篇

Spring5深入浅出篇:Spring工厂设计模式拓展应用

简单工厂实现

这里直接上代码举例子

UserService.java

代码语言:java
复制
public interface UserService {
    public void register(User user);

    public void login(String name, String password);
}

UserServiceImpl.java

代码语言:java
复制
public class UserServiceImpl implements UserService {
    private UserDAO userDAO = new UserDAOImpl();

    public UserDAO getUserDAO() {
        return userDAO;
    }

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    @Override
    public void register(User user) {
        userDAO.save(user);
    }

    @Override
    public void login(String name, String password) {
        userDAO.queryUserByNameAndPassword(name, password);
    }
}

UserDAOImpl.java

代码语言:java
复制
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);
    }
}

为了方便测试更直观看到结果UserDAOImpl的方法采用打印一条字符串来体现,下面就通过测试类来调用UserService

测试类

代码语言:java
复制
   /**
     *  用于测试:工厂类进行解耦合的操作
     */
    @Test
    public void test1() {
       UserService userService = new UserServiceImpl();


        UserService userService = (UserService) BeanFactory.getBean("userService");

        userService.login("name", "suns");


        User user = new User("suns", "123456");
        userService.register(user);


    }

最终结果如下:

可以发现当我们在上图中就出现了耦合,当我们需要重新换一个实现类的时候需要重新修改代码在进行编译部署.下面就通过工厂设计模式来解决这个问题.

创建工厂类

BeanFactory.java

代码语言:java
复制
public class BeanFactory {
       public static UserService getUserService(){
		return new UserServiceImpl();
    }
}

这样就通过了工厂类中提供的getUserService方法来获取对象,这样测试类中就彻底没有耦合了,但是new对象的方法写到了工厂类中,下面来看看如何解决.

对象的创建方式

  • 直接调用构造方法 创建对象
代码语言:java
复制
UserService userService = new UserServiceImpl();
  • 通过反射的形式 创建对象 解耦合
代码语言:java
复制
Class clazz = Class.forName("com.baizhiedu.basic.UserServiceImpl");
UserService userService = (UserService)clazz.newInstance();

重新修改工厂类

BeanFactory.java

代码语言:java
复制
public class BeanFactory {
       public static UserService getUserService(){
		 UserService userService = null;
        try {                        
            Class clazz = Class.forName("com.baizhiedu.basic.UserServiceImpl");
            userService = (UserService) clazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return userService;
    }
}

通过反射并不能完全解决耦合的问题,因为这里的全限定类名字符串如果需要修改,也涉及到需要修改源码.这里我们通过读取resources下的properties文件来进行优化

applicationContext.properties

代码语言:properties
复制
userService = com.baizhiedu.basic.UserServiceImpl

BeanFactory.java

代码语言:java
复制
   private static Properties env = new Properties();

    static{
        try {
            //第一步 获得IO输入流
            InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
            //第二步 文件内容 封装 Properties集合中 key = userService value = com.baizhixx.UserServiceImpl
            env.load(inputStream);

            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

public static UserService getUserService() {

        UserService userService = null;
        try {
                                         //com.baizhiedu.basic.UserServiceImpl
            Class clazz = Class.forName(env.getProperty("userService"));
            userService = (UserService) clazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return userService;

    }

这里就是直接通过配置文件读取对应的全限定类名即可,使我们程序之间的耦合解决.即便是我们还需要解决UserDaoImpl的耦合也是异曲同工,只需要将UserServiceImpl,改成UserDaoImpl

UserDAO解耦

BeanFactory.java

代码语言:java
复制
 public static UserDAO getUserDAO(){

        UserDAO userDAO = null;
        try {
            Class clazz = Class.forName(env.getProperty("userDAO"));
            userDAO = (UserDAO) clazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return userDAO;

    }

applicationContext.xml

代码语言:xml
复制
<bean id="userDAO" class="com.baizhiedu.basic.UserDAOImpl"></bean>

通用工厂实现

可以发现上图代码出现冗余,我们应该对这种重复的代码块进行抽取

通用工厂代码

代码语言:java
复制
public class BeanFactory{
 
 public static Object getBean(String key){
 		Object ret = null;
 try {
 		Class clazz = Class.forName(env.getProperty(key));
 		ret = clazz.newInstance();
 } catch (Exception e) {
 	e.printStackTrace();
 }
 		return ret;
 }
}

这样只需要在applicationContext.xml中增加对应配置,就可以通过getBean方法传入对应的key从工厂获取到对象了.

代码语言:java
复制
  @Test
    public void test1() {
        UserService userService = (UserService) BeanFactory.getBean("userService");

        userService.login("name", "suns");


        User user = new User("suns", "123456");
        userService.register(user);


    }

通用工厂的使用方式

1.定义类型(需要创建对象的类)

2.通过配置文件的配置告知工厂(applicationContext.properties)

以key = value的形式

3.通过工厂获得类的对象

代码语言:java
复制
 Object ret = BeanFactory.getBean("key")

总结

Spring的本质其实就是工厂+配置文件的形式,但是Spring提供的工厂肯定是比我们现在设计的工厂功能要更加强大.

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring5深入浅出篇:Spring工厂设计模式拓展应用
    • 简单工厂实现
      • 创建工厂类
      • 对象的创建方式
      • 重新修改工厂类
      • UserDAO解耦
    • 通用工厂实现
      • 通用工厂代码
    • 通用工厂的使用方式
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档