本文共 3005 字,大约阅读时间需要 10 分钟。
耦合:指定是代码间的强关联关系,一方的改变会影响到另一方
问题:不利于代码的维护
如何解决耦合问题:工厂设计模式
当我们创建简单对象的时候,是通过反射或者new的方式创建,一步一步来:
版本1:
UserService userService = new UserServiceImpl();
即把接口的实现类硬编码在代码中,当实现类改变时势必会改变代码,使得代码重新编译和部署。
版本2:
UserService userService = BeanFactory.UserServiceFactoy();public class BeanFactory { public static UserService UserServiceFactoy(){ return new UserServiceImpl(); }}
新建立一个工厂方法,在这个方法中返回接口实现类的实例对象,解决了源代码的耦合问题,但却是治标不治本,根本上没有解决问题。
可以尝试通过反射的方式创建对象。
版本3:
public class BeanFactory { public static UserService UserServiceFactoy(){ UserService userService = null; try { Class clazz = Class.forName("com.qcby.basic.UserServiceImpl"); userService = (UserService) clazz.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return userService; }}
根据全类名获取对象的Class,再通过实例化创建对象,但还是没有解决耦合的问题,但是也为我们提供了解决方案的思路:现在是全类名被硬编码在了代码之中,我们是不是可以尝试将全类名取出来,放在一个配置文件中。
版本4:
在resource目录下新创建一个properties文件 ====> applicationContext.properties
将全类名写在这个文件中
userService = com.qcby.basic.UserServiceImpl
我们只需要在代码中读取整个配置文件就可以了。
public class BeanFactory { private static Properties properties = new Properties(); static { /*获得IO输入流*/ try { InputStream resourceAsStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties"); properties.load(resourceAsStream); resourceAsStream.close(); } catch (IOException e) { e.printStackTrace(); } } public static UserService UserServiceFactoy() throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class clazz = Class.forName(properties.getProperty("userService")); Object o = clazz.newInstance(); return (UserService) o; }}
这样我们不必将全类名硬编码在代码之中,但是我们又发现了一个问题,这样建立对象的方式过于繁琐,需要为每一个类都建立一个工厂方法,我们是不是可以建立一个通用的方法,即建立一个通用工厂来解决这个问题?
版本5:
public class BeanFactory { private static Properties properties = new Properties(); static { /*获得IO输入流*/ try { InputStream resourceAsStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties"); properties.load(resourceAsStream); resourceAsStream.close(); } catch (IOException e) { e.printStackTrace(); } } public static Object getImplFactoy(String key) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class clazz = Class.forName(properties.getProperty(key)); Object obj = clazz.newInstance(); return obj; }}
UserService userService = (UserService) BeanFactory.getImplFactoy("userService");
通过上述几个版本的迭代,我们实现了通用工厂的实现,也是Spring工厂的简单实现,即实现了Spring中的下面代码:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = (UserService) context.getBean("userService");
转载地址:https://blog.csdn.net/weixin_58104242/article/details/121073437 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!