Anleitung zum Benennen umständlicher domänenspezifischer Objekte?

12

Ich modelliere ein chemisches System und habe Probleme mit der Benennung meiner Elemente / Gegenstände innerhalb einer Aufzählung.

Ich bin mir nicht sicher, ob ich verwenden soll:

  • die Atomformel
  • der chemische Name
  • ein abgekürzter chemischer Name.

Beispielsweise ist Schwefelsäure H 2 SO 4 und Salzsäure ist HCl.

Bei diesen beiden würde ich wahrscheinlich nur die Atomformel verwenden, da sie ziemlich häufig sind.

Ich habe jedoch andere wie Natriumhexafluorsilicat, das Na2SiF6 ist.

In diesem Beispiel ist die atomare Formel nicht so offensichtlich (für mich) , aber der chemische Name ist abscheulich lang: myEnum.SodiumHexaFluoroSilicate. Ich bin mir nicht sicher, wie ich in der Lage sein könnte, einen abgekürzten chemischen Namen zu finden, der ein einheitliches Namensmuster aufweist.

Es gibt einige Probleme, die ich durch die Benennung der Enum-Elemente beheben möchte.
Die erste ist die Lesbarkeit, wobei die längeren Namen ein Problem darstellen.
Die zweite ist, dass es für neue Betreuer einfach ist, den Code zu finden, und hier stellen die kürzeren Namen ein Problem dar.
Das nächste Problem ist, dass Geschäftsinhaber normalerweise auf den vollständigen chemischen Namen verweisen, aber nicht immer. Die "Bissen" -Chemikalien werden durch ihre Formel bezeichnet.
Das letzte Anliegen ist es, sicherzustellen, dass es konsistent ist. Ich bin keine gemischte Namenskonvention, da es unmöglich sein wird, sich zu erinnern, welche ich verwenden soll.

Welche der oben genannten Benennungsoptionen würden Sie unter Wartungsgesichtspunkten bevorzugen und warum?


Hinweis: Alles, was hier unter der Zeile steht, ist eine Ergänzung klärendes Material. Bitte lassen Sie sich nicht darin festsitzen. Die Hauptfrage betrifft die Benennung der umständlichen Objekte.

Atomic Option

public myEnum.ChemTypes
{  
   H2SO4,
   HCl,
   Na2SiF6
}

Chemische Namensoption

public myEnum.ChemTypes
{
   Schwefelsäure,
   Salzsäure,
   NatriumHexafluorsilikat  
}

Hier sind einige zusätzliche Details aus den Kommentaren zu dieser Frage:

  • Das Publikum für den Code wird nur Programmierer sein, keine Chemiker.
  • Ich verwende C #, finde diese Frage aber interessanter, wenn ich die Implementierungssprache ignoriere.
  • Ich beginne mit 10 - 20 Verbindungen und würde höchstens 100 Verbindungen haben, so dass ich mich nicht um jede mögliche Verbindung kümmern muss . Zum Glück ist es eine feste Domäne.
  • Die Aufzählung wird als Schlüssel für Suchvorgänge verwendet, um allgemeine chemische Berechnungen zu vereinfachen. Dies bedeutet, dass die Gleichung für alle Verbindungen gleich ist, Sie jedoch eine Eigenschaft der Verbindung einfügen, um die Gleichung zu vervollständigen.

    • Zum Beispiel wird die Molmasse (in g / mol) verwendet, wenn die Molzahl aus einer Masse (in Gramm) der Verbindung berechnet wird. FWIW, Molmasse == Molgewicht.
    • Ein weiteres Beispiel für eine gängige Berechnung ist das Ideale Gasgesetz und dessen Verwendung der Spezifischen Gaskonstante

Eine Beispielfunktion könnte folgendermaßen aussehen:

public double GetMolesFromMass (double mass_grams, myEnum.ChemTypes chem)
{
  double molarWeight = MolarWeightLookupFunctionByChem (chem); // gibt Gramm / Mol zurück
  Doppelmole = Masse / MolGewicht; // konvertiert in Maulwürfe

  Muttermale zurückgeben;
}

