NET:Интерфейсы против классов
От: AlexNek  
Дата: 15.11.11 17:59
Оценка:
Завязался тут у нас спор с коллегой по поводу "философии программирования". Интересно какие еще мнения будут относительно плюсов и минусов?
Не для каких либо частных случаев, а именно как основной подход.

Итак — Вариант 1 (для каждого класса необходимо иметь не менее 1 интрефейса. Получаем полный контроль над видимостью)

public interface IAbc
{
 // пустой
}

public interface IAbcd:IAbc
{
  //часто всего один метод, что бы потом из интерфейсов можно было конструировать различные объекты
  void Method1(); 
}

.....

internal class Abc:IAbc
{
  public void F1() {...}
  public void Fn() {...}
}

internal class Abcd:Abc,IAbcd
{
  public void Method1() {...}
  public void Fx1() {...}
  public void Fxn() {...}
}
.....
void Xxxx()
{
  // доступ и работа только через интерфейсы, напрямую к объектами запрещено обращаться
  IAbcd t1 = new Abcd(); 
  t1.Method1(); // можно
  t1.F1(); // нельзя
}


Вариант 2 (интерфейсы только когда действительно необходимо, нефиг плодить лишнее)

internal class Abc
{
  protected void F1() {...}
  protected void Fn() {...}
  // можно было и в интерфейс выкинуть, если бы была необходимость обязательной имплементации
  public virtual Method1() {} 
}

internal class Abcd:Abc
{
  public override void Method1() {...}
  protected void Fx1() {...}
  protected void Fxn() {...}
}

void Xxxx()
{
  Abcd t1 = new Abcd();
  t1.Method1(); // можно
  t1.F1(); // нельзя
}

Возможно информации маловато, но пока не хочу перегружать подробностями. Надеюсь различия подходов понятны.
Cообщение написано в << RSDN@Home 1.2.0 alpha 5-AN-R6 rev. 8461>>
Re: NET:Интерфейсы против классов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.11.11 18:07
Оценка: 1 (1) +3
Здравствуйте, AlexNek, Вы писали:

AN>Итак — Вариант 1 (для каждого класса необходимо иметь не менее 1 интрефейса


Нафига?

AN>Получаем полный контроль над видимостью)


Какая то ерунда.

AN>Возможно информации маловато, но пока не хочу перегружать подробностями. Надеюсь различия подходов понятны.


Ответ на исходный вопрос простой и сложный одновременно. Интерфейсы в 99% случаев применяют там, где необходимо изолировать публичные контракты какой то подсистемы. Собственно, все.
... << RSDN@Home 1.2.0 alpha 5 rev. 1537 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[2]: NET:Интерфейсы против классов
От: AlexNek  
Дата: 15.11.11 19:43
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, AlexNek, Вы писали:


AN>>Итак — Вариант 1 (для каждого класса необходимо иметь не менее 1 интрефейса


AVK>Нафига?

Ну концепт у человека такой. Пищит так как будто только что из Таиланда приехал
"Какой изумительный концепт". И я никак не могу врубится почему.

AN>>Получаем полный контроль над видимостью)


AVK>Какая то ерунда.

Ну не совсем полная, мне приводился где-то следующий пример (просто как принцип, а не как пример рабочего кода):
interface IText
{
  public string Text { get; set; }
}

class LabelEx:Label,IText
{
}

...
 Control ctl = new LabelEx();
 // имеем возможность пользоваться как обычным контролом "внутри пакета"
 ctl.BackgroundColor = Color.Blue;
 form.Add(ctl); 
...
 // наружу выдается только возможность прочитать/установить текст
 IText label = GetControl;   
 label.Text = "Sample";


Небольшие изменения и получаем универсальный "конструктор" нужных объектов "наружу".
interface IAllowed:IText,IBitmap
{

}

class LabelEx:Label,IAllowed
{
...
}


Я просто пока не могу сформулировать затыки такого подхода, хотя ж..ой чувствую что то должно быть.
Cообщение написано в &lt;&lt; RSDN@Home 1.2.0 alpha 5-AN-R6 rev. 8461&gt;&gt;
Re[3]: NET:Интерфейсы против классов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.11.11 19:49
Оценка: +1
Здравствуйте, AlexNek, Вы писали:

AVK>>Нафига?

