Re[6]: Почему плохо иметь много паблик методов?
От: Jack128  
Дата: 24.11.09 08:02
Оценка:
Здравствуйте, 0x7be, Вы писали:

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


M>>>В приведенно примере SameMethod(param1, 0) можно реализовать как внешнюю функцию , внешнюю по отношению к классу или модулю.

J>>можно. А зачем??
0>Что бы не плодить дополнительные сущности в контракте. В С#, начиная с версии 3.0, для решения подобных задач есть хороший механизм — extension methods.

что ты имеешь ввиду под словом "сущность" ?? метод?? тогда твоя фраза ничего не объясняет. по сути ты сказал "много методов — плохо , потому что это плохо." либо расшифруй это слово.
Re[2]: Почему плохо иметь много паблик методов?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.11.09 08:02
Оценка: -2
Здравствуйте, minorlogic, Вы писали:

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


J>>Один авторитетный, судя по рейтингу, rsdn'овиц заявил сабж. Кто ниту может объяснить почему так?


M>Меньше интерфейс, меньше зависимостей и связей.

Да ну...
Re[2]: Почему плохо иметь много паблик методов?
От: Jack128  
Дата: 24.11.09 08:10
Оценка:
Здравствуйте, minorlogic, Вы писали:

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


J>>Один авторитетный, судя по рейтингу, rsdn'овиц заявил сабж. Кто ниту может объяснить почему так?


M>Меньше баплик методов , меньшн интнрфейс.

M>Меньше интерфейс, меньше зависимостей и связей.

вот этот пункт — не очевиден.

пусть есть Class1, имеющий Method1 и Method2. Пусть есть некий Method3, сводящийся к вызову Method1 и Method2. Конкретные доводы, почему я должен реализовывать этот Method3 во внешнем классе есть?
Re[7]: Почему плохо иметь много паблик методов?
От: 0x7be СССР  
Дата: 24.11.09 08:33
Оценка: 24 (2)
Здравствуйте, Jack128, Вы писали:

0>>Что бы не плодить дополнительные сущности в контракте. В С#, начиная с версии 3.0, для решения подобных задач есть хороший механизм — extension methods.

J>что ты имеешь ввиду под словом "сущность" ?? метод?? тогда твоя фраза ничего не объясняет. по сути ты сказал "много методов — плохо , потому что это плохо." либо расшифруй это слово.
Не метод. Я там по ветке ниже уже отписался.
Суть такова: подобные методы не добавляют функционал интерфейсу, а фиксируют некоторые распространенные паттерны употребления методов интерфейса. Т.е. получается, что интрефейс описывает и, собственно, функционал, и наиболее распространенные паттерны вызовов, которые вполне могут быть контекстно-зависимыми. Мой тезис заключается в том, что паттерны вызовов вынести в extesion methods и не замусоривать ими интерфейс.
Re[8]: Почему плохо иметь много паблик методов?
От: Jack128  
Дата: 24.11.09 09:49
Оценка:
Здравствуйте, 0x7be, Вы писали:

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


0>>>Что бы не плодить дополнительные сущности в контракте. В С#, начиная с версии 3.0, для решения подобных задач есть хороший механизм — extension methods.

J>>что ты имеешь ввиду под словом "сущность" ?? метод?? тогда твоя фраза ничего не объясняет. по сути ты сказал "много методов — плохо , потому что это плохо." либо расшифруй это слово.
0>Не метод. Я там по ветке ниже уже отписался.
0>Суть такова: подобные методы не добавляют функционал интерфейсу, а фиксируют некоторые распространенные паттерны употребления методов интерфейса. Т.е. получается, что интрефейс описывает и, собственно, функционал, и наиболее распространенные паттерны вызовов, которые вполне могут быть контекстно-зависимыми. Мой тезис заключается в том, что паттерны вызовов вынести в extesion methods и не замусоривать ими интерфейс.

"мусорить интерфейс" — это слова. ты можешь конкретный сценарий привести, при котором extension методы будут удобнее просто доп методов у класса?? ну там проще рефакторить или еще что.
Re[3]: Почему плохо иметь много паблик методов?
От: minorlogic Украина  
Дата: 24.11.09 10:28
Оценка:
Здравствуйте, Jack128, Вы писали:

J>пусть есть Class1, имеющий Method1 и Method2. Пусть есть некий Method3, сводящийся к вызову Method1 и Method2. Конкретные доводы, почему я должен реализовывать этот Method3 во внешнем классе есть?


