指导尴尬的领域特定对象的命名?


12

我正在为化学系统建模,但是在枚举中命名元素/项目时遇到了问题。

我不确定是否应该使用:

  • 原子公式
  • 化学名称
  • 化学名称的缩写。

例如,硫酸是H2SO4,盐酸是HCl。

对于这两个,我可能会只使用原子公式,因为它们相当普遍。

但是,我还有其他类似Na2SiF6的六氟硅酸钠。

在该示例中,原子式(对我而言)不那么明显,但化学名称长得令人毛骨悚然: myEnum.SodiumHexaFluoroSilicate。我不确定如何才能安全地提出一个具有一致命名模式的缩写化学名称。

我正在尝试通过命名枚举元素来解决一些问题。
首先是可读性,较长的名称会带来问题。
第二个问题是为新的维护者挑选代码很容易,在这里较短的名字带来了问题。
下一个问题是企业主通常使用完整的化学名称,但并非总是如此。“鲜味”化学物质由其化学式表示。
最后要考虑的是确保其一致性。我不需要混合的命名约定,因为将无法记住要使用的命名约定。

从维护的角度来看,您希望查看上述哪个命名选项,为什么?


注意:该行下面的所有内容都是补充| 澄清材料。请不要陷入其中。主要问题涉及命名尴尬的对象。

原子选项

公共myEnum.ChemTypes
{  
   硫酸
   盐酸
   Na2SiF6
}

化学名称选项

公共myEnum.ChemTypes
{
   硫酸
   盐酸,
   六氟硅酸钠  
}

以下是有关此问题的评论中的一些其他详细信息:

  • 代码的受众只是程序员,而不是化学家。
  • 我正在使用C#,但是我认为在忽略实现语言时,这个问题会更有趣。
  • 我从10-20种化合物开始,最多可以有100种化合物,因此我不必担心每种可能的化合物。幸运的是,这是一个固定域。
  • 枚举用作查找的关键字,以方便进行常规/通用化学计算-这意味着所有化合物的方程式均相同,但您插入化合物的属性即可完成方程式。

示例函数可能类似于:

公共double GetMolesFromMass(double mass_grams,myEnum.ChemTypes chem)
{
  double moleWeight = MolarWeightLookupFunctionByChem(chem); //返回克/摩尔
  双摩尔=质量/摩尔重量; //转换为痣

  返回痣
}

//示例通话:
myMoles = GetMolesFromMass(1000,myEnum.ChemTypes.Na2SiF6);
//*要么*
myMoles = GetMolesFromMass(1000,myEnum.ChemTypes。六氟硅酸钠);
公共double GetSpecificGravity(myEnum.ChemTypes chem,double conc)
{
  //根据浓度回收化合物的比重
  double sg = SpecificGravityLookupTableByChem(chem,conc);  
}

因此,化合物名称的枚举用作键,并在引用具有相关功能的化合物时保持一致性。


7
为什么他们需要成为枚举?化合物的数量是无限的,所以您将永远无法设置它们
棘手怪胎

3
作为程序员而不是化学家,我发现Na2SiF6六氟硅酸钠同样晦涩难懂。前者的类型较短,最有可能通过不超过40个字符的标识符编码规则。
mouviciel

5
作为程序员,我个人认为Sodium比Na2滑落的速度更快-键入时单词对我来说更容易流淌(出于这个原因,我讨厌匈牙利符号)。
德雷克·克拉里斯(Decke Clarris)2012年

5
它们不应该是枚举值,而应该是Substance具有所需属性的实例。
AakashM

2
@ GlenH7:只需阅读有关“元”的问题即可。我认为对于某些人来说,这里真正的问题是“为什么化学名称必须全部包含在代码中”?仅将这些名称用作某种形式的数据可以避免使用很长的名称使代码混乱,并且您可以像系统用户所喜欢的那样选择名称,而不受开发人员的考虑。这样可以将命名职责委托给用户,从而完全避免您的问题。
Doc Brown

Answers:


9

当我开始将我当前的项目从意大利面条重写为合理的代码时,我遇到了同样的问题。我的问题领域是医学领域,我没有使用像“ ETCO2”和“ SPO2”这样的名称作为枚举,而是使用了完整的英文名称。

一方面,当我刚接触问题域时,使用英文名称非常有用。另一方面,既然我已经使用这些术语一年了,我发现英文全名太冗长了,而且我对这些术语已经非常熟悉,因此我更喜欢使用缩写。

