Керівництво в називанні незручних доменних об'єктів?


12

Я моделюю хімічну систему, і у мене виникають проблеми з називанням моїх елементів / предметів в межах enum.

Я не впевнений, чи варто використовувати:

  • атомна формула
  • хімічна назва
  • скорочена хімічна назва.

Наприклад, сірчаною кислотою є H2SO4, а соляна кислота - HCl.

З цими двома, я, мабуть, просто використовую атомну формулу, оскільки вони досить поширені.

Однак у мене є інші, як гексафторсилікат натрію, який є Na2SiF6.

У цьому прикладі, атомна формула не настільки очевидна (для мене) , але хімічна назва потворно довго: myEnum.SodiumHexaFluoroSilicate. Я не впевнений, яким чином я міг би безпечно придумати скорочене хімічне ім’я, яке б мало послідовний зразок іменування.

Є кілька проблем, які я намагаюся вирішити, називаючи елементи enum.
Перший - читабельність, і довші назви представляють проблему.
Друге - це легкість підбору коду для нових технічних засобів, і тут більш короткі назви представляють проблему.
Наступне питання полягає в тому, що власники підприємств зазвичай посилаються на повну хімічну назву, але не завжди. "Ротові" хімічні речовини називають їх формулою.
Останнім питанням є забезпечення його послідовності. Я не хочу змішаної конвенції про іменування, оскільки буде неможливо запам'ятати, яку використовувати.

З точки зору технічного обслуговування, який із варіантів називання ви б хотіли бачити і чому?


Примітка: Все, що знаходиться нижче рядка, додаткове | уточнюючий матеріал. Будь ласка, не занурюйтесь у це. Основне питання стосується називання незручних об'єктів.

Атомний варіант

загальнодоступні myEnum.ChemTypes
{  
   H2SO4,
   HCl,
   Na2SiF6
}

Хімічна назва Варіант

загальнодоступні myEnum.ChemTypes
{
   Сірчана кислота,
   Хлористого-воднева кислота,
   Натрій гексафторосилікат натрію  
}

Ось кілька додаткових деталей із коментарів до цього питання:

  • Аудиторію за кодом будуть просто програмісти, а не хіміки.
  • Я використовую C #, але я вважаю, що це питання цікавіше при ігноруванні мови реалізації.
  • Я починаю з 10 - 20 сполук і мав би щонайменше 100 сполук, тому мені не потрібно турбуватися про кожен можливий склад. На щастя, це фіксований домен.
  • Перелік використовується як ключ для пошуку для полегшення загальних / загальних хімічних обчислень - це означає, що рівняння однакове для всіх сполук, але ви вставляєте властивість сполуки закінчувати рівняння.

Зразок функції може виглядати так:

публічний подвійний GetMolesFromMass (подвійний mass_gram, myEnum.ChemTypes chem)
{
  подвійний molarWeight = MolarWeightLookupFunctionByChem (хімічний); // повертає грам / моль
  подвійні молі = маса / молярна вага; // перетворюється на кротів

  зворотні родимки;
}

// Зразок виклику:
myMoles = GetMolesFromMass (1000, myEnum.ChemTypes.Na2SiF6);
// * або *
myMoles = GetMolesFromMass (1000, myEnum.ChemTypes.SodiumHexafluorosilicate);
публічний подвійний GetSpecificGravity (myEnum.ChemTypes chem, подвійний конц)
{
  // отримує питому вагу хімічної сполуки на основі концентрації
  подвійний sg = SpecificGravityLookupTableByChem (chem, conc);  
}

Отже, enum імені сполуки використовується як ключовий і для забезпечення узгодженості у посиланні сполуки на пов'язані функції.


7
чому вони повинні бути перелюбами? є нескінченна кількість можливих сполук, тому ви ніколи не зможете їх усіх встановити
храповик виродка

3
Як програміст, а не хімік, я вважаю, що Na2SiF6 та гексафторосилікат натрію однаково незрозумілі. Перший коротший на тип і, швидше за все, передає дивні правила кодування не більше 40 символів за ідентифікатором.
mouviciel

