C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 13.08.09 10:27
Оценка: 93 (1)
А почему, собвтвенно, запретили фичу?

abstract class C
{
  private abstract void M();

  private sealed class D : C
  {
    private override void M() { }
  }
}
Help will always be given at Hogwarts to those who ask for it.
Re[10]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 14.08.09 13:19
Оценка: 1 (1)
Здравствуйте, Константин Л., Вы писали:

КЛ>не совсем понимаю зачем тут эта философская дискуссия


Тем более я не понимаю, при чём тут С++ вообще и столько цитирования в частности
Help will always be given at Hogwarts to those who ask for it.
Re[2]: C#, private abstract метод или свойство
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.08.09 11:20
Оценка: :)
Здравствуйте, Sinclair, Вы писали:

S>В случае наличия вложенных классов, где ни один из них не перегружает наш метод, сочетание по-прежнему является ошибкой.

S>Надо будет при случае спросить Эрика на эту тему.
Вдогонку:
abstract class C
{
    private abstract void M();

    private abstract class D : C
    {
        private sealed class E : D
        {
            private override void M() { }
        }
    }
}

"По мере нарастания уровня маразма, сложность анализа быстро стремится к бесконечности".
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: C#, private abstract метод или свойство
От: Константин Л. Франция  
Дата: 14.08.09 13:33
Оценка: :)
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Константин Л., Вы писали:


КЛ>>не совсем понимаю зачем тут эта философская дискуссия


_FR>Тем более я не понимаю, при чём тут С++ вообще и столько цитирования в частности


при том, причем и D
Re[12]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 14.08.09 13:40
Оценка: :)
Здравствуйте, Константин Л., Вы писали:

КЛ>>>не совсем понимаю зачем тут эта философская дискуссия


_FR>>Тем более я не понимаю, при чём тут С++ вообще и столько цитирования в частности


КЛ>при том, причем и D




Когда я здесь
Автор: _FRED_
Дата: 13.08.09
писал

_FR>D и сейчас видит закрытые члены базы

Я писал это в ответ на

__>Да и нарушается таки private, всё же через наследование class D не должен видеть M().
D и сейчас видит закрытые члены базы


Читайте исходники внимательнее
Help will always be given at Hogwarts to those who ask for it.
Re[11]: C#, private abstract метод или свойство
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 16.08.09 18:33
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

_FR>Цель, которая приследуется паттреном NVI заключается в разделении внешнего интерфейса класса и внутреннего. То, что NVI позволяет прикрутить валидациюи пост-действия — вытекающее следствие.

_FR>Цель TemplateMethod-а с вышеперечисленным никак не связана. Суть шаблонного метода никак не изменится от области его видимости.

_FR>Единственно общее у них — там и там используются виртуальные методы. ИМХО, довольно слабый довод в поддержку родственных отношений.


Прошу прощение, за длительное отсутствие ответа.
Для упрощения обсуждения, я прежде всего обратился к первоисточнику идиомы NVI книге Герба Саттера "Новый сложные задачи на С++", Задача №18. Виртуальность.

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


Здесь сразу хочется отметить, что гуру ООП Бертран Мейер категорически против такой позиции. Он является ярым сторонником возможности переопределения любой функции. В языке программирования Eiffel любая незакрытая функция является виртуальной. Более того, он считает, что должна быть возможность переопределения свойства базового класса в функцию производного класса и наоборот (в Eiffel это возможно. Кроме того, там нет различия в синтаксисе между обращением к полю и вызову функции).

Далее, опять Саттер:

А что, если мы захотим отделить спецификацию интерфейса от спецификации настраиваемого поведения реализации? Тогда мы будем вынуждены в конечном итоге перейти к чему-то наподобие шаблона проектирования "метод шаблона" (Template Method pattern), поскольку то, чего мы хотим добиться, очень напоминает данный шаблон. Однако наша задача существенно уже, и поэтому заслуживает более точного имени. Назовем этот шаблон проектирования шаблоном невиртуального интерфейса (Nonvirtual Interface (NVI) pattern).

Это то, что я писал в изначальном посту, по поводу того, что NVI — частный случай Tempate Method-а.
Затем, далее по тексту:

