一个简单的业务需求:使用Mysql和MVC三层架构根据id删除用户
dao层(持久层):
创建接口:
/**
* 专门负责用户增删改查
*/
public interface UserDao {
/**
* 根据id删除用户信息
*/
void deleteById();
}
创建接口的实现类:
public class UserDaoImplMysql implements UserDao {
@Override
public void deleteById() {
System.out.println("Mysql删除用户信息");
}
}
Service层(业务层):
业务接口:
/**
* 业务层,处理业务逻辑
*/
public interface UserService {
/**
* 删除用户信息
*/
void deteleUser();
}
业务层实现类:
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImplMysql();
@Override
public void deteleUser() {
userDao.deleteById();
}
}
web层:
public class UserAction {
UserService userService = new UserServiceImpl();
public void deleteRequest(){
userService.deteleUser();
}
}
测试程序:
public class Test {
public static void main(String[] args) {
UserAction userAction = new UserAction();
userAction.deleteRequest();
}
}
如果用了一段时间后,客户改需求,想要用Oracle数据库,那么程序需要改动的地方
public class UserDaoImplOracle implements UserDao {
@Override
public void deleteById() {
System.out.println("Oracle删除用户信息");
}
}
private UserDao userDao = new UserDaoImplOracle();
违反OCP原则,DIP原则
OCP:开闭原则,对修改关闭(使用方),对扩展开放(提供方)。最重要、最核心、最基础的原则。
软件需要变化时,尽量通过扩展软件实体行为来实现变化,而不是通过修改已有的代码来实现变化。
当进行系统功能扩展的时候,如果修改了之前稳定的程序,那么之前所有的程序都要进行重新测试,这是非常麻烦的。
DIP:依赖倒转(倒置)原则,核心是面向接口编程
当前程序怎么让其遵守OCP和DIP原则,采用”控制反转“这种编程思想。
控制反转:Ioc(Inversion of Control),是一种新型的设计模式,由于比较新,没有被纳入到GoF23种设计模式之中。
控制反转的核心:
控制反转的实现方式有多种,比较重要的是:依赖注入(Dependency Injection 简称DI)。
DI有包括两种常见的方式:
首先,对当前程序进行改造
1.service,UserDao不 new 具体的实现类了。
2.UserAction也不new具体的service实现类。
3.使用set注入或者构造方法注入
service:
public class UserServiceImpl implements UserService {
//private UserDao userDao = new UserDaoImplMysql();
//private UserDao userDao = new UserDaoImplOracle();
private UserDao userDao;
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void deteleUser() {
userDao.deleteById();
}
}
web:
public class UserAction {
//UserService userService = new UserServiceImpl();
UserService userService;
public UserAction(UserService userService) {
this.userService = userService;
}
public void deleteRequest(){
userService.deteleUser();
}
}
测试程序:
public class Test {
public static void main(String[] args) {
//UserAction userAction = new UserAction();
UserAction userAction = new UserAction(new UserServiceImpl(new UserDaoImplOracle()));
userAction.deleteRequest();
}
}
如果把这个Test看成一个Servlet,显然,具体需要用哪一个实现类,还是需要开发人员自己去new,如果这些实现类相当多,那么new的这个操作会相当复杂,可读性就会变差。
我们可以使用Spring框架,让框架帮我们管理这些对象。
Spring框架:Spring框架实现了控制反转Ioc这种思想的容器
1.可以帮你new对象
2.可以帮你维护对象之间的关系