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

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

4 ответа

Решение

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

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

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

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

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

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

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

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

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

Удачи.

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

Я не знаю, кто написал статью, на которую вы ссылаетесь ( http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface), но я чувствую, что автор упустил суть.

...

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

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

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

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

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

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

NVI и объектная иерархия

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

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

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

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

Другие вопросы по тегам