// Beispielanruf:
myMoles = GetMolesFromMass (1000, myEnum.ChemTypes.Na2SiF6);
//*oder*
myMoles = GetMolesFromMass (1000, myEnum.ChemTypes.SodiumHexafluorosilicate);
public double GetSpecificGravity (myEnum.ChemTypes chem, double conc)
{
  // Ermittelt das spezifische Gewicht der chemischen Verbindung basierend auf der Konzentration
  double sg = SpecificGravityLookupTableByChem (chem, conc);  
}

Die Aufzählung des Verbindungsnamens wird daher als Schlüssel verwendet, um eine konsistente Referenzierung der Verbindung mit den zugehörigen Funktionen zu gewährleisten.


quelle
7
Warum müssen sie Aufzählungen sein? Es gibt unendlich viele mögliche Verbindungen, so dass Sie nie in der Lage sein werden, alle zu setzen
Ratschenfreak
3
Als Programmierer, nicht als Chemiker, finde ich, dass Na2SiF6 und Natriumhexafluorsilikat gleichermaßen dunkel sind. Ersteres ist kürzer und besteht höchstwahrscheinlich aus nicht mehr als 40 Zeichen pro Bezeichner.
mouviciel
5
Als Programmierer denke ich persönlich, dass Natrium schneller von meinen Fingern rollen wird als Na2 - Wörter fließen beim Tippen für mich leichter (aus diesem Grund hasse ich die ungarische Notation).
Drake Clarris
5
Sie sollten keine Aufzählungswerte sein, sondern Instanzen Substancemit den Eigenschaften, die sie benötigen.
AakashM
2
@ Glenh7: lies einfach deine frage auf "meta". Ich denke, das eigentliche Problem hier für einige Leute ist "warum müssen chemische Namen überhaupt im Code sein"? Wenn Sie diese Namen nur als eine Art von Daten haben, vermeiden Sie, dass Ihr Code mit sehr langen Namen überfüllt ist, und Sie können die Namen so auswählen, wie es der Benutzer Ihres Systems bevorzugt, unabhängig davon, was ein Entwickler über sie denken mag. Dies würde die Namensverantwortung an den Benutzer delegieren und Ihr Problem vollständig vermeiden.
Doc Brown

Antworten:

9

Als ich anfing, mein aktuelles Projekt von Spaghetti in vernünftigen Code umzuschreiben, hatte ich das gleiche Problem. Meine Problemdomäne ist medizinisch und anstatt Namen wie "ETCO2" und "SPO2" für meine Aufzählungen zu verwenden, habe ich die vollständigen englischen Namen verwendet.

Einerseits war es sehr nützlich, englische Namen zu haben, als ich neu in der Problemdomäne war. Auf der anderen Seite finde ich jetzt, da ich seit einem Jahr mit diesen Begriffen arbeite, dass die vollständigen englischen Namen viel zu ausführlich sind und ich bin mit den Begriffen vertraut, die ich am liebsten mit den Abkürzungen verwenden würde.

Mein Rat wäre, die Atomformel zu verwenden und einen Kommentar zu jedem Aufzählungswert einzuschließen, der seinen vollständigen Namen angibt, unter der Annahme, dass jeder, der sich Ihren Code ansieht, entweder ein Chemiker ist oder b) lange genug am Code arbeitet dass sie sich natürlich mit den Formeln vertraut machen.

Ameise
quelle
1
+1: Außerdem könnte man immer "ETCO2" oder "Na2SiF6" nachschlagen und damit fertig sein.
Steven Evers
5

Wer ist das Publikum für den Code? Werden Chemiker die Enums verwenden oder nur Programmierer ohne spezielle Fachausbildung in Chemie?

Wenn Chemiker den Code verwenden, fragen Sie sie. Sehr wahrscheinlich werden sie die abgekürzten Symbole bevorzugen, da sie diese leicht erkennen können. Wenn Allgemeinwissen-Programmierer diese Kennungen im Auftrag der Chemiker verwenden, ist es meiner Meinung nach besser, die englischen Versionen zu verwenden.

Robert Harvey
quelle
Es werden nur Programmierer sein, keine Chemiker
1
oder fügen Sie die Übersetzung in die Dokumentation jedes Enum
Ratschenfreaks
4

Kein Grund, "all das oben Genannte" nicht zu kombinieren.

Das Problem mit den vollständigen Namen ist, dass es mühsam sein wird, sie einzugeben. Das Problem mit den Symbolnamen ist mangelnde Bedeutung.

