Дизайн интерфейса C #, выставить библиотеки классов? - PullRequest
3 голосов
/ 13 июня 2011

Я хочу определить интерфейс «IFile», который включает в себя массив пар ключ / значение «Метаданные». При получении или установке этих пар ключ / значение разработчик IFile должен иметь возможность предпринять действия. Каков будет лучший способ пойти по этому поводу? Я вижу три метода:

Способ 1) Получить / установить объект словаря:

public interface IFile
{
    ...

    Dictionary<String, String> GetMetadata();

    void SetMetadata(Dictionary<String, String> metadata);
}

Метод 2) Использование класса Dictionary напрямую:

public interface IFile
{
    ...

    Dictionary Metadata();
}

и в реализации IFile может быть предоставлена ​​унаследованная версия Dictionary, которая действует на get / set.

Метод 3) Избегайте словаря и предоставьте пользовательский интерфейс, например:

public interface IMetadata
{
    String GetValue(String key);        
    void SetValue(String key, String value);        
    Boolean Contains(String key);        
    void Delete(String key);  

    ...
}

public interface IFile
{
    ...

    IMetadata Metadata();
}

Я склоняюсь к методу 3, потому что он позволяет разработчику решать, как на самом деле реализовать структуру данных метаданных. Другие решения заставляют использовать словарь. Однако метод 3, кажется, включает в себя много дополнительного кода для переноса.

Я чувствую, что за этим вопросом стоит глубокая дилемма при проектировании иерархий классов, которая заключается в том, открывать ли непосредственно библиотечные классы или предоставлять несколько упакованных функций, которые скрывают внутренне используемый библиотечный класс. У меня мало фактического опыта в создании ООП-проектов, поэтому совет о том, каков «Правильный путь» в этом отношении, будет очень кстати!

Спасибо

Lars

Ответы [ 4 ]

1 голос
/ 13 июня 2011

Метод 4:

public class JFile
{
    ...

    protected Dictionary Metadata() { ... }

    ...

    // --> all this use "Dictionary" internally
    // --> but, do somthing to other "IFile" fields

    public String GetValue(String key) { ... }
    public void SetValue(String key, String value)  { ... }
    public Boolean Contains(String key)  { ... }
    public void Delete(String key)  { ... }
}

Извините, если кажется, что я делаю сложный ответ.

Я собирался предложить метод 2, но ...

... Поскольку вы упоминаете, что когда основной объект / интерфейс "IFile", должен выполнить некоторые действия, когда одно значение метаданных изменяется , а у элементов метаданных нет "делегатов "," события ", что угодно, и хорошая идея по-прежнему группировать метаданные.

Если ваш интерфейс хранит данные только без каких-либо действий при добавлении или удалении элементов, способ 2 будет более практичным.

Мне кажется, что вы сами усложняетесь, прыгая прямо в интерфейсы. Я предлагаю:

  1. сделать полную демонстрацию рабочего класса MyClass
  2. сделать абстрактный суперкласс с тем же методом, класс MyClass: MySuperClass, с рабочим демо.
  3. Возьмите абстрактный суперкласс и спроектируйте интерфейс на основе этого суперкласса

Существует «лучший путь», но «правильного, совершенного, способа» не существует в разработке программного обеспечения, потому что он слишком сложен, чтобы иметь какой-то один способ сделать что-то. Даже если вы выберете другой метод, если он работает, хорошо, тогда он работает.

Удачи; -)

1 голос
/ 13 июня 2011

Если тип метаданных известен во время компиляции, то лично я, вероятно, пойду на это:

public interface IFile
{
    ...

    IDictionary<string, string> Metadata { get; }
}

Примечание - IDictionary вместо Dictionary - это оставляет классу реализации вопрос о том, какой тип реализации словаря использовать.

(в качестве примера я использовал строку для типа словаря, а также потому, что этот тип вы использовали для IMetadata - при необходимости измените его в соответствии с вашими потребностями)

ps - если диапазон ключей для метаданных фиксирован и относительно мал, сделайте ключ перечислением - это более эффективно, чем сравнение строк.

1 голос
/ 13 июня 2011

Мне нравится вариант 3 (определение методов в интерфейсе), потому что:

  1. Это не заставляет реализацию использовать определенную структуру данных.
  2. Более тестируемо / смоделировано.
0 голосов
/ 13 июня 2011

Почему бы не использовать IDictionary, если ваша задача - принудительное наследование словаря в словаре пары ключ-значение?

, тогда ваш первый подход работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...