Если нужен только вызов Method3, то Method1 и Method2 лучше сделать приватными. Тогда это улучшений , интерфейс снановится более узким.

Если Method3 нужен только для удобства использования, тогда пишется так называемый Фасад.
http://en.wikipedia.org/wiki/Facade_pattern

Класс который инкапсулирует сложность работы с другой сущностью, в какомто конкретном применении.
Мотивация к использованию данного шаблона, скорее всего она подойдет для описанного случая.
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[4]: Почему плохо иметь много паблик методов?
От: Jack128  
Дата: 24.11.09 11:59
Оценка: +1
Здравствуйте, minorlogic, Вы писали:

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


J>>пусть есть Class1, имеющий Method1 и Method2. Пусть есть некий Method3, сводящийся к вызову Method1 и Method2. Конкретные доводы, почему я должен реализовывать этот Method3 во внешнем классе есть?


M>Если нужен только вызов Method3, то Method1 и Method2 лучше сделать приватными. Тогда это улучшений , интерфейс снановится более узким.


M>Если Method3 нужен только для удобства использования, тогда пишется так называемый Фасад.

M>http://en.wikipedia.org/wiki/Facade_pattern

M>Класс который инкапсулирует сложность работы с другой сущностью, в какомто конкретном применении.

M>Мотивация к использованию данного шаблона, скорее всего она подойдет для описанного случая.

чесно говоря не видел, чтоб фасад скрывал сложность ОДНОГО класса. обычно он скрывает взаимосвязи между множеством классов.
Re[5]: Почему плохо иметь много паблик методов?
От: minorlogic Украина  
Дата: 24.11.09 13:10
Оценка:
Здравствуйте, Jack128, Вы писали:

J>чесно говоря не видел, чтоб фасад скрывал сложность ОДНОГО класса. обычно он скрывает взаимосвязи между множеством классов.


Так и есть в широкодуступных описаниях. Я же говорю о том что этот шаблон можно и нужно применять в меньших масштабах. Механизмы остаются те же.
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[3]: Почему плохо иметь много паблик методов?
От: jhfrek Россия  
Дата: 24.11.09 13:33
Оценка: +1
Здравствуйте, Jack128, Вы писали:

J>пусть есть Class1, имеющий Method1 и Method2. Пусть есть некий Method3, сводящийся к вызову Method1 и Method2. Конкретные доводы, почему я должен реализовывать этот Method3 во внешнем классе есть?


потому что не бывает классов с Метод1, Метод2, Метод3 и т.д. Бывает класс с конкретными методами, реализующий конкретное поведение.

Если это хранилище с методами Найти и Добавить, то метод НайтиЕслиНетДобавить — вполне логичен (правда может стоит оставить только его...).

А вот метод НайтиИУмножитьНайденноеНа3ЕслиНетСоздатьНовыйКакЛучшийИзПервогоИПоследнего — не логичен, ибо magic заложенный в этот метод никак не относится к хранилищу и ясен только вам, как автору метода. Для него лучше завести отдельный класс MyMagicSequence с таким методом — будет проще сопровождать код.
Re: Почему плохо иметь много паблик методов?
От: Воронков Василий Россия  
Дата: 24.11.09 13:37
Оценка: 10 (2) +2
Здравствуйте, Jack128, Вы писали:

J>Один авторитетный, судя по рейтингу, rsdn'овиц заявил сабж. Кто ниту может объяснить почему так?


Предположим, у тебя есть класс IniFileStorage, у которого есть два метода:

IniFileStorage
{
  void SetValue(string key, object value);

  object GetValue(string key);
}


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

IniFileStorage
{
  void SetValue(string key, object value);

  object GetValue(string key);

  void Serialize(string key, object graph);

  object Deserialize(string key, Type objectType);
}


И все бы хорошо, но спустя какое-то время ты понимаешь, что INI-файлы это УГ, и нужно использовать что-нибудь более удобное — например, XML или реестр. Что тебе приходится делать? Правильно — переписать весь класс IniFileStorage, а заодно с ним поменять весь клиентский код. А если клиентский код пишешь не только ты, но и многочисленные плагинописатели?

А как можно было бы поступить иначе?

Предположим, у тебя есть класс IniFileStorage, и его методы вынесены в интерфейс:

IStorage
{
  void SetValue(string key, object value);

  object GetValue(string key);
}


Когда у тебя возникает необходимость в создании своего сериализатора, ты пишешь отдельный класс:

MySerializer
{
  Initialize(IStorage storage);

  void Serialize(string key, object graph);

  object Deserialize(string key, Type objectType);    
}


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

Рассмотрим другой пример. У тебя есть все тот же IniFileStorage. Потом ты понимаешь, что в ряде случаев удобнее использовать генерик-методы для записи и чтения. Ну и добавляешь их в класс.

IniFileStorage
{
  void SetValue(string key, object value);

  object GetValue(string key);

  void SetValue<T>(string key, T value);

  T GetValue<T>(string key);
}


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

Возьмем более банальный пример. У тебя IniFileStorage используется не только напрямую, но и в обобщенном коде — в том же сериализаторе, — которому генерик методы неудобны. И он их никогда не будет вызывать. Другой программист, работающий вместе с тобой, может не знать об этом поведении и также о том, что согласно твоим принципам дизайна SetValue и SetValue<> должны делать абсолютно одно и то же, чтобы все правильно работало. А не знать он может просто потому, что такие паттерны науке неизвестны. И вот он возьмет и добавит какой-нибудь специфичный код в SetValue<>, который согласно новым требованиям должен бы выполняться всегда, но будет работать лишь время от времени, когда вызывается SetValue<>, а не SetValue. А ведь "старые" клиенты вообще не подозревают о существовании SetValue<>.
А послезавтра третий программист добавит еще одну пару методов, которая покажется ему удобной и тоже забьет на все изменения в SetValue<> — или же продублирует их, но не неправильно. Получаем "макароны" на ровном месте и в связи с очень простой задачей. И случай не такой уж и далекий от жизни. А что может быть в реальном проекте, который делает что-то более интеллектуальное, чем запись в ини-файл?
Re[3]: Почему плохо иметь много паблик методов?
От: IB Австрия http://rsdn.ru
Дата: 24.11.09 14:01
Оценка: +1
Здравствуйте, Jack128, Вы писали:

J>пусть есть Class1, имеющий Method1 и Method2. Пусть есть некий Method3, сводящийся к вызову Method1 и Method2. Конкретные доводы, почему я должен реализовывать этот Method3 во внешнем классе есть?

Есть — это ухудшает инкапсуляцию, так как Method3 получает доступ к приватному состоянию Class1, что совершенно не нужно для его работы.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[3]: Почему плохо иметь много паблик методов?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 24.11.09 14:01
Оценка:
Здравствуйте, Jack128, Вы писали:

M>>Меньше баплик методов , меньшн интнрфейс.

M>>Меньше интерфейс, меньше зависимостей и связей.

J>вот этот пункт — не очевиден.


J>пусть есть Class1, имеющий Method1 и Method2. Пусть есть некий Method3, сводящийся к вызову Method1 и Method2. Конкретные доводы, почему я должен реализовывать этот Method3 во внешнем классе есть?


Method3 реализует некоторую логику, пользуясь при этом Method1 и Method2. Является ли реализация этой логики частью обязанностей (ответственности) Class1? Строго говоря — нет. Хотя тут возможны исключения — зависит от того, как возникла такая ситуация: в результате рефакторинга или by design. К чему это приводит: изменения Method3 (как части интерфейса) приведут к перекомпиляции всех частей, зависимых от Class1 (и т.д.), хотя эти части не обязательно зависят от Method3. Изменение любых типов-параметров Method3 также приведет к этому, и т.д.
Еще хуже, когда при необходимости изменения реализации Method3 верез Class1 будут протаскиваться дополнительные параметры. В каких-то местах может быть завязка на текущую реализацию Method3, и автоматическое изменение поведения из-за изменения, скажем Method1 может быть нежелательным. Может оказаться что функциональность Method3 уже где-то рализована и реализация Method3 по существу — дублирование кода. И т.п.

В некоторых контекстах подобного рода зависимости могут не иметь особого значения, в некоторых наоборот. По умолчанию — два маленьких (Class1 & Class2) лучше чем один большой (Class1).
Re[4]: Почему плохо иметь много паблик методов?
От: Jack128  
Дата: 24.11.09 16:12
Оценка:
Здравствуйте, IB, Вы писали:

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


J>>пусть есть Class1, имеющий Method1 и Method2. Пусть есть некий Method3, сводящийся к вызову Method1 и Method2. Конкретные доводы, почему я должен реализовывать этот Method3 во внешнем классе есть?

