【问题标题】:Single Responsibility Principle and Service/Repository design单一职责原则和服务/存储库设计
【发布时间】:2015-12-15 10:27:01
【问题描述】:

我想知道如何在以下示例中最好地分离职责。

有一个Foo 对象,它有一些id 和一些reallySecretImportantData 字段。 Id 是用于引用对象的简单标识符,而reallySecretImportantData 是应该在数据库中加密的数据,因为数据库是本示例中唯一的漏洞点。

现在,如果我们有一个带有方法 void storeFoo(Foo foo)Foo readFoo(Id id)FooService

我们还有一个 FooRepository,它具有标准 CRUD 方法,可将 Foo 对象存储在数据库中。

现在,由于我想加密保存reallySecretImportantData,我必须在某处加密并在某处解密。

由于FooRepositorys 的职责不应该包括加密操作,逻辑位置是FooService

现在,如果我在某个开发环境中,出于开发和测试目的,我希望将 reallySecretImportantData 保存为纯文本。

如果我使用某种 DI,我可以编写我的服务的 2 个实现,一个用于生产,另一个用于开发/测试,只需将 DI 配置为在生产环境中使用产品,在开发和测试环境中使用开发/测试。

现在,如果在不久的将来出现更改 reallySecretImportantData 存储方式的请求,我可以简单地编写该服务的另一个实现并使用我的 DI 框架注入它。

这个简单的设计对于当前的模型案例是否足够好?

【问题讨论】:

    标签: java oop encryption single-responsibility-principle


    【解决方案1】:

    你的设计让我想起了strategy pattern. FooService 可以被认为是一个策略界面。

    但是我更喜欢在这个接口中添加encrypt()decrypt()方法而不是store()read()。我们可以将其命名为FooCryptoStrategy

    此外,FooRepository 可以用FooCryptoStrategy 对象构造。 因此,您可以 CRUD Foo 不涉及加密问题的对象。 您可以为发布和测试创建多个FooCryptoStrategy 实现。甚至你也可以实现NonCryptoStrategy

    总之,使用策略模式,我们可以为一个类分配一项职责:
    Foo:存储数据
    FooCryptoStrategy:加密和解密Foo对象
    FooRepository:制作Foo 对象持久化。
    控制器类:创建具体的FooCryptoStrategyFooRepository 对象。

    【讨论】:

      【解决方案2】:

      为什么需要“服务”?

      考虑一个知道如何加密/解密/加密的Secret 对象,以及一个处理持久性的数据管理对象。

      通过使用通用接口实现加密算法,使您的功能“可插入”,例如加密。因此,例如,您可能有一个 AesEncryptor 和一个 TestPlainEncryptor

      // simple non-dependency-injection example    
      Secret encrypted = new Secret(new AesEncryptor, "key", "my secret stuff");
      new SecretDM().Save(s);
      
      Secret retrieved = new SecretDM().Get("key");
      // println(retrieved.Decrypt());
      

      【讨论】:

      • 好吧,手头的问题是我无法更改数据库架构。另一个问题是,鉴于您的解决方案,我应该以某种方式保留 IEncrypt 接口的实例,这不是我想要的,我也不确定这是一个好的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2012-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 2010-11-26
      • 2016-07-31
      相关资源
      最近更新 更多