Во-вторых (во-первых, там не интересно), при лучшем разделении интерфейса и реализации, мы можем обеспечить большую свободу в настройке поведения класса, не влияя на его вид для внешних пользователей. Так, в примере 18-2 мы решили, что имеет смысл предоставить пользователю одну функцию Process и в то же время обеспечить более гибкую настройку, разбив реализацию на две части — DoProcessPhase1 и DoProcessPhase2. Это оказалось очень просто. Мы бы не смогли добиться этого при использовании версии с открытыми виртуальными функциями без того, чтобы такое разделение стало видимо в интерфейсе, тем самым добавляя сложности для пользователей, которым в этой ситуации пришлось бы вызывать две функции.
В-третьих, теперь базовый класс лучше приспособлен к будущим изменениям. Мы можем позже изменить наши замыслы и добавить проверку выполнения пред- и постусловий или разделить работу на несколько этапов, или, например, реализовать полное разделение интерфейса и реализации с использованием идиомы указателя на реализацию (Pimpl), или внести другие изменения в интерфейс для настройки класса, при этом никак не влияя на код, который использует этот класс. Например, существенно труднее начать с открытой виртуальной функции и позже пытаться обернуть ее в другую для проверки пред- и постусловий, чем изначально предоставить невиртуальную функцию-оболочку (даже если никакой дополнительной проверки или иной работы в настоящий момент не требуется) и вставить в нее необходимые проверки позже.


Саттер определяет следующее назначение идиомы NVI:
1. Отделение интерфейса от реализации
2. Упрощение последующего развития и сопровождения кода
Причем первое назначение ярко выражено в С++, где проблема разделения интерфейса и реализации стоит особенно остро. Более того, Саттер предлагает рассмотреть другие идиомы, такие как Pimpl, шаблон проектирования Bridge или handle/body для еще большего разделения интерфейса от реализации, если NVI будет не достаточно.
Второе назначение идиомы не относится к С++, а присуще этой идиоме при применении ее в любом другом языке программирования.
Следует очевидный вывод, что рассматривая эту идиому в терминах C#, стоит уделять больше внимания второй проблеме, т.к. в .net проблемы "физического" разделения интерфейса и реализации (как в С++) просто не существует. Остается лишь проблема "логического" разделения интерфейса от реализации, но это уже не так существенно и весьма и весьма спорно (в Java по-умолчанию все функции виртуальные, и, опять же, Мейер крайне негативно относится к тому, что по-умолчанию во многих языках функции не являются виртуальными).

Хочу добавить, что наблюдения Саттера совпадают с моим собственным опытом.
Например, я начинаю проектирование некоторой иерархии некоторых сущностей. Я определяю некоторые операции, которые получены при анализе предметной области. На данном этапе еще не всегда понятно, является эта операция мономорфной (это более правильный термин, чем изоморфной) или полиморфной. Иногда это понятно сразу, иногда нет, зависит от знаний в этой самой области.
В принципе, при достаточных знаниях в предметной области, можно сразу оценить какова вероятность того, что метод будет полиморфным, существует ли мономорфная составляющая, существуют ли пре- и постусловия и т.д.
Если функция кажется достаточно простой и при этом мономорфная составляющая (видимо) отсутствует, то я делаю ее открытой и виртуальной. Если мономорфная составляющая (скорее всего) присутствует, то я делаю открытый метод невиртуальным и добавляю абстрактный метод в формате MethodNameCore. Итог, мы получаем NVI.
Далее, работая над проектом некоторое время, может появится больше сведений по поводу иерархии этих сущностей вообще, и этого конкретного метода в частности. Очень часто полиморфность оказывается не такой, как видилось изначально и мономорфная составляющая может изменяться. Добавляются пре- и постусловия, и довольно часто понимаешь, что полиморфная составляющая, на самом деле, состоит из нескольких этапов. В результате появляются две абстрактные функции и мы приходим к Методу шаблона.
Обратная ситуация также возможна, когда вначале применяется Tempate Method, а со временем он вырождается в NVI.

З.Ы. Автор считает NVI и Template Method родственными, с возможностями перехода от NVI к Template Method и наоборот. А с автором идиомы (в данном случае с Саттером) спорить сложно, т.к. если ты трактуешь эту идиому не так, как трактует ее автор, то это значит, что ты используешь ее неверно, либо ты используешь другую идиому
Re: C#, private abstract метод или свойство
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.08.09 11:03
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А почему, собвтвенно, запретили фичу?