AN>Ну концепт у человека такой.

Ну, альтернативно одаренных программистов в природе встречается достаточно, чтобы очередной сильно удивлял.

AN>Ну не совсем полная, мне приводился где-то следующий пример (просто как принцип, а не как пример рабочего кода):


Ну и? Ради такой ерунды плодить кучу интерфейсов? По мне так стандартный internal вполне себе покрывает основные потребности.
Интерфейсы нужны, когда ты хочешь явно задекларировать какие то контракты для внешнего кода. Вот там они незаменимы.

AN>Я просто пока не могу сформулировать затыки такого подхода, хотя ж..ой чувствую что то должно быть.


Да затык то очень простой — куча тупой работы программиста ради крайне незначительного бенефита.
... << RSDN@Home 1.2.0 alpha 5 rev. 1537 on Windows 7 6.1.7601.65536>>
AVK Blog
Re: NET:Интерфейсы против классов
От: Abyx Россия  
Дата: 15.11.11 20:02
Оценка: +1
Здравствуйте, AlexNek, Вы писали:

AN>Завязался тут у нас спор с коллегой по поводу "философии программирования". Интересно какие еще мнения будут относительно плюсов и минусов?

AN>Не для каких либо частных случаев, а именно как основной подход.

AN>void Xxxx()

AN>{
AN> // доступ и работа только через интерфейсы, напрямую к объектами запрещено обращаться
AN> IAbcd t1 = new Abcd();
AN> t1.Method1(); // можно
AN> t1.F1(); // нельзя
AN>}

"void Xxxx()" не должен сам создавать объекты, иначе теряется весь смысл
In Zen We Trust
Re: NET:Интерфейсы против классов
От: SV.  
Дата: 15.11.11 20:03
Оценка: 4 (1) +2 :))) :)
Здравствуйте, AlexNek, Вы писали:

AN>Возможно информации маловато, но пока не хочу перегружать подробностями. Надеюсь различия подходов понятны.


Представьте, что вы директор театра и нанимаете на работу актера Пожарова. Будете ли вы в трудовом договоре с Ивановым писать, что именно он должен делать и говорить на сцене? Наверное, нет. Во-первых, сегодня у вас Пожаров, а завтра Иванов. Если договор с Пожаровым потеряется, как с Ивановым договариваться? Во-вторых, партнерша Пожарова по спектаклю актриса... мнэ... Петрова должна знать, что Пожаров будет делать и говорить, как ей иначе репетировать? А дать ей почитать договор с Пожаровым нельзя — там последним пунктом указана огромная зарплата Пожарова, чего Петрова не потерпит. В-третьих, зачем Пожарова заставлять читать набор реплик вплоть до "Домком — око недреманное", если роль Аллилуи известна всякому приличному театралу? Подумав, вы пишете в договоре: "...Пожаров принимается на следующие роли: Аллилуи, Лоханкина...".

Далее, вам надо принять на работу бабу Дусю, уборщицу. Ее обязанности не настолько жестко закреплены, чтобы каждое слово регламентировалось. К тому же, она, в отличие от предшественницы бабы Нюры, просит назначить ее убирать поздно по вечерам, а не рано утром. Следовательно, вы можете прямо в ее договоре написать: "вытирать пыль с одиннадцати до двенадцати ежевечерне". Эти детали никого не интересуют: ни Пожарова, ни Иванова, ни Петрову. Они к этому времени уже покидают театр. Будете ли вы писать роль уборщицы, вводить ее в спектакли и принимать бабу Дусю с указанием этой роли? Я — нет. Хотя еще и не такие режиссеры бывают. Особенно, когда первый раз прочитают про Сценические Паттерны ("...паттерн Вешалка был придуман еще Станиславским...").

Надеюсь, различия подходов понятны.
Re[4]: NET:Интерфейсы против классов
От: Abyx Россия  
Дата: 15.11.11 20:07
Оценка:
Здравствуйте, AndrewVK, Вы писали:


AVK>Ну и? Ради такой ерунды плодить кучу интерфейсов? По мне так стандартный internal вполне себе покрывает основные потребности.

AVK>Интерфейсы нужны, когда ты хочешь явно задекларировать какие то контракты для внешнего кода. Вот там они незаменимы.

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

