Spring之OCP开闭原则和DIP依赖倒置原则
通过如下代码,来分析几个开发原则(OCP开闭原则和DIP依赖倒置原则)
代码结构
1.Test类
package com.xu.spring6.client;
import com.xu.spring6.web.UserAction;
public class Test {
public static void main(String[] args) {
UserAction userAction = new UserAction();
userAction.deleteUser();
}
}
2.UserAction类
package com.xu.spring6.web;
import com.xu.spring6.service.UserService;
import com.xu.spring6.service.impl.UserServiceImpl;
public class UserAction {
private UserService userService = new UserServiceImpl();
public void deleteUser(){
userService.deleteUser();
}
}
3.UserService接口和UserServiceImpl实现类
package com.xu.spring6.service;
public interface UserService {
void deleteUser();
}
package com.xu.spring6.service.impl;
import com.xu.spring6.dao.UserDao;
import com.xu.spring6.dao.impl.UserDaoImplForMySQL;
import com.xu.spring6.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImplForMySQL();
@Override
public void deleteUser() {
userDao.deleteUser();
}
}
4.UserDao接口和UserDaoImplForMySQL实现类
package com.xu.spring6.dao;
public interface UserDao {
void deleteUser();
}
package com.xu.spring6.dao.impl;
import com.xu.spring6.dao.UserDao;
public class UserDaoImplForMySQL implements UserDao {
@Override
public void deleteUser() {
System.out.println("正在删除用户信息~");
}
}
分析上述代码存在问题
UserAction类中用到了private UserService userService = new UserServiceImpl();
UserServiceImpl实现类中用到了private UserDao userDao = new UserDaoImplForMySQL();
如果现在,我想从MySQL(UserDaoImplForMySQL)切换到Oracle(UserDaoImplForOracle),那么我就必须修改UserServiceImpl类的代码,将声明成员变量userDao的代码改为如下:
private UserDao userDao = new UserDaoImplForOracle();
这个就违反了OCP开闭原则和DIP依赖倒置原则。
OCP开闭原则
开闭原则(Open-Closed Principle):简称OCP,在软件开发过程中应当对扩展开放,对修改关闭。也就是说,如果在进行功能扩展的时候,添加额外的类是没问题的,但因为功能扩展而修改之前运行正常的程序,这是不推荐的。因为一旦修改之前运行正常的程序,就会导致项目整体要进行全方位的重新测试。这是相当繁琐的过程。导致这个问题的主要原因是:代码和代码之间的耦合度太高。如下图所示:
上层是依赖下层的。UserAction依赖UserServiceImpl,而UserServiceImpl依赖UserDaoImplForMySQL,这样就会导致下面只要改动,上面必然会受牵连(跟着也会改),所谓牵一发而动全身。这个也同时违背了另一个开发原则:依赖倒置原则。
DIP依赖倒置原则
依赖倒置原则(Dependence Inversion Principle):简称DIP,主要倡导面向抽象编程,面向接口编程,不要面向具体编程,让上层不再依赖下层,下面改动了,上面的代码不会受到牵连。这样可以大大降低程序的耦合度,耦合度低了,扩展力就强了,同时代码复用性也会增强。(软件七大开发原则都是在为解耦合服务)
前面有问题的代码没有完全实现面向接口编程,因为代码中还是使用了接口的具体实现类。
下面这种才算是完全的面向接口编程,符合依赖倒置原则。