Должен ли я использовать интерфейсы в своих коллекциях Singleton и как, где? C # - PullRequest
0 голосов
/ 22 ноября 2011

Полагаю, я не понимаю полного назначения интерфейсов. Поэтому я прошу совета по этому вопросу.

У меня есть несколько таблиц в моей базе данных. Немногие из них: Languages, FrontEndMenus, BackEndMenus ... Эти таблицы имеют разные столбцы, поэтому объекты C # также имеют разные свойства (даже объекты меню FrontEnd и BackEnd имеют несколько разных полей)

Для повышения производительности они хранятся в оперативной памяти в классах SINGLETON с именем (LanguageCollection, FrontEndMenuCollection, BackEndMenuCollection)

Прежде всего, все эти объекты имеют 3 метода: IsValid, Save и Remove. Обычно они используются как:

LanguageItem item1 = new LanguageItem();
item1.IsValid();
item1.Save();
item1.Remove();

FrontEndMenuItem item2 = new FrontEndMenuItem();
item2.IsValid();
item2.Save();
item2.Remove();

//And Same as BackEndMenus class too.. 

И когда я хочу получить один из объектов в одноэлементных коллекциях, я называю их так:

FrontEndMenuItem item = GetInstance.FilterSingleOrDefault(new FrontEndMenuItemArgs{ Id = 14 });

А вот и мой вопрос:

Насколько я понимаю, для создания гибкой структуры я должен использовать реализацию интерфейса для этих классов объектов (FrontEndMenuItem, LanguageItem, BackEndMenuItem)

Я сделал что-то вроде:

    public interface IBusinessItem
    {
        bool IsValid();
        OperationResult Remove();
        OperationResult Remove(bool isCommitOnDatabase);
        OperationResult Save();
        OperationResult Save(bool isCommitOnDatabase);
    }

Но я не уверен, как я могу это использовать ...

Не могли бы вы дать мне небольшое руководство по этому подходу? Я был бы очень рад, если бы вы могли помочь мне, написав очень простые коды.


Я добавил в качестве комментария, но так как это очень важно, я бы хотел добавить эту часть и в мой существующий вопрос:

Когда требуется обновление или вставка, сам объект обновляется по его полям и затем сохраняется. Это так:

FrontEndMenuItem item2 = new FrontEndMenuItem();
item2.Title = "Some title";
item2.ModuleId = 5;
item2.LinkTypeId = 2;
item2.Save(); //Since its a new item its gonna be saved as new that means INSERT.

Методы сохранения могут понять, является ли он новым или нет после его вызова из самого объекта, например item2.Save(), поэтому этот метод также будет работать при вызове из интерфейса IBusinessItem.

Но как насчет полей? В BackEndMenuItem нет поля ModuleId или LinkTypeId

Может ли быть IBusinessItem.ModuleId = 5? Если это так, должен ли я использовать интерфейс, если нет, в какой ситуации я могу использовать интерфейсы для этой проблемы?

Большое спасибо,

Ответы [ 4 ]

2 голосов
/ 22 ноября 2011

По сути, использование интерфейса состоит в том, чтобы не дать потребителю кода узнать, с какой из этих двух конкретных реализаций (LanguageItem и FrontEndMenuItem) он имеет дело, если ему это не нужно. Все, что нужно знать, это то, что любая реализация IBusinessItem имеет список методов, которые вы определяете.

Интерфейсы, таким образом, обеспечивают "слабую связь"; вам не нужно знать, что такое объект, вы просто должны знать, что он делает, или, точнее, что вы можете сделать с ним / с ним.

Теперь, если вы каким-то образом должны знать, что FrontEndMenuItem является FrontEndMenuItem в вашем использовании, то возможность рассматривать его как IBusinessItem не принесет вам большой пользы. Тем не менее, я бы тогда поставил под сомнение ваше использование; похоже, что обе реализации работают одинаково, так почему же LanguageItem нельзя использовать вместо FrontEndMenuItem? Есть несколько веских причин, но есть и несколько очень плохих причин, чтобы настроить его таким образом.

1 голос
/ 22 ноября 2011

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

Не совсем уверен, как вы используете ваши статические классы, но допустим, что у вас есть метод в другом классе, который их использует.Если вы тесно связаны (не используете интерфейс), то для этого метода будет сложно написать модульный тест, поскольку ваш метод теперь тесно связан с этим статическим классом, который обеспечивает некоторую функциональность.

Есливместо этого, вы передаете ссылку на ваш экземпляр в вашем методе (или объявляете экземпляр уровня класса интерфейса, а затем получаете конкретный экземпляр этого в конструкторе), тогда вы сможете смоделировать статический класс (используя что-токак moq или RhinoMock), и тестируйте функциональность только этого метода, не подключаясь к конкретному статическому классу.

В общем, вы хотите максимально уменьшить зависимости в своем коде, когда это возможно.

Надеюсь, это немного поможет ...

0 голосов
/ 23 ноября 2011

Задумывались ли вы об использовании МОК, как Castle Windsor.Это дало бы полное разделение, и стиль жизни по умолчанию - Singleton, и да, использование Singleton и Interfaces - отличный дизайн

0 голосов
/ 22 ноября 2011

Вы определяете свои классы элементов как реализацию интерфейса IBusinessItem:

public class FrontEndMenuItem : IBusinessItem { //... }

Тогда вам не нужно беспокоиться о том, какой элемент коллекции вы используете:

IBusinessItem item1 = new LanguageItem();  
item1.IsValid();  
item1.Save();  
item1.Remove();  

IBusinessItem item2 = new FrontEndMenuItem();  
item2.IsValid();  
item2.Save();  
item2.Remove();  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...