绪论
最近使用 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 ,整个程序都无法通过编译(如图)。那么这时候就需要解耦。
这时候我们的工厂模式也就出来了。
工厂模式解耦
解耦
在实际开发中,耦合是必然存在的,故只能尽量降低依赖,不能消除。
-
一般的解耦的思路:
- 通过反射来创建对象,而避免使用 new 关键字
- 通过读取配置文件来获取要创建对象的全限定类名
使用配置文件
使用配置文件可以达到一个目的,就是当我们通过一些固定不变的内容,可以把其抽取出单独保存,通过调用的方式获取其实例(跟常量类的方式无异)。
- 创建 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();
}
}
这样整个包结构就变成了这样:
- 这时候相比之前耦合程度就大大降低了,这时候尽管删除持久层包下的实现类 AccountDaoImpl,编译是不会出错,但是没有该类是肯定运行不了。编译器会报 java.lang.ClassNotFoundException 异常,而不是 Error。
总结
耦合只是相对而言,工厂模式也不是完美的,仍然存在很多可以优化的地方,但是可以减少部分耦合就是对程序性能的一个大幅度的提升。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。