конечно если класс всегда и только всегда будет жить внутри своего модуля (сборки), то в этом действительно смысла нет
но если есть шанс что кто-то захочет реюзнуть класс, скопировав его в другой проект, и не хочет тянуть всю сборку?
In Zen We Trust
Re[4]: NET:Интерфейсы против классов
От: AlexNek  
Дата: 15.11.11 20:08
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, AlexNek, Вы писали:


AN>>Я просто пока не могу сформулировать затыки такого подхода, хотя ж..ой чувствую что то должно быть.


AVK>Да затык то очень простой — куча тупой работы программиста ради крайне незначительного бенефита.

Это парируется, зато хорошая ххх (вместо ххх могут подставлятся различные умные слова)
Нужны "технические" затыки. Пожалуй, попрошу у него пример для поиграться и попробую примерчик не нагло "убить".
Cообщение написано в &lt;&lt; RSDN@Home 1.2.0 alpha 5-AN-R6 rev. 8461&gt;&gt;
Re[2]: NET:Интерфейсы против классов
От: AlexNek  
Дата: 15.11.11 20:16
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, AlexNek, Вы писали:


AN>>Завязался тут у нас спор с коллегой по поводу "философии программирования". Интересно какие еще мнения будут относительно плюсов и минусов?

AN>>Не для каких либо частных случаев, а именно как основной подход.

AN>>void Xxxx()

AN>>{
AN>> // доступ и работа только через интерфейсы, напрямую к объектами запрещено обращаться
AN>> IAbcd t1 = new Abcd();
AN>> t1.Method1(); // можно
AN>> t1.F1(); // нельзя
AN>>}

A>"void Xxxx()" не должен сам создавать объекты, иначе теряется весь смысл

Да не хотелось много текста писать, надо было строчки разделить многоточием.
Cообщение написано в &lt;&lt; RSDN@Home 1.2.0 alpha 5-AN-R6 rev. 8461&gt;&gt;
Re[5]: NET:Интерфейсы против классов
От: AlexNek  
Дата: 15.11.11 20:23
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, AndrewVK, Вы писали:



AVK>>Ну и? Ради такой ерунды плодить кучу интерфейсов? По мне так стандартный internal вполне себе покрывает основные потребности.

AVK>>Интерфейсы нужны, когда ты хочешь явно задекларировать какие то контракты для внешнего кода. Вот там они незаменимы.

A>а почему бы не задекларировать контракты для внутреннего кода?

A>с точки зрения конкретного класса, все остальные — "внешние" по отношению к нему

A>конечно если класс всегда и только всегда будет жить внутри своего модуля (сборки), то в этом действительно смысла нет

A>но если есть шанс что кто-то захочет реюзнуть класс, скопировав его в другой проект, и не хочет тянуть всю сборку?
Копировать не собираются, просто хотят иметь ящик внутри которого можно делать все, а снаружи только то, что позволено, причем объекты и снаружи и внутри хочется иметь одинаковые.
Cообщение написано в &lt;&lt; RSDN@Home 1.2.0 alpha 5-AN-R6 rev. 8461&gt;&gt;
Re[5]: NET:Интерфейсы против классов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.11.11 20:37
Оценка:
Здравствуйте, Abyx, Вы писали:

A>а почему бы не задекларировать контракты для внутреннего кода?


Зачем?

A>с точки зрения конкретного класса, все остальные — "внешние" по отношению к нему


С точки зрения класса — вполне возможно. Но я говорил про точку зрения дизайна программы или модуля программы в целом.

A>но если есть шанс что кто-то захочет реюзнуть класс, скопировав его в другой проект, и не хочет тянуть всю сборку?


Зависит от назначения этого класса. Если это просто набор хелперов, то смысла выносить контракты наружу никакого. А вот явно введенные слои абстракции — их контракты надо описывать интерфейсами практически всегда.
... << RSDN@Home 1.2.0 alpha 5 rev. 1537 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[5]: NET:Интерфейсы против классов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.11.11 20:37
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Это парируется, зато хорошая ххх (вместо ххх могут подставлятся различные умные слова)


Веру техническими аргументами не оспоришь.

AN>Нужны "технические" затыки.


