Является ли идиома Non-Virtual Interface (NVI) столь же полезной в C#, как и в C++?

В C++ мне часто требовалось NVI чтобы получить согласованность в моих API. Однако я не вижу, чтобы он использовался среди других в C#. Интересно, это потому, что C#, как язык, предлагает функции, которые делают NVI ненужными? (Я все еще использую NVI в C#, хотя, где это необходимо.)

4 ответов


Я думаю, что объяснение просто в том, что в C# "традиционный" Java-стиль ООП гораздо более укоренился, и NVI противоречит этому. C# имеет реальный interface type, тогда как NVI полагается на" интерфейс", фактически являющийся базовым классом. В любом случае, так это делается на C++, поэтому это естественно.

В C# это все еще можно сделать, и это все еще очень полезная идиома (гораздо больше, я бы сказал, чем" обычные " интерфейсы), но она требует, чтобы вы игнорировали встроенный язык особенность.

многие программисты C# просто не думали бы о классе NVI как о "правильном интерфейсе". Я думаю, что это умственное сопротивление-единственная причина, по которой оно менее распространено в C#.


C# создает проблему с NVIs, забирая множественное наследование. Хотя я думаю, что множественное наследование порождает больше зла, чем добра, это необходимо (в большинстве случаев) для НВИ. Самое простое, что приходит на ум: класс В C# не может реализовать более одного NVI. Как только человек обнаруживает это неприятное аспект тандема C#/NVI становится намного проще отказаться от NVIs, чем от C#.

и кстати, говоря о аспекты. Это очень интересная концепция, и ее цель точно такая же, как у NVIs, только она пытается взглянуть на "истинную суть" вопроса и решить его "правильно", так сказать. посмотреть.

и что касается .NET Framework, есть механизм, чтобы сделать именно это: ввести код, который является "ортогональным", так сказать, к основной логике под рукой. Я говорю обо всем этом бизнесе MarshalByRef / TransparentProxy, я уверен, вы слышали об этом. Это серьезно влияет на производительность , хотя, так что здесь не повезло.

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

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

здесь можно найти эти вопросы обсуждаются более подробно, а также более подробную информацию и ссылки на фактические инструменты. Использование Google для той же цели также приемлемо. :-)

удачи.


Трэй Нэш в своей книге Ускоренный C# продвигает шаблон NVI как каноническую форму в C#.

Я не знаю, кто написал статью, на которую вы ссылаетесь (Больше Идиом C++ / Не Виртуальный Интерфейс), но я чувствую, что автор пропустил этот момент.

...

интерфейс против абстрактных классов

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

с C# вы всегда будете программировать на интерфейс, если вам нужен интерфейс. Вы используете только (абстрактный) базовый класс, потому что вы также хотите использовать реализации.

многие кодовые базы объединяют их и программу с интерфейсом в дополнение к предоставлению класса иерархия как реализация по умолчанию для интерфейса.

NVI для интерфейсов в C

Если ваша единственная мотивация использовать NVI в C++ будет иметь интерфейс, то нет, вы не будете использовать это в C#, потому что язык / CLR предоставляет интерфейсы как первоклассную функцию.

nvi и иерархии объектов

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

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

мое мнение: да, NVI очень полезен в C#.


Я думаю, что NVI так же полезен в C#, как и в C++. Я вижу, что его очень часто используют в моей компании.