IB>Есть — это ухудшает инкапсуляцию, так как Method3 получает доступ к приватному состоянию Class1, что совершенно не нужно для его работы.

отсюда следует просто вывод: в классе вообще _не должно_ быть методов, которые вызывают только паблик методы этого класса. Ты сам действительно так пишешь???
Re[5]: Почему плохо иметь много паблик методов?
От: Воронков Василий Россия  
Дата: 24.11.09 16:17
Оценка: :))
Здравствуйте, Jack128, Вы писали:

J>отсюда следует просто вывод: в классе вообще _не должно_ быть методов, которые вызывают только паблик методы этого класса. Ты сам действительно так пишешь???


А ты думаешь, что он ответит тебе "нет"? А потом все дружно извинятся и скажут, что эта была просто попытка тебя обмануть, а ты молодец, что не поддался?
Re[2]: Почему плохо иметь много паблик методов?
От: Jack128  
Дата: 24.11.09 16:21
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Когда у тебя возникает необходимость в создании своего сериализатора, ты пишешь отдельный класс:


ВВ>
ВВ>MySerializer
ВВ>{
ВВ>  Initialize(IStorage storage);

ВВ>  void Serialize(string key, object graph);

ВВ>  object Deserialize(string key, Type objectType);    
ВВ>}
ВВ>


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

ВВ>Стало лучше? Мне кажется, да.

лудше. Только я не понял, ты выделил отдельный класс сериализатора — только для того чтобы уменьшить кол-во мтеодов в iniStorage'e ?? тогда почему бы не разбить MySerializer на два класс:
MySaver
{
Initialize(IStorage storage);
void Serialize(string key, object graph);
}

MyLoader
{
Initialize(IStorage storage);
object Deserialize(string key, Type objectType);
}
вроде кол-во методов в кадом классе уменьшилось??


ВВ>Возьмем более банальный пример. У тебя IniFileStorage используется не только напрямую, но и в обобщенном коде — в том же сериализаторе, — которому генерик методы неудобны. И он их никогда не будет вызывать. Другой программист, работающий вместе с тобой, может не знать об этом поведении и также о том, что согласно твоим принципам дизайна SetValue и SetValue<> должны делать абсолютно одно и то же, чтобы все правильно работало. А не знать он может просто потому, что такие паттерны науке неизвестны. И вот он возьмет и добавит какой-нибудь специфичный код в SetValue<>, который согласно новым требованиям должен бы выполняться всегда, но будет работать лишь время от времени, когда вызывается SetValue<>, а не SetValue. А ведь "старые" клиенты вообще не подозревают о существовании SetValue<>.


А терь предположим что метод SetValue<> реализован не в INiStorage а в другом классе. И "другой программист возьмет и добавит какой-нибудь специфичный код в SetValue<>, который согласно новым требованиям должен бы выполняться всегда, но будет работать лишь время от времени, когда вызывается SetValue<>, а не SetValue. А ведь "старые" клиенты вообще не подозревают о существовании SetValue<>."

что изменилось??
Re[3]: Почему плохо иметь много паблик методов?
От: Воронков Василий Россия  
Дата: 24.11.09 16:26
Оценка:
Здравствуйте, Jack128, Вы писали:

J>лудше. Только я не понял, ты выделил отдельный класс сериализатора — только для того чтобы уменьшить кол-во мтеодов в iniStorage'e ?? тогда почему бы не разбить MySerializer на два класс:

J>MySaver
J>{
J> Initialize(IStorage storage);
J> void Serialize(string key, object graph);
J>}

J>MyLoader

J>{
J> Initialize(IStorage storage);
J> object Deserialize(string key, Type objectType);
J>}
J>вроде кол-во методов в кадом классе уменьшилось??

Ну объясни мне тогда согласно каким принципам ты произвел это разделение и в каких ситуациях оно может помочь.

J>А терь предположим что метод SetValue<> реализован не в INiStorage а в другом классе. И "другой программист возьмет и добавит какой-нибудь специфичный код в SetValue<>, который согласно новым требованиям должен бы выполняться всегда, но будет работать лишь время от времени, когда вызывается SetValue<>, а не SetValue. А ведь "старые" клиенты вообще не подозревают о существовании SetValue<>."

J>что изменилось??

Изменилось то, что в первом случае "другой программист" сделает то, что от него и требуется — реализует функционал в классе, за этот функционал отвечающем.
Во втором случае больной на голову программист реализует логику в экстеншине, созданном исключительно ради "удобного доступа" к другому функционалу.
Re[4]: Почему плохо иметь много паблик методов?
От: Jack128  
Дата: 24.11.09 18:10
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

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

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

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