Erstellen Sie also Konstanten der Werte mit dem vollständigen Namen. Erstellen Sie dann mit der Konstante verknüpfte Definitionen. Sie können dann auf einfache Weise neuere, kürzere Definitionen erstellen, wenn Sie mit der Bedeutung der Abkürzung vertraut sind.

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

#define SoduimSilicate SodiumHexaFluoroSilicate 
#define F6Na2Si SodiumHexaFluoroSilicate 
#define au Gold 
Daniel
quelle
Ich habe ein gegabeltes C-Codebeispiel verwendet ... Ich denke, es sollte sich leicht in C # übersetzen lassen.
Daniel
Ich mache mir weniger Sorgen um eine bestimmte Implementierung, weshalb ich in meiner Frage kein C # angegeben habe. Und ich mochte Ihren Vorschlag aus C-Sicht. Das C # Description-Tag von System.ComponentModel ist jedoch eine elegante Möglichkeit, den Deskriptor hinzuzufügen. Mich interessierte eher die breitere Beantwortung der Frage nach einer bestimmten Implementierung.
3

Wenn Sie eine Anwendung entwerfen, sollten Sie die Daten von der Programmlogik trennen. Sind die chemischen Verbindungen wirklich Teil der Programmlogik und nicht die Daten, mit denen die Programmlogik arbeitet?

Wenn es sich um Daten handelt, ist es viel besser, sie nicht als Aufzählungen zu behandeln, sondern ihre Namen und Eigenschaften aus einer Konfigurationsdatei zu lesen und sie in einer Datenstruktur zu speichern. Das würde auch die Wartung erheblich erleichtern. Wenn neue Verbindungen hinzugefügt werden müssen oder Fehler in den Eigenschaften einer Verbindung gefunden werden, können diese einfach die Konfigurationsdatei bearbeiten.

Philipp
quelle
1
+1 @ GlenH7, es wäre hilfreich, wenn Sie erklären könnten, warum bestimmte chemische Verbindungen Teil des Codes sind, insbesondere nachdem Sie gesagt haben, dass "die Gleichung für alle Verbindungen gleich ist".
Caleb
1
@ GlenH7: Noch immer kein Grund, warum die Chemikalien nicht nur Daten sind. Einige Plakate empfehlen Ihnen, keine Aufzählung zu verwenden. Ich würde es bestimmt nicht tun.
Kevin Cline
1
@kevincline & caleb (und eigentlich alle anderen), ich habe eine Meta-Frage erstellt, in der um Hilfe gebeten wird, wie diese Frage und der Aufzählungsaspekt davon zu strukturieren sind. Ich würde mich über Ihr Feedback freuen.
3
Nun, wenn jemand mit einem Messer im Kopf zu Ihnen kommt und Sie bittet, sich den Splitter in seiner Hand anzusehen, ist es schwierig, sich darauf zu konzentrieren.
Philipp
1
@Caleb - Frage aktualisiert, um die Verwendung der Aufzählung besser zu verdeutlichen.
3

Dies scheint, als könnte es besser als eine Klasse implementiert werden, die basierend auf den Anforderungen der Entwickler erweitert und übersetzt werden kann. Im Folgenden finden Sie einige Beispiele für C #, die ich erstellt habe, um einige bekannte definierte Chemikalien (als Eigenschaften) und dann abfragbare Speicher (über Addund GetMethoden) zuzulassen . Sie können auch ziemlich einfach erweitern, um Ihre Molmasse und andere chemische Eigenschaften zur Verfügung zu haben.

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;
    }
}

Sie können neue Chemikalien wie diese hinzufügen:

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

und die anderen Bits als solche erhalten:

        Console.WriteLine(Chemical.GetChemicalByChemicalName("sulfuric acid").AtomicFormula);
Jesse C. Slicer
quelle
Vielen Dank für die Antwort, und ich habe meine Frage aktualisiert, damit klarer wird, auf was ich abziele. Ich bin nicht so besorgt darüber, den Namen der chemischen Verbindung zu erhalten, sondern darüber, wie ich über verschiedene Tabellen und dergleichen auf deren Eigenschaften zugreifen kann. Ich habe eine offene Meta-Frage, ob ich die Enum-Diskussion ergänzen oder in ein separates Q