IOC程序中解耦应用-工厂模式解耦

需求

** 实际开发中由于客户的数据库环境经常变化,客户希望更换数据库时候,只需要修改dao(数据访问层)的代码,不需要修改service(业务层)的代码,这个时候就需要根据开闭原则使用到耦合性很低的技术了,保证不动源码的情况下进行程序的拓展开发是开发者必备技能之一。下面我们通过一段代码来实现对IOC容器工厂模式解耦的应用.**

先创建一个maven工程,因为需要用到junit测试,公众号前几天的文章讲过怎么创建maven工程,这里不再赘述,不了解的小伙伴可以在微信公众号{框架师}查找之前的文章,里面有详细的介绍怎么创建maven工程.

代码实现

1)先设计Dao接口和实现

/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 15:26
 */
public interface UserDao {
    public void save();
}

在设计一个mysql实现,因为是测试所以并不是真的连接数据库.

package com.mobaijun.dao.impl;

import com.mobaijun.dao.UserDao;

/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 15:27
 */
public class UserDaoMysqlImpl implements UserDao {

    @Override
    public void save() {
        System.out.println("数据库已经保存到MySQL数据库了");
    }
}

2)设计一个Service接口和实现

package com.mobaijun.service;

/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 15:28
 */
public interface UserService {
    public void save();
}

/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 15:30
 * 业务层
 */
public class UserServiceImpl implements UserService {

    //创建具体Dao实现对象
    private UserDao userDao = new UserDaoMySQLImpl();

    @Override
    public void save() {
        userDao.save();
    }
}

3)在maven工程test创建测试类UserServiceTest测试类

/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 15:31
 * 测试类
 */
public class UserServiceTest {

    @Test
    public void testSave(){
        UserService userService = new UserServiceImpl();
        userService.save();
    }

}

这时,需要从MySQL切换到Oracle数据库,根据开闭原则,扩展了Dao实现

/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 15:32
 */
public class UserDaoOracleLImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("数据已经保存到oracle数据库啦");
    }
}

这时业务层修改源代码,切换Dao

/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 15:33
 */
public class UserServiceImpl implements UserService {

    //创建具体Dao实现对象
    //private UserDao userDao = new UserDaoMySQLImpl();

    //切换Dao实现类
    private UserDao userDao = new UserDaoOracleLImpl();

这样不太好,每次都需要修改Service的源代码,Service和Dao的耦合性太高!

那么怎么办?这时我们就可以使用工厂模式(Factory)解决问题!

设计一个对象工厂,创建UserDao实现类

/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 15:36
 * 创建对象(UserDao实现类对象)
 */
public class BeanFactory {
    public static UserDao getBean(){
        return new UserDaoMySQLImpl();
    }
    
}

这时,业务每次需要Dao从工厂获取,好处是没有修改Dao,不用修改Service

/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 15:39
 *  业务层
 */
public class UserServiceImpl implements UserService {

    //创建具体Dao实现对象
    //private UserDao userDao = new UserDaoMySQLImpl();

    //切换Dao实现类
    //private UserDao userDao = new UserDaoOracleLImpl();

    //从工厂获取对象
    private UserDao userDao = BeanFactory.getBean();

但是还有问题,BeanFactory每次都修改代码,耦合也是太高,思路:可不可以 不用使用配置文件配置创建对象,BeanFactory改造成更加通用的工厂?是可以的 !我们通过使用配置文件

在resources包下创建bean.properties配置文件配置存放链接数据库的配置文件

userDao=com.mobaijun.dao.impl.UserDaoMySQLImpl

userService=com.mobaijun.service.impl.UserServiceImpl

这时修改BeanFacotry

/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 15:50
 * 创建工厂对象
 */
public class BeanFactory {

    //ResourceBundle读取properties{配置文件}
    private static  ResourceBundle bundle;

    /*public static UserDao getBean(){
        return new UserDaoOracleLImpl();
    }*/

    /**
     * 读取bean.properties创建对应的对象
     * @return
     */
    public static Object getBean(String key){
        //1.读取bean.properties
        if(bundle==null){
            bundle = ResourceBundle.getBundle("bean");
        }

        //2.通过key获取value
        String className = bundle.getString(key);

        //3.通过反射创建对象
        try {
            return Class.forName(className).newInstance();
        }  catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

最后,Service和测试代码

/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 16:12
 */
public class UserServiceImpl implements UserService {

    //创建具体Dao实现对象
    //private UserDao userDao = new UserDaoMySQLImpl();

    //切换Dao实现类
    //private UserDao userDao = new UserDaoOracleLImpl();

    //从工厂获取对象
    private UserDao userDao = (UserDao)BeanFactory.getBean("userDao");
/**
 * @Author:Auser·杰
 * @DATE:2019/8/18 16:20
 *测试类
 */
public class UserServiceTest {

    @Test
    public void testSave(){
        UserService userService = (UserService) BeanFactory.getBean("userService");
        userService.save();
    }

}

总结 ,在使用工厂模式的时候,我们明显的让Service和Dao的耦合降低了!

你可能感兴趣的:(java,后端工程师,java程序员)