Это вполне технический. Ну если хочешь — технологический затык. Потому что синтаксический мусор не только усложняет первоначальное написание, но и засоряет код при чтении ненужными сущностями.
Но если тебя таки интересуют чисто технические проблемы — есть несколько.
1) Вызов интерфейса в большинстве практических случаев — двойная косвенность. Т.е. вызов накладнее даже виртуального вызова, не говоря уж про раннесвязанный.
2) Особенность реализации interface table (аналог vmt для интерфейсов) в рантайме такова, что каждый загруженный в память интерфейс увеличивает потребную для загрузки всех последующих классов память (ЕМНИП на 4/8 байт в зависимости от разрядности). При большом количестве интерфейсов это обеспечивает вполне заметный оверхед по памяти. На это накладывается оверхед по хранению метаданных самих интерфейсов.
3) Создание делегата на метод интерфейса в некоторых ситуациях приводит к сильному замедлению этого конструирования.
... << RSDN@Home 1.2.0 alpha 5 rev. 1537 on Windows 7 6.1.7601.65536>>
AVK Blog
Re: NET:Интерфейсы против классов
От: fddima  
Дата: 15.11.11 20:39
Оценка:
Здравствуйте, AlexNek, Вы писали:

Как по мне:

(Все случае когда интерфейс напрашивается сам собой — опускаем).

Если вы делаете один единственный класс с уникальной функциональностью — то этот класс уже имеет свой публичный интерфейс — незачем городить лишнюю абстракцию, которую вдобавок ещё и нужно поддерживать.

Если вы делаете классы, которые имплементят какие-то уже известные интерфейсы — не ленитесь создавать интерфейсы, заодно с отсылками к первоисточниками.

Пример: это наличие хорошо задокументированных интерфейсов из W3C DOM (XML): Element, Node, Attribute и т.п. Весь вэб на них держится. И всё идеально укладывается в дотнетные интерфейсы. Что в реальности? System.Xml это набор классов "в себе" — подменить имплементацию невозможно, хотя это заложено изначально, там на правах internal даже есть DOMImplementation (нафига тока оно надо, если оно internal и не выполняет своих функций?). Правда в этом случае в большей степени — это перманентная проблема MS — всё время переизобретать колесо и погоня за призраками.

В этом же смысле XLinq — обратная сторона медали — в тыщу раз лучше, а код внутри — просто прелесть. Перестали копировать W3C DOM, — на все случаи не годиться, но покрывает 99% потребностей. А те, что не покрывает, например потребность быстрой навигации назад (previous sibling и т.п.) — благодаря annotations — решаема. В этом случае следовать интерфейсам — было бы вредно.
Re[2]: NET:Интерфейсы против классов
От: artelk  
Дата: 15.11.11 20:59
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Интерфейсы в 99% случаев применяют там, где необходимо изолировать публичные контракты какой то подсистемы.

И в 98% случаев для обеспечения ООП-шного полиморфизма.
Re[6]: NET:Интерфейсы против классов
От: AlexNek  
Дата: 15.11.11 21:31
Оценка: :)
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, AlexNek, Вы писали:


AN>>Это парируется, зато хорошая ххх (вместо ххх могут подставлятся различные умные слова)


AVK>Веру техническими аргументами не оспоришь.

Я уже и не знаю какие аргументы использовать.
Просто боюсь подумать, что туда кому то другому может прийдется что то добавлять. Он еще туда MVP паттерн запиндрючил, получилось не менее 30 классов и интерфейсов без учета различных элементов отображения.
А основные классы создает через активатор по динамически создаваемым именам. Блин, и книги отобрать низзя
Cообщение написано в &lt;&lt; RSDN@Home 1.2.0 alpha 5-AN-R6 rev. 8461&gt;&gt;
Re[7]: NET:Интерфейсы против классов
От: fddima  
Дата: 15.11.11 21:36
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Просто боюсь подумать, что туда кому то другому может прийдется что то добавлять. Он еще туда MVP паттерн запиндрючил, получилось не менее 30 классов и интерфейсов без учета различных элементов отображения.