我的建议是使用原子公式,并在每个枚举值中加上一个给出其全名的注释,前提是任何看您代码的人都将是a)化学家,或b)在代码上工作足够长的时间他们自然会熟悉该公式。


1
+1:此外,您始终可以查找“ ETCO2”或“ Na2SiF6”并完成操作。
史蒂文·埃弗斯

5

谁是该代码的受众?化学家会使用Enums,还是只使用没有经过化学领域特定培训的程序员?

如果化学家会使用该密码,请询问他们。他们很可能会喜欢缩写符号,因为他们可以轻松识别它们。如果一般知识的程序员将代表化学家使用这些标识符,我认为最好使用类似英语的版本。


这将只是程序员,而不是化学家

1
或在每个枚举的文档中添加翻译
棘手怪胎

4

没有理由不将“以上所有内容”结合在一起。

全名的问题是键入会很麻烦,符号名的问题缺乏含义。

因此,请使用全名创建值的常量。然后创建与该常量关联的定义。当您对缩写的含义更加熟悉时,便可以轻松地创建更新,更短的定义。

const int SodiumHexaFluoroSilicate = 16893859;   
const float Gold = 196.966569;

#define SoduimSilicate SodiumHexaFluoroSilicate 
#define F6Na2Si SodiumHexaFluoroSilicate 
#define au Gold 

我使用了一些乏味的C代码示例...我认为它应该足够容易地转换为C#。
丹尼尔(Daniel)

我不担心特定的实现,这就是为什么我在问题中未指定C#的原因。从C的角度来看,我很喜欢您的建议。但是,System.ComponentModel中的C#Description标签是添加描述符的一种优雅方式。我对某个特定实现中对该问题的更广泛回答更感兴趣。

3

设计任何应用程序时,应将数据与程序逻辑分开。化学化合物确实是程序逻辑的一部分,而不是程序逻辑所操作的数据吗?

当它们是数据时,最好不要将它们视为枚举,而是从配置文件中读取它们的名称和属性,并将其存储在数据结构中会更好。这也将使维护变得容易得多。当需要添加新化合物或发现一种化合物的错误时,他们只需编辑配置文件即可。


1
+1 @ GlenH7,如果您可以解释为什么特定的化学成分是代码的一部分,这将很有帮助,尤其是当您说“方程式对所有化合物都相同”之后。
Caleb

1
@ GlenH7:仍然没有理由不只是化学数据。多个海报有助于告诉您不要使用枚举。我当然不会。
凯文·克莱恩

1
@kevincline&caleb(实际上还有其他所有人),我创建了一个元问题,以寻求有关如何构造此问题及其枚举方面的帮助。非常感谢您的反馈。

3
好吧,当有人用刀卡在你头上来找你,他要你看着他手中的碎片时,很难专心于此。
菲利普

1
@Caleb-更新问题以更好地阐明枚举的用法。

3

似乎可以将其更好地实现为可以根据开发人员的需求进行扩展和翻译的类。以下是一些我想出的示例C#,它允许使用一些众所周知的定义化学品(作为属性),然后允许查询存储(via AddGet方法)。您还可以轻松扩展以提供您的摩尔质量和其他化学性质。

public interface IChemical
{
    string AtomicFormula
    {
        get;
    }

    string ChemicalName
    {
        get;
    }

    string AbbreviatedChemicalName
    {
        get;
    }
}

public sealed class Chemical : IChemical
{
    private static readonly IChemical h2so4 = new Chemical("H2SO4", "sulfuric acid", "sulf. acid");

    private static readonly IChemical hcl = new Chemical("HCl", "hydrochloric acid", "hydro. acid");

    private static readonly IDictionary<string, IChemical> chemicalsByAtomicFormula = new Dictionary<string, IChemical>();

    private static readonly IDictionary<string, IChemical> chemicalsByChemicalName = new Dictionary<string, IChemical>();

    private static readonly IDictionary<string, IChemical> chemicalsByAbbreviatedChemicalName = new Dictionary<string, IChemical>();

    private readonly string atomicFormula;

    private readonly string chemicalName;

    private readonly string abbreviatedChemicalName;