J>>А терь предположим что метод SetValue<> реализован не в INiStorage а в другом классе. И "другой программист возьмет и добавит какой-нибудь специфичный код в SetValue<>, который согласно новым требованиям должен бы выполняться всегда, но будет работать лишь время от времени, когда вызывается SetValue<>, а не SetValue. А ведь "старые" клиенты вообще не подозревают о существовании SetValue<>."

J>>что изменилось??

ВВ>Изменилось то, что в первом случае "другой программист" сделает то, что от него и требуется — реализует функционал в классе, за этот функционал отвечающем.


он реализует функционал в соответствующем классе, но не в том методе.

ВВ>Во втором случае больной на голову программист реализует логику в экстеншине, созданном исключительно ради "удобного доступа" к другому функционалу.


и в первом и во втором случае программист косячит.
Re[5]: Почему плохо иметь много паблик методов?
От: Воронков Василий Россия  
Дата: 24.11.09 18:24
Оценка:
Здравствуйте, Jack128, Вы писали:

J>я произвел деление по принципу уменьшения кол-ва паблик методов в каждом классе. чем и в каких ситуациях это может помочь я не знаю. я как раз пытаюсь это выяснить в этой теме.


Тебе и пытаются объяснить, что нет такой задачи как "уменьшить количество паблик методов в классе". Паблик методов должно быть ровно столько, сколько нужно. Но не меньше. И не больше.

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

Т.е. я не решал задачу "уменьшить количество паблик методов", у меня ее просто не было. Я показал, к каким проблемам может привести подход, при котором мы не задумываемся над такими умными понятиями как декомпозиция, SRP и пр., а просто лепим все в один класс — ибо если нужно, остальные и так разберутся.

ВВ>>Изменилось то, что в первом случае "другой программист" сделает то, что от него и требуется — реализует функционал в классе, за этот функционал отвечающем.

J>он реализует функционал в соответствующем классе, но не в том методе.

Почему не в том? Как узнать, какой тот? По мне так SetValue(object) выглядит вообще несколько deprecated по сравнению с SetValue<T>(T val). Может, первый просто забыли удалить? Или это тупо легаси?

ВВ>>Во втором случае больной на голову программист реализует логику в экстеншине, созданном исключительно ради "удобного доступа" к другому функционалу.

J>и в первом и во втором случае программист косячит.

Это точно. Вопрос только в том, какой именно программист косячит в первом и во втором случае.
Re: Почему плохо иметь много паблик методов?
От: crable США  
Дата: 24.11.09 19:23
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Один авторитетный, судя по рейтингу, rsdn'овиц заявил сабж. Кто ниту может объяснить почему так?


На эту тему есть хорошая статья у Скотта Майерса. Если кратко, то чем больше методов у класса тем больше кода, который зависит от его внутренностей, т.е. тем хуже инкапсуляция со всеми вытекающими. Впрочем, если в документации к классу указано, что некоторый метод является просто обёрткой для другого метода и все изменения проходят через ревью, проблем может и не будет.
The last good thing written in C was Franz Schubert's Symphony No. 9.
Re[6]: Почему плохо иметь много паблик методов?
От: Jack128  
Дата: 24.11.09 19:32
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

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


J>>я произвел деление по принципу уменьшения кол-ва паблик методов в каждом классе. чем и в каких ситуациях это может помочь я не знаю. я как раз пытаюсь это выяснить в этой теме.


ВВ>Тебе и пытаются объяснить, что нет такой задачи как "уменьшить количество паблик методов в классе".


Jack128>> а чем плохо иметь много публичных мемберов?? Вот System.Linq.Enumerable имеет ну просто дохера методов и вроде пока жив-здоров. Control тоже..

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

http://www.rsdn.ru/forum/dotnet/3613028.1.aspx
Автор: Воронков Василий
Дата: 23.11.09


ВВ>>>Изменилось то, что в первом случае "другой программист" сделает то, что от него и требуется — реализует функционал в классе, за этот функционал отвечающем.

J>>он реализует функционал в соответствующем классе, но не в том методе.

ВВ>Почему не в том? Как узнать, какой тот? По мне так SetValue(object) выглядит вообще несколько deprecated по сравнению с SetValue<T>(T val). Может, первый просто забыли удалить? Или это тупо легаси?


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