【问题标题】:Naming convention for IoC intended interfacesIoC 预期接口的命名约定
【发布时间】:2018-03-15 16:01:16
【问题描述】:

当您使用 IoC 框架时,您最终会专门为 IoC 而创建接口。我很想为这些使用命名约定。

例如,在图片上没有 IoC 的情况下,您可能有以下业务领域驱动的结构:

interface IBodyPart
{
    string ScientificName { get; set; }
    string StreetName { get; set; }
}

class Head : IBodyPart
{
    public string ScientificName { get; set; }
    public string StreetName { get; set; }
}

class BodyPartPoker
{
    bool isSituationAcademic;
    BodyPartPoker(bool isSituationAcademic)
    {
        this.isSituationAcademic = isSituationAcademic;
    }

    void Poke(IBodyPart bodyPart)
    {
        if (this.isSituationAcademic)            
            Debug.Print($"Proceeding to poke {bodyPart.ScientificName}");            
        else            
            Debug.Print($"Poking that {bodyPart.StreetName} LOL");
    }
}

现在假设您想使用 IoC 注入 BodyPartPoker 实例。您还想使用某种单元测试模拟框架来测试该逻辑。

在这种情况下,即使你没有业务领域的案例,你也会引入IBodyPartPoker接口:

interface IBodyPartPoker
{
    bool IsSituationAcademic { get; set; }
    void Poke(IBodyPart bodyPart);
}

class BodyPartPoker : IBodyPartPoker
{

我的问题是:为IBodyPartPoker 之类的接口制定命名约定是否有意义,因此我们明确确定它的目的是不与业务域相关?

说....

interface IIocBodyPartPoker

【问题讨论】:

  • 我会说这样做没有多大意义。

标签: c# unit-testing oop mocking inversion-of-control


【解决方案1】:

在 C# 中,约定通常是利用语言的惯用命名约定,并使用前面的I 命名接口,如IBodyPartPoker。这使得 BodyPartPoker 可以免费作为类的名称。

在 Java 中,约定是不使用匈牙利符号命名接口,因此该接口通常命名为 BodyPartPoker,这通常会导致人们将其单个类命名为 BodyPartPokerImp

您应该将其视为代码异味,正是因为该接口存在的唯一原因似乎是启用单元测试。你可以说它违反了Reused Abstractions Principle

给接口取另一个名字,比如IIocBodyPartPoker,并不能解决根本问题。

如果存在专门用于支持单元测试的接口,您很可能会发现测试与实现细节过于耦合,并且每次尝试重构生产代码时,测试都会中断。同样,命名约定不会解决此类问题。

【讨论】:

  • 我已经感觉到这是一种代码味道,但是,我在一个这样说可能会引起争议的环境中工作。我在那种工作环境中相当新,所以除非我有一个非常有力的案例,否则我会尝试按照现有的做法进行操作。我的团队和在线协议的看法是,大多数 人不介意仅仅为了 IoC 而创建界面。现在对我来说,挑战是 PoC 是我团队代码的重构版本,它不引入接口只是因为同时工作......同时对单元测试友好。谢谢。
猜你喜欢
  • 2016-12-15
  • 2010-10-15
  • 2014-12-07
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 2014-04-30
  • 1970-01-01
相关资源
最近更新 更多