Прикольно.
Надо полагать, не додумались до такого сценария. Или сочли, что он слишком сложен в реализации — смотри, при анализе кода достаточно легко сопоставить private и abstract. В случае отсутствия вложенных классов, такое сочетание однозначно является ошибкой.
В случае наличия вложенных классов, где ни один из них не перегружает наш метод, сочетание по-прежнему является ошибкой.
Надо будет при случае спросить Эрика на эту тему.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 13.08.09 11:27
Оценка:
Здравствуйте, Sinclair, Вы писали:

_FR>>А почему, собвтвенно, запретили фичу?

S>Прикольно.
S>Надо полагать, не додумались до такого сценария. Или сочли, что он слишком сложен в реализации — смотри, при анализе кода достаточно легко сопоставить private и abstract. В случае отсутствия вложенных классов, такое сочетание однозначно является ошибкой.
S>В случае наличия вложенных классов, где ни один из них не перегружает наш метод, сочетание по-прежнему является ошибкой.

Такой анализ, кажется, даже не нужен: если нет вложенных классов-наследников, то экземпляр "легально" создать нельзя. Но в качестве ворнинга пригодилось бы.

S>Надо будет при случае спросить Эрика на эту тему.


Тут более-менее понятно: данный неподдерживаемый функционал целиком покрывается этим вот рабочим:
class C
{
  private C() { }

  // Несанкционированных наследников 
  // у класса с private-конструктором
  // не будет, поэтому можно сделать protected
  protected virtual void M() { }

  class D : C // Доступ к приватным конструкторам-то есть
  {
    protected override void M() { }
  }
}


Но странным не показалось то, что запрет на сабж не получился как следствие, а был введён намеренно, то есть (как любит говорить сам Эрик) "because no one ever designed, specified, implemented, tested, documented and shipped that feature…", не смотря на то, что запрещаемая функциональность [на мой простой взгляд] не противоречит дизайну языка.
Help will always be given at Hogwarts to those who ask for it.
Re[3]: C#, private abstract метод или свойство
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.08.09 12:11
Оценка:
Здравствуйте, _FRED_, Вы писали:
_FR>Такой анализ, кажется, даже не нужен: если нет вложенных классов-наследников, то экземпляр "легально" создать нельзя.
Ну и что?
Даже если они есть, нет никакой гарантии, что экземпляр всё еще можно создать.


_FR>Тут более-менее понятно: данный неподдерживаемый функционал целиком покрывается этим вот рабочим:

_FR>
_FR>class C
_FR>{
_FR>  private C() { }

_FR>  // Несанкционированных наследников 
_FR>  // у класса с private-конструктором
_FR>  // не будет, поэтому можно сделать protected
_FR>  protected virtual void M() { }

_FR>  class D : C // Доступ к приватным конструкторам-то есть
_FR>  {
_FR>    protected override void M() { }
_FR>  }
_FR>}
_FR>


_FR>Но странным не показалось то, что запрет на сабж не получился как следствие, а был введён намеренно, то есть (как любит говорить сам Эрик) "because no one ever designed, specified, implemented, tested, documented and shipped that feature…", не смотря на то, что запрещаемая функциональность [на мой простой взгляд] не противоречит дизайну языка.

Не очень понятно. Запрещён совершенно конкретный сценарий. К сожалению, под него, помимо очевидно ошибочных случаев, случайно попадают и редкие "рабочие".
Какое решение ты предлагаешь — отказаться от этого еррора совсем, понизив его до ворнинга?
Сделать его ворнингом в случае наличия вложенных классов-наследников, оставив ошибкой в противном случае?
Сделать его ошибкой, если транзитивное замыкание всех вложенных классов-наследников не включает в себя ни одного неабстрактного?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: C#, private abstract метод или свойство
От: master_of_shadows Беларусь  
Дата: 13.08.09 12:19
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А почему, собвтвенно, запретили фичу?


_FR>
_FR>abstract class C
_FR>{
_FR>  private abstract void M();

_FR>  private sealed class D : C
_FR>  {
_FR>    private override void M() { }
_FR>  }
_FR>}
_FR>


Забавно, ну уж весьма спецефический сценарий. Врядли кто либо расстроился из-за отсутвия данной фичи, а комплиер и спеки стали проще.

