避免使用命名空间进行Smurf命名类的问题


39

我从这里取消了“蓝精灵命名”一词(21号)。为了省去不熟悉的人的麻烦,Smurf命名是为一堆相关的类,变量等添加通用前缀的行为,因此您最终将“ a SmurfAccountView传递SmurfAccountDTOSmurfAccountController”,等等。

我通常听到的解决方案是创建一个smurf名称空间并删除smurf前缀。通常,这对我来说很好,但是我遇到了两个问题。

  1. 我正在与一个图书馆一起Configuration上课。它可以被调用,WartmongerConfiguration但是在Wartmonger命名空间中,因此它被称为Configuration。我同样有一个Configuration可以调用的类SmurfConfiguration,但是它在Smurf命名空间中,因此是多余的。我的代码中有些地方Smurf.Configuration出现在旁边,Wartmonger.Configuration并键入完全限定的名称比较笨拙,并且使代码的可读性较差。处理一个SmurfConfigurationand 会更好(如果这是我的代码而不是一个库)WartmongerConfiguration

  2. Service在Smurf命名空间中有一个可能称为的类SmurfServiceService是运行Smurf作业的复杂Smurf库顶部的外观SmurfService似乎是一个更好的名字,因为Service没有Smurf前缀是非常通用的。我可以接受的是,这SmurfService已经是一个通用且无用的名称,而去除蓝精灵只是使这一点更加明显。但是它本来可以命名为RunnerLauncher等等,但对我来说仍然会“感觉更好”,SmurfLauncher因为我不知道a的Launcher作用,但是我知道a的SmurfLauncher作用。您可能会争辩说a的Smurf.Launcher行为应该与a的行为一样明显Smurf.SmurfLauncher,但我可以看到`Smurf.Launcher是某种与安装相关的类,而不是启动smurfs的类。

如果有一种开放和封闭的方式来处理这两种情况,那将是很好的。如果不是,有什么常用的方法可以减轻他们的烦恼?


3
Smurf.Launcher发射蓝精灵还是发射SmurfJobs?也许可以称之为Smurf.JobLauncher
Blorgbeard

2
命名类XService,XManager等是一种代码味道。它们没有任何意义。就像一个实用程序。如果浏览的是文件名,则文件中可能有任何内容,也可能缺少任何内容。除非您向里看,否则没有办法知道。我将其从SmurfService重命名为其他名称。
丹尼尔·卡普兰

1
它确实会启动SmurfJobs,或者在技术上运行它们以与Smurf文档的语言保持一致。根据上述以及其他答案,我将重命名SmurfServiceSmurfJobRunner。似乎1号没有我预期的与语言无关的最佳解决方案。我可以看到在哪里进行SmurfConfiguration电话接听是正确的选择,但就我而言,Configuration即使遇到麻烦,我也认为最好Wartmonger.Configuration
Daniel Koverman

6
我试图理解为什么您只有一个班级,根本不关心配置Wartmongers和Smurfs。
Donal Fellows 2013年

为什么Smurf.ConfigurationSmurfConfiguration感觉不同?当然不是多余的字符了吗?(Config如果长度是问题,请缩短。)是否Smurf.Configuration有没有的问题SmurfConfiguration
Pablo H

Answers:


16

您提出了一些好点。

  1. 关于具有重复的类,可以在C#中对类进行别名。使用示例using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;请参阅StackOverflow上的这篇文章。您没有指出您的编程语言,但我是根据您所写的内容推论得出的。因此,在处理两个不同的项目时,可以将它们命名为SmurfConfigurationWartmongerConfiguration这样在使用这两个类时就可以消除歧义。

  2. 当服务暴露给外部应用程序时,我看不到使用您的应用程序名称为服务打上商标的问题,因此在这种情况下SmurfService将是有效的,因为它实际上会消除使用应用程序中的服务组的歧义。

我觉得应该使用命名空间来避免这种命名方式。不阅读MyCompanyMyProductMyAreaClassName,就更难查看代码并以其面值查看类是什么。使用别名技术可以使您在需要的地方减少歧义。正如我在第二条中指出的那样,我认为您应该在命名中引入复杂性的唯一时间是何时人们会使用服务。在这种情况下,具有这种命名方式是很有意义的,因为如果消费者拥有多种服务,那么使用这种歧义可能会造成混淆。


5
别名只会使事情变得混乱。现在有了SmurfService = Smurf.Service,而不是Smurf.Service。因此,您最好首先使用SmurfService作为事物的名称。他们有一个地方,但不适用于此特定问题。但是,它可能是对没有答案的问题的最佳答案:)
gbjbaanb 2013年

我的问题中出现了C#,但实际上我目前正在处理java和org.apache.smurfville.wartmonger.configuration。不幸的是,这排除了别名。2是很明确的一点,因此我将继续为服务使用Smurf品牌。
Daniel Koverman 2013年

25

命名空间的意义在于,您可以在不冲突的情况下拥有来自不同库的同名类。当您需要从两者使用相同的命名类时,需要通过在其名称空间范围前添加一个或两个前缀来消除歧义。

就是说,如果Smurf告诉您有关该类的一些特定知识,那么拥有一堆Smurf类并不是真的很糟糕。类名应具有足够的描述性,以便为您提供有关类功能的一些信息。

      Session
       ^   ^
      /     \
DBSession   HttpSession

类似地,a DBSession可能需要一个DBRequest返回DBResponse对象的对象。在HttpSession威力还经营上HttpRequestHttpResponse对象。

这些是有目的的蓝精灵课程。

他们可能住在MyCompany命名空间,但MyCompanyHttpSessionMyCompanyDBSession没有给你任何更多信息比你过的。在这种情况下,删除蓝精灵并使其成为名称空间。

MyCompany.HttpSession

3

我以前遇到过同样的困惑点,通常这确实是一个问题,我们是否将其名称包括在内?

您提到SmurfConfigurationWartmongerConfiguration作为潜在的配置类型。您表示已将形容词(其种类)移至其名称空间,因此剩下的只是vanilla Configuration。我会避免这样做。

这就像确定草莓冰淇淋只是草莓命名空间中的冰淇淋,以及巧克力中的冰淇淋一样,但是发生的是,您已经将赋予其标识的形容词与事物本身分开了。它不是草莓类别的冰淇淋。这是草莓冰淇淋-一种冰淇淋。

假设在您的应用中,您导入了Strawberry.IceCream类,然后直接从实例化IceCream

var ic = new IceCream(); //actually I'm strawberry ice cream

直到您最终导入另一个IceCream类之前,这似乎都很好。现在,您回到了必须以某种方式区分它们的原始问题,这是有问题的。您一直想要的是:

var sic = new StrawberryIceCream();
var cic = new ChocolateIceCream();

最好保留命名空间,以避免第三方之间可能会在其库中偶然表示相同概念的潜在冲突。但是,当一个开发人员创建一个库或项目时,他应该唯一地命名每个概念,并将命名空间用作组织的文件夹。通常,文件夹的名称可以在其组织的概念名称中找到,这没关系。


2

绝对有一个很好的经验法则:如果您在一堆类上都有一个通用前缀,那么它们可能应该放在自己的命名空间中。为了解决该问题,当您需要使用来自两个命名空间的名称相似的类时:

1)别名名称空间,尽管我会简短地说到这一点,任何自然的缩写,甚至可能只是一个字母:

using Sm = Smurf;
using W = Wartmonger;

然后总是在任何使用的地方加上前缀并适当地命名实例:

Sm::Configuration smConf; 
W::Configuration wConf;

2)别名,如其他答案所示。

using SmConf = Smurf.Configuration;

3)您可以控制的任何库,请考虑不使用术语“配置”。使用词库:例如“设置”,“模型”,“参数”。无论如何,这对于上下文来说可能更有意义:例如,如果Smurf是某种数值分析模块,那么您编写的“参数”可能对其配置会更好。利用与模块上下文相关联的特定词汇,以发挥自己的优势,即使它们混入其他命名空间中,也可以拥有保持唯一性的唯一名称。我认为这可能是OP问题2的答案。

4)重构代码,这样您就不必在两个不同的地方混合使用配置。具体细节由您决定。

5)在将其传递给班级之前,将这两种配置组合为一个。使用组合的conf类来表示:

struct Conf {
    SmurfConfiguration smurf;
    WartmongerConfiguation wart;
}

短成员变量名称现在可以实现与别名类/命名空间相同的功能。


0

奇怪的是,在名称上加一分会打扰您。

Wartmonger.Configuration configuration = Wartmonger.Configuration .new();

// vs

WartmongerConfiguration configuration = WartmongerConfiguration.new();

如果将两者SmurfWartmonger配置一起使用在一个地方,但是将它们分开用于多个地方,那么命名空间绝对是个好方法。

具有名称空间将使在内部代码中使用“干净”名称的可能性成为可能,在这些前缀中,您最终会使用SmurfConfiguration内部SmurfService的内部代码,这在每次打开该代码时都会变得很烦人。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.