避免模​​块之间的依赖

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。