Да и нарушается таки private, всё же через наследование class D не должен видеть M(). Через то, что он внутри неймспейса класса он этот метод видит, а через наследование нет — т.е. не может перегрузить.
Re[2]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 13.08.09 12:41
Оценка:
Здравствуйте, master_of_shadows, Вы писали:

__>Забавно, ну уж весьма спецефический сценарий. Врядли кто либо расстроился из-за отсутвия данной фичи, а комплиер и спеки стали проще.


Стал ли проще компилятор — не уверен. И на счёт спеки тоже — что описывать ошибку компиляции, что описывать поведение — количество информации, ИМХО, одно и то же. Да и дай нам обеднеть на столько, что бы определять необходимость фичи по размер спецификации для её описания ;о)

__>Да и нарушается таки private, всё же через наследование class D не должен видеть M().


D и сейчас видит закрытые члены базы
Help will always be given at Hogwarts to those who ask for it.
Re[3]: C#, private abstract метод или свойство
От: master_of_shadows Беларусь  
Дата: 13.08.09 12:51
Оценка:
Здравствуйте, _FRED_, Вы писали:

__>>Забавно, ну уж весьма спецефический сценарий. Врядли кто либо расстроился из-за отсутвия данной фичи, а комплиер и спеки стали проще.


_FR>Стал ли проще компилятор — не уверен. И на счёт спеки тоже — что описывать ошибку компиляции, что описывать поведение — количество информации, ИМХО, одно и то же. Да и дай нам обеднеть на столько, что бы определять необходимость фичи по размер спецификации для её описания ;о)


Так ошибка то ведь останется, даже если ввести такое вот исключительное поведение. Компилер ругается на private abstract/virtual.

__>>Да и нарушается таки private, всё же через наследование class D не должен видеть M().


_FR>D и сейчас видит закрытые члены базы


Выделил ключевой момент. Мы же пытаемся перегрузить метод, а не просто дёрнуть его. Хотя вот к конструктору есть доступ ...
Re[4]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 13.08.09 12:55
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

_FR>>Такой анализ, кажется, даже не нужен: если нет вложенных классов-наследников, то экземпляр "легально" создать нельзя.
S>Ну и что?
S>Даже если они есть, нет никакой гарантии, что экземпляр всё еще можно создать.

А такая гарантия и не нужна: например, компилятору, мне кажется, совсем не надо ругаться — а он и не ругается — на такой вот класс:
class C
{
  private C() { }
}

хотя пользы от него тоже не много.

_FR>>Но странным не показалось то, что запрет на сабж не получился как следствие, а был введён намеренно, то есть (как любит говорить сам Эрик) "because no one ever designed, specified, implemented, tested, documented and shipped that feature…", не смотря на то, что запрещаемая функциональность [на мой простой взгляд] не противоречит дизайну языка.

S>Не очень понятно. Запрещён совершенно конкретный сценарий. К сожалению, под него, помимо очевидно ошибочных случаев, случайно попадают и редкие "рабочие".

Не ясно, почему запрещён. Мне видится одна причина — не было найдено ни одного удовлетворительного сценария использования. Есть ли другие причины? Если нет, то зачем позволили виртуальные field-like события? Вот с ними точно ничего хорошего не добиться — больше ошибок наделаешь.

S>Какое решение ты предлагаешь — отказаться от этого еррора совсем, понизив его до ворнинга?


Да, можно было бы просто разрешить безо всяких ошибок-ворнингов-анализов: потому что никакого вреда [пока nikov нам не показал обратного ] данная фича не причиняет и говорит лишь о скорее всего (без использования inner-наследников) бессмысленности действий програмиста, но не об ошибке с его стороны. Смотри пример в начале сообшения: так же бессмысленно, но с точки зрения компилятора верно.
Help will always be given at Hogwarts to those who ask for it.
Re[4]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 13.08.09 12:58
Оценка:
Здравствуйте, master_of_shadows, Вы писали:

__>>>Да и нарушается таки private, всё же через наследование class D не должен видеть M().

_FR>>D и сейчас видит закрытые члены базы
__>Выделил ключевой момент. Мы же пытаемся перегрузить метод, а не просто дёрнуть его. Хотя вот к конструктору есть доступ ...

Даже сейчас возможно такое:
    class C
    {
        protected virtual void M() { }

        private void M2() { }

        class D : C
        {
            protected override void M() { M2(); }
        }
    }

