1、什么是耦合
耦合,是我们现在经常说到的一个词语。其实耦合说简单就是,一个对象依赖另一个对象,如果其中一个对象进行了修改,引用的对象也要做出修改。
我们用程序来直观的表达:
在我们日常的开发中,将我们的后端分为三个层次,controller、service、和dao。
controller控制层:
public class UserController { UserService userService = new UserServiceImpl(); public String save(){ userService.save(); return ""; } }
Service接口层:
public interface UserService { void save(); }
service实现层:
public class UserServiceImpl implements UserService { UserDao userDao = new UserMySQLDaoImpl(); @Override public void save() { userDao.save(); } }
dao接口层:
public interface UserDao { void save(); }
dao实现层:
public class UserMySQLDaoImpl implements UserDao { @Override public void save() { System.out.println("mysql进行save"); } }
以前我们在没有使用Spring,没有进行解耦的时候,开发的代码就是这样。service想要使用dao层的代码,只能通过new的方式。
如果说,现在我们的需求发生了改变。mysql数据库坏了,无法使用了,我们现在要转换成oracle数据库,我们只能这么操作
public class UserServiceImpl implements UserService { // UserDao userDao = new UserMySQLDaoImpl(); UserDao userDao = new UserOracleDaoImpl(); @Override public void save() { userDao.save(); } }
dao层需要增加一个oracle实现类:
public class UserOracleDaoImpl implements UserDao { @Override public void save() { System.out.println("oracle进行save"); } }
我们发现,如果我们的dao层代码发送了改变,我们的service层的代码也需要发生改变。这就耦合。
如果我们的代码量级上去了,是成千上万行代码,这就是一件非常麻烦的事情。所以
我们引入了工厂设计模式(用来解耦)
2、工厂设计模式
我们可以通过一个对象来获取我们需要的对象,我们将这个类叫工厂
public class BeanFactory { public static UserDao getBean(){ return new UserMySQLDaoImpl(); } }
我们可以将service的和dao层的耦合转移到service和beanfactory的耦合
public class UserServiceImpl implements UserService { // UserDao userDao = new UserMySQLDaoImpl(); // UserDao userDao = new UserOracleDaoImpl(); UserDao userDao = BeanFactory.getBean(); @Override public void save() { userDao.save(); } }
将耦合转移到工厂对象上是我们做的解耦合的第一步
可是随着我们的对象越来越多,我们在BeanFactory类中写的返回对象也就越多,那我们有没有办法优化下呢?
这个时候我们的简单工厂就出现了,我们将代码进行优化一下:
public class BeanFactory { private static Properties properties = new Properties(); //加载配置文件 static { try { InputStream resourceAsStream = BeanFactory.class.getResourceAsStream("/application.properties"); properties.load(resourceAsStream); } catch (IOException e) { e.printStackTrace(); } } // public static UserDao getBean(){ // return new UserMySQLDaoImpl(); // } // public static UserDao getBean(){ // return new UserOracleDaoImpl(); // } public static UserDao getBean(String key){ //读取配置文件 String className = properties.getProperty(key); try { //通过反射获得对象 return (UserDao)Class.forName(className).newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } }
然后application.properties配置内容为:
userDao=com.wx.myspring.dao.impl.UserMySQLDaoImpl
我们发现简单工厂每次需要返回不同的对象,还是需要修改我们的BeanFactory对象,来进行返回不同的对象。那么我们可以返回一个通用对象吗?
public static Object getBean(String key){ Object ref = null; //读取配置文件 String className = properties.getProperty(key); try { //通过反射获得对象 ref = Class.forName(className).newInstance(); } catch (Exception e) { e.printStackTrace(); } return ref; }
这个时候我们只需要将service进行优化下
public class UserServiceImpl implements UserService { // UserDao userDao = new UserMySQLDaoImpl(); // UserDao userDao = new UserOracleDaoImpl(); UserDao userDao = (UserDao) BeanFactory.getBean("userDao"); @Override public void save() { userDao.save(); } }
3、总结
- 耦合就是一个类依赖其他的对象。这里我们可以定义为:在三层(controller、service、dao)结构划分明确的前提下,一层的代码做了修改,其他的层的代码也需要修改,这个就叫做耦合。
- 解耦,并不会让我们的代码量减少。
- 我们使用了BeanFactory后,我们只需要在使用的地方调用下getBean()方法,并传入对象的key,在将对象强转成我们需要使用的对象即可。
Spring就是这么一步步帮助我们解耦的