AN>А основные классы создает через активатор по динамически создаваемым именам. Блин, и книги отобрать низзя
У меня есть проект в котором используется куча интерфейсов. Достался в наследство.
Интерфейсы эти: для DataAccess, для BussinessRules, для фасадов. Проблема только в том, что ничего кроме головной боли они не добавляют, потому что, вместо того что бы написать новый метод в одном (трёх) местах — приходится рыскать и добавлять ещё и во всех интерфейсах (т.е. вместо трёх — шесть). При чём, как бы оно там ни было правильно — но реально, никаких DI или тестов — нет. Т.е. это живёт само в себе. Такое нужно давить, интерфейса на фасаде хватило бы. Интерфейс проще добавить, если он реально необходим, тем более в шарпе, с его способносятм к рефакторингу.
Re: NET:Интерфейсы против классов
От: IT Россия linq2db.com
Дата: 16.11.11 01:55
Оценка: +2
Здравствуйте, AlexNek, Вы писали:

AN>Завязался тут у нас спор с коллегой по поводу "философии программирования". Интересно какие еще мнения будут относительно плюсов и минусов?

AN>Не для каких либо частных случаев, а именно как основной подход.

В качестве основного подхода можно порекомендовать задавать себе почаще вопрос при принятии подобных решений — а какую конкретную проблему мы решаем. Если не конкретно, а сильно в общем, то интерфейсы и большинство паттернов, на них базирующиеся, позволяют рещать проблемы так или иначе связанные с гибкостью кода. Но как нам известно из закона сохранения сложности за всё нужно платить. Плата за интерфейсы — количественное усложнение кода и увеличение, порой весьма существенное, сложности восприятия кода. Тотальное использование интерфейсов скорее всего приведёт к тотальной потери восприятия кода, что в более менее сложном проекте неизбежно закончится полной или частичной потерей контроля над кодом. Там где на поиск и решение проблемы потребовалось бы пару минут будет уходить по нескольку часов, а там где нужно было бы несколько часов или дней, придётся тратить недели и месяцы.

В простонародье подобные решения называются overdesign/overarchitecture, когда фактическая получаемая выгода от принятых решений низка или полностью отсутсвует, а привнесённые существенные усложнения тупо не замечаются или старательно игнорируются. Но, к сожалению, сложность очень коварна. Если бы мы имели дело с одним, пусть даже большим, монолитным куском некой субстанции, то можно было бы напрячься и одним махом разрешить все проблемы, которые от неё исходят. Но сложность не монолит, а скорее куча мелкой крошки и песка, и с каждой крошкой и песчинкой приходтся иметь дело индивидуально. Лучше не нести весь этот мусор в код с самого начала. Голова она хоть и большая, но у программиста ей и без этого есть о чём болеть.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: NET:Интерфейсы против классов
От: XRonos Россия  
Дата: 16.11.11 07:13
Оценка:
Здравствуйте, SV., Вы писали:

SV.>Представьте, что вы директор театра и нанимаете на работу актера Пожарова. Будете ли вы в трудовом договоре с Ивановым писать, что именно он должен делать и говорить на сцене? ...

Довольно абстрактно сказано, примерно так же, как и в случае с большим количеством ненужных интерфейсов.

AndrewVK всё верно говорил: всё должно согласовываться с принципом достаточности, необходимости и разумности и только. В каждом конкретном случае надо думать, просто думать... А не бездумно применять наугад тот или иной паттерн. Если речь идёт об интерфейсах — это всего лишь контракты для сокрытия реализации... а реализацию нужно скрывать только там, где это крайне необходимо, например: плагины, компоненты, модули, семейства сущностей, имеющих общие черты (фигуры, например)... Вот и всё. Ничего лишнего...
Бди!
Re: NET:Интерфейсы против классов
От: AlexNek  
Дата: 16.11.11 08:21
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Завязался тут у нас спор с коллегой по поводу "философии программирования". Интересно какие еще мнения будут относительно плюсов и минусов?

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



    public interface IDeviceModel :
        IBaseModel,
        IPropertyDataSummary,
        IPropertyModelInformation
    {
        IPropertyCommunicationEventsSummary Communication{get;    }

        IPropertyComPortSummary Port{get;}

        void SetExternalDeviceData(DeviceDataItemsSet collection);

        void SetExternalConfigData( DeviceDataItemsSet collection );
    }
Re[2]: NET:Интерфейсы против классов
От: VoidEx  
Дата: 16.11.11 08:23
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, AlexNek, Вы писали:


IT>Но как нам известно из закона сохранения сложности за всё нужно платить.


Прям таки и сохранения? Как не крутись, а сложность будет одинаковая?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.