工厂模式为 MVC 解耦

绪论

最近使用 MVC 模式实在是不能自拔,同时也致使出现一列的问题:高耦合。
每一个程序猿谈到程序如何设计才好的时候,基本上张嘴就来:高并发、低耦合、高内聚......
那么问题来了,什么是耦合?如何实现低耦合?

耦合

耦合就是对模块间关联程度的度量。简单来讲就是个程序之间的依赖程度,包括类之间的依赖、函数之间的了依赖。

栗子

咱们有这么一个场景,须要实现一个帐户保存的功能。这个很简单,无非就是两个接口、两个实现类、再加一个测试类的事情。

整个功能的包结构

包结构

上代码

Talk is cheap, show me the code;
  • 建立帐户持久层接口 IAccountDao,定义保存帐户抽象方法
public interface IAccountDao {

    /**
     * 保存帐户
     */
    void saveAccount();
}
  • 实现帐户持久层酒楼 AccountDaoImpl,并建立并实现 saveAccount 方法,输出保存信息。
public class AccountDaoImpl implements IAccountDao {

    @Override
    public void saveAccount() {
        System.out.println("已保存帐户~!");
    }
}
  • 定义帐户业务层接口 IAccountService,并定义一个保障帐户的方法
public interface IAccountService {

    /**
     * 保存帐户
     */
    void saveAccount();
}
  • 实现帐户业务层接口 AccountServiceImpl,实现调用持久层 saveAccount 方法实现保存帐号抽象方法。
public class AccountServiceImpl implements IAccountService {

    /**
     * 持久层对象
     */
    private IAccountDao accountDao = new AccountDaoImpl();

    @Override
    public void saveAccount() {
        accountDao.saveAccount();
    }
}
  • 最后编写表现层 AccountDemo,测试下该用例是否能正常运行(确定能,这步是多余的),贴代码了
public class AccountDemo {

    public static void main(String[] args) {
        IAccountService as = new AccountServiceImpl();
        as.saveAccount();
    }
}

// 如下为输出结果
已保存帐户~!

强势分析一波

那么咱们刚刚说的低耦合,在上面的这几段代码中,耦合程度是很高的。为啥说高耦合呢,倘若咱们不当心删了 AccountDaoImpl ,整个程序都没法经过编译(如图)。那么这时候就须要解耦。

compile excetion

这时候咱们的工厂模式也就出来了。

工厂模式解耦

解耦

在实际开发中,耦合是必然存在的,故只能尽可能下降依赖,不能消除。
  • 通常的解耦的思路:java

      1. 经过反射来建立对象,而避免使用 new 关键字
      1. 经过读取配置文件来获取要建立对象的全限定类名

使用配置文件

使用配置文件能够达到一个目的,就是当咱们经过一些固定不变的内容,能够把其抽取出单独保存,经过调用的方式获取其实例(跟常量类的方式无异)。
  • 建立 bean.properties 文件,保存帐户业务层实现类的路径 AccountServiceImpl 和帐户持久层接口实现类 AccountDaoImpl 信息,具体以下:
accountService=wiki.laona.service.impl.AccountServiceImpl
accountDao=wiki.laona.dao.impl.AccountDaoImpl
  • 使用反射获取相应的对象实例,具体代码以下:
/**
 * @description: Bean对象的工厂模式
 * @author: laona
 **/
public class BeanFactory {

    /**
     * Properties 对象
     */
    private static Properties props;

    /**
     * 静态代码块为 Properties 对象赋值
     */
    static {
        try {
            // 实例化对象
            props = new Properties();
            // 获取 properties 文件的流对象
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            props.load(in);
        } catch (IOException e) {
            throw new ExceptionInInitializerError("初始化 properties 文件异常!");
        }
    }

    /**
     * 获取对象实例
     * @param beanName 对象实例名
     * @return {@link Object} 对象实例
     */
    public static Object getBean(String beanName) {
        Object bean = null;
        try {
            String beanPath = props.getProperty(beanName);
            bean = Class.forName(beanPath).newInstance();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return bean;
    }
}
  • 那么这时候,帐户业务层实现类就能够这么写:
public class AccountServiceImpl implements IAccountService {

    // 经过工厂模式获取 AccountDaoImpl 的实例
    private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao");

    @Override
    public void saveAccount() {
        accountDao.saveAccount();
    }
}
  • 表现层这么写:
public class AccountDemo {

    public static void main(String[] args) {
//        IAccountService as = new AccountServiceImpl();
        IAccountService as = (AccountServiceImpl) BeanFactory.getBean("accountService");
        as.saveAccount();
    }
}
这样整个包结构就变成了这样:
new AccountDemo
  • 这时候相比以前耦合程度就大大下降了,这时候尽管删除持久层包下的实现类 AccountDaoImpl,编译是不会出错,可是没有该类是确定运行不了。编译器会报 java.lang.ClassNotFoundException 异常,而不是 Error。

总结

耦合只是相对而言,工厂模式也不是完美的,仍然存在不少能够优化的地方,可是能够减小部分耦合就是对程序性能的一个大幅度的提高。
相关文章
相关标签/搜索