前言
看《架构整洁之道》之前 ,依赖翻转理解: 依赖于抽象,而不是依赖于实现。
抽象:比如水果店Apple、Banana,抽象个水果接口 IFruit,用 IFruit 接口去做一些操作。
正文
抽象出接口,是一种战术操作(具体的操作)。但为什么这么操作呢?
OK,我们从 构建 这个战略层次看下。
内容简述:
- 多个组件的循环依赖,导致多个组件实际在部署上是一个组件。
- 为了 消除 循环依赖,我们需要依赖变成单向
- 依赖变为单向,可以通过依赖翻转实现
循环依赖
- 如果 Fruit库依赖于 SaleMachine库,SaleMachine库依赖于 Fruite库。(构建版本号指定上)
- Fruit库升级到v2.0,因为SaleMachie v1.0依赖 Fruit库v1.0。那App需要 v1.0,v2.0 的Fruit库,依赖冲突
- 为了解决依赖冲突,SaleMachine升级到 v2.0,依赖于 Fruit 库v2.0, 冲突修复。
如上反之亦然,Fruit库和SaleMachine库 在构建、发包角度,已经是一个库了。升级一个,两个都得升级。
// Fruit 库
public interface IFruit {
double weight;
double name;
double unitPrice; //单价
}
public Apple implement IFruit {
import SaleMachine;
void showWeight() {
double weight = (new WeightMachine().getWeight(this))
print(weight);
}
// SaleMachine 库
import IFruit;
public class SaleMachine {
public void sale(IFruit fruit) {
int price = fruit.weight * fruit.unitPrice
代码中 Apple这个类 依赖了SaleMachine。
SaleMachine 这个类有依赖了IFruit.
消除循环依赖
抽象出接口,将两个库隔离。主组件(main)负责具体类的注入。
// Fruit 库
/// 苹果店需要的machine
interface IFruitStoreMachine {
double getWeight(IFruit);
}
public Apple implement IFruit {
void showWeight(IFruitStoreMachine fruitMachine) {
weight = (fruittMachine.getWeight(this))
}
// Machine 库内
interface IGoods {
String getName();
}
interface IWeightMachine {
double getWeight(IGoods goods);
}
public calss WightMachine implement IFruitStoreMachine {
@Override
double getWeight(IFruit fruit) {
//...
}
// Main库
public class FruitMachineAdapter implement IFruitStoreMachine {
private IWeightMachine weightMachien;
public FruitMachineAdapter(IWeightMachine weightMachien) {
this weightMachien = weightMachien;
}
@Override
double getWeight(final IFruit fruit) {
return weightMachien.getWeight(new IGoods() {
@Override
String getName() {
return fruit.name;
}
}
}
}
public class AppleStore {
public static void main(String[] args) {
IFruit apple = new Apple();
apple.showWeight(new FruitMachineAdapter(new WeightMachine()));
}
Machine库与Fruit 用接口隔离,main组件再通过 Adapter适配器模式(我更喜欢叫 转接头模式),将Machine库的机器 转化为 Fruit库需要的机器接口。
Fruit对Machine库的依赖方向发生了 偏转,由依赖于machine仓库,变为依赖了Fruit内的抽象接口。
而Machine库页断开了依赖。 具体的实现类,在main组件中生成、赋值(也就是配置)
好处
Fruit库、Machine库可以单独 部署、编译、发版
写的不是很好,这篇文章的目的是 抽离于 依赖翻转的实现上,而是从组件 部署的角度去看待这件事。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)