5
Як програміст, я особисто думаю, що натрій відкочує мої пальці швидше, ніж Na2 - слова, як правило, протікають мені легше під час набору тексту (я ненавиджу угорські позначення з цієї причини).
Дрейк Кларріс

5
Вони не повинні бути значеннями перерахунку, вони повинні бути примірниками Substanceбудь-яких властивостей, які їм потрібні.
AakashM

2
@ GlenH7: просто прочитайте своє запитання на "мета". Я думаю, що справжня проблема тут для деяких людей полягає в тому, "чому хімічні назви взагалі повинні бути в коді"? Якщо ці імена є лише деякими формами даних, ви не зможете збивати ваш код дуже довгими іменами, і ви можете вибирати імена так, як віддає перевагу користувач вашої системи, незалежно від того, що розробник може думати про них. Це покладе відповідальність на іменування на користувача та повністю уникне вашої проблеми.
Док Браун

Відповіді:


9

Коли я почав переписувати свій сучасний проект зі спагетті в розумний код, я зіткнувся з тією ж проблемою. Мій проблемний домен - це медичні, а замість того, щоб використовувати такі імена, як "ETCO2" та "SPO2" для моїх переліків, я використав повні англійські імена.

З одного боку, було дуже корисно мати англійські імена, коли я був новаком у проблемній області. З іншого боку, зараз, коли я працюю з цими термінами рік, я вважаю, що повні англійські назви є занадто багатослівними, і я досить знайомий з термінами, які я б більше вважав за краще використовувати скорочення.

Моя порада полягає в тому, щоб використовувати атомну формулу і включити коментар до кожного значення enum, яке дає повне ім'я, за умови, що кожен, хто дивиться на ваш код, буде або а) хіміком, або 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 # досить легко.
Даніель

Я не так переживаю конкретну реалізацію, тому я не вказав C # у своєму питанні. І мені сподобалася ваша пропозиція з точки зору С. Тег C Description від System.ComponentModel - це елегантний спосіб додати дескриптор. Мене більше зацікавила більш широка відповідь на питання щодо конкретної реалізації.

3

Створюючи будь-яку програму, слід відокремити дані від логіки програми. Чи справді хімічні сполуки є частиною логіки програми, а не даних, якими працює логіка програми?

Коли вони є даними, було б набагато краще не ставитися до них як до переліків, а краще читати їх імена та властивості з конфігураційного файлу та зберігати їх у структурі даних. Це також значно полегшить обслуговування. Коли потрібно додати нові сполуки або виявити помилку у властивостях одного, вони можуть просто відредагувати файл конфігурації.


1
+1 @ GlenH7 допоможе, якщо ви можете пояснити, чому конкретні хімічні сполуки є частиною коду, особливо після того, як ви сказали, що "рівняння однакове для всіх сполук".
Калеб

1
@ GlenH7: Все ще немає причини, чому хімічні речовини - це не просто дані. Кілька плакатів корисно говорять вам про те, щоб не використовувати переслідування. Я, звичайно, не хотів.
Кевін Клайн

1
@kevincline & caleb (і всі інші насправді), я створив мета-запитання з проханням допомогти, як структурувати це питання та його перелік. Буду вдячний за ваші відгуки.

3
Що ж, коли хтось до тебе приходить із забитим у голові ножем, і він просить тебе подивитися на осколок у руці, важко сконцентруватися на цьому.
Філіпп

1
@Caleb - запитання оновлено, щоб краще уточнити використання enum.

3

Це здається, що його можна було б краще реалізувати як клас, який може розширюватись та перекладати, залежно від потреб розробників. Нижче наведено приклад C #, який я придумав, щоб дозволити декілька відомих визначених хімічних речовин (як властивості), а потім магазини, що піддаються пошуку (за допомогою Addта Getметодами). Ви також можете досить легко розширити, щоб мати молярну масу та інші хімічні властивості.

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.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.