    static Chemical()
    {
        chemicalsByAtomicFormula.Add(h2so4.AtomicFormula, h2so4);
        chemicalsByChemicalName.Add(h2so4.ChemicalName, h2so4);
        chemicalsByAbbreviatedChemicalName.Add(h2so4.AbbreviatedChemicalName, h2so4);
        chemicalsByAtomicFormula.Add(hcl.AtomicFormula, hcl);
        chemicalsByChemicalName.Add(hcl.ChemicalName, hcl);
        chemicalsByAbbreviatedChemicalName.Add(hcl.AbbreviatedChemicalName, hcl);
    }

    public Chemical(string atomicFormula, string chemicalName, string abbreviatedChemicalName)
    {
        if (string.IsNullOrWhiteSpace(atomicFormula))
        {
            throw new ArgumentException("Atomic formula may not be null or whitespace.", "atomicFormula");
        }

        if (string.IsNullOrWhiteSpace(chemicalName))
        {
            throw new ArgumentException("Chemical name may not be null or whitespace.", "chemicalName");
        }

        if (string.IsNullOrWhiteSpace(abbreviatedChemicalName))
        {
            throw new ArgumentException("Abbreviated chemical name may not be null or whitespace.", "abbreviatedChemicalName");
        }

        this.atomicFormula = atomicFormula;
        this.chemicalName = chemicalName;
        this.abbreviatedChemicalName = abbreviatedChemicalName;
    }

    public static IChemical H2SO4
    {
        get
        {
            return h2so4;
        }
    }

    public static IChemical HCl
    {
        get
        {
            return hcl;
        }
    }

    public string AtomicFormula
    {
        get
        {
            return this.atomicFormula;
        }
    }

    public string ChemicalName
    {
        get
        {
            return this.chemicalName;
        }
    }

    public string AbbreviatedChemicalName
    {
        get
        {
            return this.abbreviatedChemicalName;
        }
    }

    public static void AddChemical(IChemical chemical)
    {
        if (chemical == null)
        {
            throw new ArgumentNullException("chemical", "chemical may not be null");
        }

        if (chemicalsByAtomicFormula.ContainsKey(chemical.AtomicFormula))
        {
            return;
        }

        chemicalsByAtomicFormula.Add(chemical.AtomicFormula, chemical);

        if (chemicalsByChemicalName.ContainsKey(chemical.ChemicalName))
        {
            return;
        }

        chemicalsByChemicalName.Add(chemical.ChemicalName, chemical);

        if (chemicalsByAbbreviatedChemicalName.ContainsKey(chemical.AbbreviatedChemicalName))
        {
            return;
        }

        chemicalsByAbbreviatedChemicalName.Add(chemical.AbbreviatedChemicalName, chemical);
    }

    public static IChemical GetChemicalByAtomicFormula(string atomicFormula)
    {
        if (string.IsNullOrWhiteSpace(atomicFormula))
        {
            throw new ArgumentException("Atomic formula may not be null or whitespace.", "atomicFormula");
        }

        IChemical chemical;

        return chemicalsByAtomicFormula.TryGetValue(atomicFormula, out chemical) ? chemical : null;
    }

    public static IChemical GetChemicalByChemicalName(string chemicalName)
    {
        if (string.IsNullOrWhiteSpace(chemicalName))
        {
            throw new ArgumentException("Chemical name may not be null or whitespace.", "chemicalName");
        }

        IChemical chemical;

        return chemicalsByChemicalName.TryGetValue(chemicalName, out chemical) ? chemical : null;
    }

    public static IChemical GetChemicalByAbbreviatedChemicalName(string abbreviatedChemicalName)
    {
        if (string.IsNullOrWhiteSpace(abbreviatedChemicalName))
        {
            throw new ArgumentException("Abbreviated chemical name may not be null or whitespace.", "abbreviatedChemicalName");
        }

        IChemical chemical;

        return chemicalsByAbbreviatedChemicalName.TryGetValue(abbreviatedChemicalName, out chemical) ? chemical : null;
    }
}

您可以添加新的化学物质,例如:

        Chemical.AddChemical(new Chemical("Na2SiF6", "sodium hexafluorosilicate", "sod. hex.flu.sil."));

并获得其他位:

        Console.WriteLine(Chemical.GetChemicalByChemicalName("sulfuric acid").AtomicFormula);

感谢您的回答,我已经更新了我的问题,使我的定位更加明确。我不必担心要获取化合物的名称,因为我可以从各种表格等中访问其属性。我有一个开放的元问题就是否我应该在枚举讨论添加或打破到一个单独的Q.
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.