Является ли идиома Non-Virtual Interface (NVI) такой же полезной в C #, как в C ++? - PullRequest
6 голосов
/ 26 февраля 2010

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

Ответы [ 4 ]

8 голосов
/ 26 февраля 2010

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

И, кстати, говоря о аспектах . Это очень интересная концепция, и ее цель точно такая же, как и у NVI, только она пытается взглянуть на «истинную суть» проблемы и решить ее, так сказать, «правильно». Взгляните .

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

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

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

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

Удачи.

5 голосов
/ 26 февраля 2010

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

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

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

4 голосов
/ 15 сентября 2010

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

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

...

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

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

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

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

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

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

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

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

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

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

0 голосов
/ 26 февраля 2010

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

...