【问题标题】:Refactoring implementation of multiple classes having common code (With DI)重构具有公共代码的多个类的实现(使用 DI)
【发布时间】:2017-01-03 06:49:41
【问题描述】:

我在 1 个大系统中有多个子系统。所以每个子系统都有自己的 BAL 和 DAL 实现。现在 BAL(s) 具有重要的逻辑,但 DAL 基本上具有相似的代码,因此我将其重构为一个通用 DAL 类,该类现在用于所有子系统。像这样的:

假设子系统名称为 A 和 B

public class DalA
{
    private IGenericDal genericDal;

    public DalA( IGenericDal injectedGenericDal)
    {
        this.genericDal = injectedGenericDal;
    }

    public bool DoSomeDBWorkForA()
    {
        return genericDal.CommonDalMethod();
    }
}


public class DalB
{
    private IGenericDal genericDal;

    public DalB(IGenericDal injectedGenericDal)
    {
        this.genericDal = injectedGenericDal;
    }

    public bool DoSomeDBWorkForB()
    {
       return genericDal.CommonDalMethod();
    }
}

现在,从单元测试的角度来看,注入通用 DAL 的 DI 部分很重要,因此 BAL(s) 必须注入通用 DAL 对象。因此,现在 BAL 仅仅因为重构和 DI 要求而不必要地了解通用 DAL 对象,理想情况下它不应该这样做(特别是在重构的情况下)。

我的一位朋友还指出,子系统 A 和 B 的 DAL 什么都不做,所以我们可能应该摆脱它们并调用通用 DAL 本身,但我认为它降低了灵活性,因为明天 A 的 DAL可能想要做一些 B 甚至 C 可能不会订阅的日志记录或其他一些特殊操作。

那你们觉得呢?有没有人有更好的重构实现,其中 DI、关注点分离(即 A 的 BAL 只知道 A 的 DAL 而不是通用 DAL 对象)和灵活性(所有子系统具有不同的 DAL)是完整的。

我想到的一种方法是在 A 和 B 的 DAL 中有 2 个构造函数,这样我们就可以在不注入通用 DAL 的情况下从 BAL 调用,而从单元测试中我可以注入通用 DAL 对象。

【问题讨论】:

  • 恕我直言,在一个系统(解决方案)中拥有多个子系统是错误的,这些子系统具有系统的所有部分;使用微服务是更好的主意,或者将子系统更改为模块;)。
  • @shA.t 这是一个很好的建议,但在这种情况下,我无法承受由于微服务实施而增加的延迟;)那么在这种情况下,您有什么建议呢?

标签: c# oop dependency-injection


【解决方案1】:

子系统 A 和 B 的 DAL 什么都不做,所以我们可能应该摆脱它们并调用通用 DAL 本身,但在我看来它降低了灵活性,因为明天 A 的 DAL 可能想要做一些日志记录或一些B 甚至 C 可能不会订阅的其他特殊操作。

类应该是open for extension but closed to modification。这意味着添加日志记录并不意味着您需要更改 A 的 DAL。您应该能够通过创建包装通用 DAL 的装饰器来做到这一点。其他横切关注点也是如此。

因此,这种灵活性并不是 IMO 保留额外间接层的有力论据。

【讨论】:

  • 所以你说暂时删除中间 DAL(s) 是要走的路,修改应该通过装饰器处理,但你不认为世界各地的 DAL(s)很少处理很多逻辑,所以从更广泛的意义上说,不应该总是(或至少经常)以这种方式设计 DAL,因为大多数应用程序都有多个模块(因此有多个 DAL)要处理?跨度>
  • @RachitPandey:是的,考虑到提供的信息,我建议删除中间层。我无法真正评论“DAL(s) across the world”是如何设计的,因为有太多的共同口味。
  • 我同意现在移除中间层,但会有一个异常情况,我希望您能考虑一下。如果我直接从 BAL 调用通用 DAL,那么我确实需要提供一些“DAL 特定参数”,例如 SP 名称等,我认为 BAL 不应该真正意识到这些。此外,我无法从通用 DAL 中删除这些参数以使其保持通用。
  • @RachitPandey 如果您需要从 BAL 提供这些参数,这意味着您的 DAL 正在泄漏实现细节。换句话说,你的 DAL 是一个泄漏的抽象。这些值应该封装在您的 DAL 中。
  • @RachitPandey:好吧,如果通用 DAL 实现与具有不同架构的不同存储过程进行对话(反对在具有确切架构的多个数据库中调用相同的 SP),这表明您确实需要多重抽象。否则你将违反Liskov Substitution Principle
猜你喜欢
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-09
相关资源
最近更新 更多