避免模块之间的依赖
Avoid dependencies between modules
为了这个问题,假设我有一个加密模块 opensslCryptographicModule
,它具有以下方法:
public String encrypt(String content, String key);
public String decrypt(String encrypted, String key);
还有一个模块,我们称它为 MainModule
,它需要一个加密模块才能工作。
由于MainModule
中使用的密码模块可能会改变我创建了一个接口如下:
public interface CryptographicModule {
public String encrypt(String content, String key);
public String decrypt(String encrypted, String key);
}
并且 MainModule
在其构造函数中采用 CryptographicModule
。
我的问题是如何保持加密模块完全独立?
如果我将接口放在 MainModule
中,那么 opensslCryptographicModule
将需要实现在其他项目中声明的接口,因此将依赖于该项目。
但是如果我将接口放在 opensslCryptographicModule
中,那么其他加密模块将需要 opensslCryptographicModule
来获取接口。
我能看到的唯一解决方案是第三个模块,它将在两个模块之间形成 link。
它将使用适配器模式实现接口(将在 MainModule 中)以提供加密模块的功能:
public class OpenSSLCryptographicModuleAdapter implements CryptographicModule {
private OpensslCryptographicModule module;
public OpenSSLCryptographicModuleAdapter(OpensslCryptographicModule module) {
this.module = module
}
@Override
public String encrypt(String content, String key) {
//...
}
@Override
public String decrypt(String encrypted, String key) {
//...
}
}
并且 MainModule
将依赖这第三个模块来工作。
但我觉得这有点矫枉过正,尤其是当我们控制了所有模块时。这种设计模式在使用第三方库或我们想使用一些旧代码时非常有用,但在编写整个项目时就不行了。
您的分析是正确的,包括您声明这可能有点矫枉过正的部分。
这是人们经常错过的 "design patterns" 的基本部分。有时,应用模式(解耦等)的好处不会超过成本(通常是 "complexity")。
工程的一部分是弄清楚权衡是否值得。
三个模块可能是个好主意,或者对您的情况来说可能有点矫枉过正;这实际上取决于您项目的具体情况。从更简单的设置开始可能是个好主意,然后在您发现适当的抽象位置时再考虑接口。不可能给这样的事情一个通用的规则。
您可以创建 OpenSSLCryptographicModule 和抽象 class,并创建加密和解密抽象方法。那么对于每个实现,您将只有一个基本抽象 class 和另一个具体 class。
为了这个问题,假设我有一个加密模块 opensslCryptographicModule
,它具有以下方法:
public String encrypt(String content, String key);
public String decrypt(String encrypted, String key);
还有一个模块,我们称它为 MainModule
,它需要一个加密模块才能工作。
由于MainModule
中使用的密码模块可能会改变我创建了一个接口如下:
public interface CryptographicModule {
public String encrypt(String content, String key);
public String decrypt(String encrypted, String key);
}
并且 MainModule
在其构造函数中采用 CryptographicModule
。
我的问题是如何保持加密模块完全独立?
如果我将接口放在 MainModule
中,那么 opensslCryptographicModule
将需要实现在其他项目中声明的接口,因此将依赖于该项目。
但是如果我将接口放在 opensslCryptographicModule
中,那么其他加密模块将需要 opensslCryptographicModule
来获取接口。
我能看到的唯一解决方案是第三个模块,它将在两个模块之间形成 link。
它将使用适配器模式实现接口(将在 MainModule 中)以提供加密模块的功能:
public class OpenSSLCryptographicModuleAdapter implements CryptographicModule {
private OpensslCryptographicModule module;
public OpenSSLCryptographicModuleAdapter(OpensslCryptographicModule module) {
this.module = module
}
@Override
public String encrypt(String content, String key) {
//...
}
@Override
public String decrypt(String encrypted, String key) {
//...
}
}
并且 MainModule
将依赖这第三个模块来工作。
但我觉得这有点矫枉过正,尤其是当我们控制了所有模块时。这种设计模式在使用第三方库或我们想使用一些旧代码时非常有用,但在编写整个项目时就不行了。
您的分析是正确的,包括您声明这可能有点矫枉过正的部分。
这是人们经常错过的 "design patterns" 的基本部分。有时,应用模式(解耦等)的好处不会超过成本(通常是 "complexity")。
工程的一部分是弄清楚权衡是否值得。
三个模块可能是个好主意,或者对您的情况来说可能有点矫枉过正;这实际上取决于您项目的具体情况。从更简单的设置开始可能是个好主意,然后在您发现适当的抽象位置时再考虑接口。不可能给这样的事情一个通用的规则。
您可以创建 OpenSSLCryptographicModule 和抽象 class,并创建加密和解密抽象方法。那么对于每个实现,您将只有一个基本抽象 class 和另一个具体 class。