то есть вызов из наследника закрытого члена базового класса. Так почему нельзя разрешить перегрузку?
Help will always be given at Hogwarts to those who ask for it.
Re[5]: C#, private abstract метод или свойство
От: master_of_shadows Беларусь  
Дата: 13.08.09 13:25
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>то есть вызов из наследника закрытого члена базового класса. Так почему нельзя разрешить перегрузку?


Ну да, вызов (и не только, ещё доступ к полям и т.д.) возможен, но нельзя через перегрузку добраться. Полагаю при перегрузке компилер проверяет совсем другие условия. А почему нельзя: рубанули вообще private virtual, ибо не увидели внятных сценариев .

Как вариант work around-а можно использовать internal .
Re: C#, private abstract метод или свойство
От: nikov США http://www.linkedin.com/in/nikov
Дата: 13.08.09 15:52
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А почему, собвтвенно, запретили фичу?


Мы как-то здесь
Автор: AndrewVK
Дата: 25.12.06
спорили.
А здесь
Автор: nikov
Дата: 12.02.09
еще загадка в тему.
Re[2]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 13.08.09 18:32
Оценка:
Здравствуйте, nikov, Вы писали:

_FR>>А почему, собвтвенно, запретили фичу?


N>А здесь
Автор: nikov
Дата: 12.02.09
еще загадка в тему.


http://www.rsdn.ru/forum/dotnet/3288179.aspx
Автор: pt4h
Дата: 12.02.09


Ух ты, я даже оказывается видел уже этот пример
Help will always be given at Hogwarts to those who ask for it.
Re[6]: C#, private abstract метод или свойство
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.08.09 02:41
Оценка:
Здравствуйте, master_of_shadows, Вы писали:

__>Ну да, вызов (и не только, ещё доступ к полям и т.д.) возможен, но нельзя через перегрузку добраться.

Этот момент не понял. Ты предлагаешь новый уровень доступа, который включает private, но не включает protected? Или описываешь некое поведение компилятора, которого я не понимаю?
Приведи пример кода, о котором ты говоришь.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: C#, private abstract метод или свойство
От: master_of_shadows Беларусь  
Дата: 14.08.09 06:38
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


__>>Ну да, вызов (и не только, ещё доступ к полям и т.д.) возможен, но нельзя через перегрузку добраться.

S>Этот момент не понял. Ты предлагаешь новый уровень доступа, который включает private, но не включает protected? Или описываешь некое поведение компилятора, которого я не понимаю?
S>Приведи пример кода, о котором ты говоришь.

Я говорю о двух вещах (грубо говоря повторение того, что тут и обсуждалось):
1. Вложенный класс может дораться до private мемберов внешнего к нему класса.
2. Но перегрузить те же private мемберы внешнего и родительского к нему класса не может.
Не знаю откуда ты вывел ещё один модификатор доступа .


class A
{
    private void M() {}
    private virtual void M2() {}
    private int _f;

    class B : A
    {
        B() { M(); _f = 1; } //Можно добраться.
        override void M2() {} //А тут нет.
    }
}
Re[8]: C#, private abstract метод или свойство
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.08.09 07:30
Оценка:
Здравствуйте, master_of_shadows, Вы писали:

__>Я говорю о двух вещах (грубо говоря повторение того, что тут и обсуждалось):

__>1. Вложенный класс может дораться до private мемберов внешнего к нему класса.
__>2. Но перегрузить те же private мемберы внешнего и родительского к нему класса не может.
__>Не знаю откуда ты вывел ещё один модификатор доступа .
Всё, я протупил. Понятно.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: C#, private abstract метод или свойство
От: Константин Л. Франция  
Дата: 14.08.09 12:05
Оценка:
Здравствуйте, _FRED_, Вы писали:

[]

_FR>D и сейчас видит закрытые члены базы


как и с++
Re[4]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 14.08.09 12:14
Оценка:
Здравствуйте, Константин Л., Вы писали:

_FR>>D и сейчас видит закрытые члены базы


КЛ>как и с++


В С++ больше: есть прекрасная возможность сделать override private-методу Правда, и обломиться можно из-за того, что override не нужно писать, но всё-таки.
Help will always be given at Hogwarts to those who ask for it.
Re[5]: C#, private abstract метод или свойство
От: Константин Л. Франция  
Дата: 14.08.09 12:19
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Константин Л., Вы писали:


_FR>>>D и сейчас видит закрытые члены базы


КЛ>>как и с++


_FR>В С++ больше: есть прекрасная возможность сделать override private-методу Правда, и обломиться можно из-за того, что override не нужно писать, но всё-таки.


я это в первую очередь имел ввиду
Re[5]: C#, private abstract метод или свойство
От: Константин Л. Франция  
Дата: 14.08.09 12:19
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Константин Л., Вы писали:


_FR>>>D и сейчас видит закрытые члены базы


КЛ>>как и с++


_FR>В С++ больше: есть прекрасная возможность сделать override private-методу Правда, и обломиться можно из-за того, что override не нужно писать, но всё-таки.


на этом хорошо делается nvi
Re[5]: C#, private abstract метод или свойство
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 14.08.09 12:22
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>В С++ больше: есть прекрасная возможность сделать override private-методу Правда, и обломиться можно из-за того, что override не нужно писать, но всё-таки.


Да, в С++ существует распространенная идиома (предложенная Гербом Саттером) под названием Non-Virtual Interface (которая является частным случаем шаблона проектирования Template Method, и которая основана исключительно на возможности override-а приватного метода.
Re[6]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 14.08.09 12:38
Оценка:
Здравствуйте, Константин Л., Вы писали:

_FR>>>>D и сейчас видит закрытые члены базы

КЛ>>>как и с++
_FR>>В С++ больше: есть прекрасная возможность сделать override private-методу Правда, и обломиться можно из-за того, что override не нужно писать, но всё-таки.

КЛ>на этом хорошо делается nvi


NVI отлично делается и на шарпе с protected. private имеет отношение не к самому NVI, а к дополнительному уровню инкапсуляции.
Help will always be given at Hogwarts to those who ask for it.
Re[6]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 14.08.09 12:39
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>Да, в С++ существует распространенная идиома (предложенная Гербом Саттером) под названием Non-Virtual Interface (которая является частным случаем шаблона проектирования Template Method, и которая основана исключительно на возможности override-а приватного метода.


А про "частный случай" — это откуда? ИМХО, две совершенно разные по сути (возможно, как-то похожие внешне) вещи.
Help will always be given at Hogwarts to those who ask for it.
Re[7]: C#, private abstract метод или свойство
От: Константин Л. Франция  
Дата: 14.08.09 12:45
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Константин Л., Вы писали:


_FR>>>>>D и сейчас видит закрытые члены базы

КЛ>>>>как и с++
_FR>>>В С++ больше: есть прекрасная возможность сделать override private-методу Правда, и обломиться можно из-за того, что override не нужно писать, но всё-таки.

КЛ>>на этом хорошо делается nvi


_FR>NVI отлично делается и на шарпе с protected. private имеет отношение не к самому NVI, а к дополнительному уровню инкапсуляции.


нет, с protected делается хорошо, а с private отлично. и уровень доступа все-таки имеет отношение к nvi
Re[7]: C#, private abstract метод или свойство
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 14.08.09 12:59
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А про "частный случай" — это откуда? ИМХО, две совершенно разные по сути (возможно, как-то похожие внешне) вещи.


Понятно, что Wiki — это не показатель, но это первое, что я нашел (описание NVI):

Intent

* To modularize/refactor common before and after code fragments (e.g., invariant checking, acquiring/releasing locks) for an entire class hierarchy at one location.

Also Known As

* Template Method — a more generic pattern, from the Gang of Four's Design Patterns book.


Ну и SergH об этом вскользь в своей статье
Автор(ы): Сергей Холодилов
Дата: 28.12.2008
Библиотека ввода-вывода языка С++ — достаточно спорное явление. Но, так или иначе, она существует, иногда используется, и надо как-то с этим жить.
упоминает.
Re[8]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 14.08.09 13:05
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>нет, с protected делается хорошо, а с private отлично.


Это зависит лишь от метода — должна ли быть возможность вызвать базовую реализацию из наследника или нет. К самому NVI отношения данный вопрос не имеет.

КЛ>и уровень доступа все-таки имеет отношение к nvi


Лишь то, что [открытый] интерфейс не должен быть виртуальным. То есть виртуальный должен быть "не открытым". На видимость "не открытых" методов (private там они или protected или даже что ещё) не налагается. Конкретная видимость не открытого члена должна отвечать не за реализацию того или иного паттерна, а за реализацию самого метода — нужен он в наследнике или нет.

Посуди сам — допустим, мы не соблюдаем NVI. Всё равно у нас есть причины делать виртуальные методы закрытыми в случае, если мы не хотим позволить вызывать их из наследников.
Help will always be given at Hogwarts to those who ask for it.
Re[9]: C#, private abstract метод или свойство
От: Константин Л. Франция  
Дата: 14.08.09 13:11
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Константин Л., Вы писали:


КЛ>>нет, с protected делается хорошо, а с private отлично.


_FR>Это зависит лишь от метода — должна ли быть возможность вызвать базовую реализацию из наследника или нет. К самому NVI отношения данный вопрос не имеет.


КЛ>>и уровень доступа все-таки имеет отношение к nvi


_FR>Лишь то, что [открытый] интерфейс не должен быть виртуальным. То есть виртуальный должен быть "не открытым". На видимость "не открытых" методов (private там они или protected или даже что ещё) не налагается. Конкретная видимость не открытого члена должна отвечать не за реализацию того или иного паттерна, а за реализацию самого метода — нужен он в наследнике или нет.


_FR>Посуди сам — допустим, мы не соблюдаем NVI. Всё равно у нас есть причины делать виртуальные методы закрытыми в случае, если мы не хотим позволить вызывать их из наследников.


не совсем понимаю зачем тут эта философская дискуссия
Re[8]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 14.08.09 13:48
Оценка:
Здравствуйте, SergeyT., Вы писали:

_FR>>А про "частный случай" — это откуда? ИМХО, две совершенно разные по сути (возможно, как-то похожие внешне) вещи.

ST>Понятно, что Wiki — это не показатель, но это первое, что я нашел (описание NVI):
ST> * Template Method — a more generic pattern, from the Gang of Four's Design Patterns book.

ST>Ну и SergH об этом вскользь в своей статье
Автор(ы): Сергей Холодилов
Дата: 28.12.2008
Библиотека ввода-вывода языка С++ — достаточно спорное явление. Но, так или иначе, она существует, иногда используется, и надо как-то с этим жить.
упоминает.


Упоминают — ладно: самому-то тебе как кажется — что у них общего?
Help will always be given at Hogwarts to those who ask for it.
Re[9]: C#, private abstract метод или свойство
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 14.08.09 14:33
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Упоминают — ладно: самому-то тебе как кажется — что у них общего?


Общее то, что в NVI помимо простого редиректа к виртуальному методу может (а точнее рекомендуется) содержать валидация аргументов и еще какую-либо часть предварительных действий. Он также может содержать некоторые пост-действия (проверка инварианта класса, результата виртуального метода). А это уже частный случай Template Method-а, который тоже состоит из невиртуальной (изоморфной составляющей) и набора полиморфных операций, часть из которых может переопределять (настраивать) наследник.
Вот и получается, что NVI — это частный случай Template Method-а с одним виртуальным методом.
Re[10]: C#, private abstract метод или свойство
От: _FRED_ Черногория
Дата: 14.08.09 14:46
Оценка:
Здравствуйте, SergeyT., Вы писали:

_FR>>Упоминают — ладно: самому-то тебе как кажется — что у них общего?


ST>Общее то, что в NVI помимо простого редиректа к виртуальному методу может (а точнее рекомендуется) содержать валидация аргументов и еще какую-либо часть предварительных действий. Он также может содержать некоторые пост-действия (проверка инварианта класса, результата виртуального метода). А это уже частный случай Template Method-а, который тоже состоит из невиртуальной (изоморфной составляющей) и набора полиморфных операций, часть из которых может переопределять (настраивать) наследник.

ST>Вот и получается, что NVI — это частный случай Template Method-а с одним виртуальным методом.

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

Цель, которая приследуется паттреном NVI заключается в разделении внешнего интерфейса класса и внутреннего. То, что NVI позволяет прикрутить валидациюи пост-действия — вытекающее следствие.
Цель TemplateMethod-а с вышеперечисленным никак не связана. Суть шаблонного метода никак не изменится от области его видимости.

Единственно общее у них — там и там используются виртуальные методы. ИМХО, довольно слабый довод в поддержку родственных отношений.
Help will always be given at Hogwarts to those who ask for it.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.