程序的耦合与解耦

耦合:程序间的依赖关系,包括

  • 类之间的依赖
  • 方法间的依赖

解耦:降低程序间的依赖关系

实际开发时应做到

编译器不依赖,运行时才依赖

解耦的思路

  1. 使用反射来创建对象,避免使用new对象
  2. 通过读取配置文件来获取要创建的对象的全限定类名

如下演示工程,即为耦合性较强的

结构.png

public class controller {
    public static void main(String[] args) {
        //演示
        AccountService accountService = new AccountServiceImpl();
        accountService.saveAccount();
    }
}
public class AccountServiceImpl implements AccountService {
    AccountDao accountDao = new AccountDaoImpl();

    public void saveAccount() {
        accountDao.saveAccount();
    }
}
public class AccountDaoImpl implements AccountDao {
    public void saveAccount() {
        System.out.println("保存了账号");
    }
}

我们可以看到,一层调用一层,并且每次都使用了new,假如某个类在其中出现了问题,那么会导致无法编译,各个类之间的依赖性极强。

使用工厂模式解耦

Bean

英语中,有可重用组件的意思

JavaBean

用Java编写的可重用组件,且Java Bean > 实体类

建立工厂类,如下

package com.oylong.factory;

import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class BeanFactory {
    private static Properties properties;

    private static Map<String, Object> beans;

    static {
        properties = new Properties();

        try {
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            properties.load(in);
            beans = new HashMap<String, Object>();
            Enumeration keys = properties.keys();

            //单例
            while (keys.hasMoreElements()) {
                String key = keys.nextElement().toString();
                String path = properties.getProperty(key);

                Object value = Class.forName(path).newInstance();
                beans.put(key, value);
            }
        } catch (Exception e) {
            throw new ExceptionInInitializerError("初始化properties出错");
        }
    }

    public static Object getBean(String baseName) {
        return beans.get(baseName);
    }
}

这里使用了单例和反射,我们通过类名去创建了对应的实例,并且将其保存在HashMap中,以供下次使用的时候继续调用。

  • bean.propertise的内容
    accountService=com.oylong.service.impl.AccountServiceImpl
    accountDao=com.oylong.dao.impl.AccountDaoImpl

    使用如下:

    public static void main(String[] args) {
          //演示
          AccountService accountService = (AccountService) BeanFactory.getBean("accountService");
          accountService.saveAccount();
      }
AccountDao accountDao = (AccountDao) BeanFactory.getBean("accountDao");

public void saveAccount() {
    accountDao.saveAccount();
}

我们直接通过beanFactory来创建,改善之后,就算我们将其中的某个类去掉,我们还是能正常编译(运行时当然还是会异常)。极大的降低了类间的依赖性。

最后修改:2020 年 03 月 24 日
如果觉得我的文章对你有用,请随意赞赏