Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Properties, полезны ли они? 
:(
    Опции темы
Дрон
  Дата 20.6.2005, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 24
Всего: 92



Вот в теме "Что такое C#?" тов. Domestic Cat со свойственным ему рвением ругает properties.

Цитата(Domestic @ 20.6.2005, 19:34)
Писать на десяток символов меньше, и объединены гет/сет в один блок. Больше ничем. Зато появляется еще одна конструкция, усложняется документация. Если все на методах, то я, когда хочу что-то сделать, могу угадать название метода. А с пропертями мне нужно искать и в свойствах, и в методах. В результате я делаю мизерную экономию на наборе текста, но компенсирую это поиском в доках.
Если учесть, что почти любая ИДЕ дает возможность сгенерить гет/сет методы, то вообще преимущество пропертей я не вижу...


Дабы не разводить оффтоп, решил создать отдельную тему, чтобы окончательно разрулить ситуацию smile

По-моему проперти для меня облегчают понимание кода, так как обычно их суть в том, чтобы по необходитмость проинициализировать/вычислить какое-либо значение и вернуть его пользователю. Мне психологически приятней писать:
Код
Color = Colors.Black;

чем
Код
setColor(Colors.Black);

Так как здесь очевидно, что свойству объекта присваивается какое-то значение.

Кроме того, отделение свойств от методов позволило создать такой компонент как PropertyGrid (хотя он, конечно, далёк от идеала smile ).

Сейчас мне некогда, но по-позже, с радостью попытаюсь обсудить объективные преимущества и недостатки этих подходов smile


--------------------
Да. Именно так.
PM   Вверх
arilou
Дата 20.6.2005, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Великий МунаБудвин
****


Профиль
Группа: Экс. модератор
Сообщений: 2646
Регистрация: 15.7.2004
Где: город-герой Минск

Репутация: 21
Всего: 61



Праально говоришь! Properties следюут принципу black-box - класс выставляет интерфейс взаимодействия с ним. Свойства:
1) Контролируют доступ к полям (раз есть поля, почему бы не быть оберткам вокруг них?)
2) Дают возможность реализовать некоторое поведение при обращении к ним, например lazy load при get, и вызов события вида "PropertyChanged" при set)


--------------------
user posted imageuser posted image
PM WWW ICQ   Вверх
Domestic Cat
Дата 20.6.2005, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 9
Всего: 172



Ну вообще то если мы следуем принципам ОО то ситуация такая
1. Инкапсуляция: Отделение интерфейса (видимых методов) от имплементации (свойств объекта, его внутренней структуры) Проще говоря, поля объектов должны мыть максимум protected, publicом могут быть только константы.
2. Программа есть набор взаимодействующих объектов. Взаимодействие осуществляется путем пересылки сообщений - посредством методов. То есть, например myObject.setColor(Colors.Black) по сути есть отсылка сообщения объекту myObject. Как и что далее будет делать с этим сообщением объект - его дело, он для остальных объектов "черный ящик".

Микрософт попытался с введением свойств выделить методы, которые должны (по идее) менять какие-то свойства объекта. То есть, а.Color = Colors.Black меняет свойство объекта а, а например метод а.Resize() чего-то сделает с объектом.

Почему мне это не нравицца:
1. Не всегда однозначно можно отнести метод к той или иной группе. Например, GetHashCode(). Он реализован как метод, но ведь он также может быть рассмотрен и как свойство объекта.
2. Несмотря на то, что авторы FCL, видимо, следовали описанным выше принципам, никто не мешает им НЕ следовать. Возьмем проперти Environment.CurrentDirectory. Посмотрите, что оно делает - меняет текущую рабочую директорию. Почему это не метод? Тот же Resize - почему он не проперти Size?
3. Каков выигрыш от подобного разделения на свойства и методы? Что конкретно выиграно? Усложнены язык и документация, можно писать левый код, используя проперти там, где нужен метод, и наоборот. А выигрыша то нет, поиск по докам забирает (для меня по крайней мере) больше времени.
4. Какой конкретно ОО принцип реализует подобное нововведение? По-моему оно скорее противоречит ОО принципам, поскольку у пользователя создается впечатление, что свойства объекта меняются напрямую, тогда как суть не изменилась - внутри get{} set{} по-прежнему можно делать все что угодно. Вызов метода однозначно свидетельствует об отсылке сообщения, тогда как a.Number = 2
может означать как вызов метода set_Number() так и изменения паблик поля объекта.


--------------------

PM   Вверх
arilou
Дата 20.6.2005, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Великий МунаБудвин
****


Профиль
Группа: Экс. модератор
Сообщений: 2646
Регистрация: 15.7.2004
Где: город-герой Минск

Репутация: 21
Всего: 61



Domestic Cat
Мне кажется, ту штука, котрорую ты не учитываешь - это то, что свойства дают возможность реализовать поля со сложным поведением. Т.е. никто не отменяет правила того, что программист должен думать, когда применять метод, а когда - свойство. ИМХО, поля вообще не должны быть public, потому что это как раз и будет нарушением инкапсуляции (спасибо, что напомнил, как называется то, о чем я писал постом выше).

Поэтому и создана отдельная сущность "свойство", которая выглядит как поле, но дает возможность определять поведение.


--------------------
user posted imageuser posted image
PM WWW ICQ   Вверх
Дрон
Дата 20.6.2005, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 24
Всего: 92



По 1, 2 согласен. Только что-то я не припомню метода Resize. Проперти Size -- есть smile
По 3 -- не знаю, меня это совсем не напрягает.
По 4 -- это уже фанатизм, батенька. Чистое ООП -- это же самая мерзкая бюрократия, которую только можно придумать... Не дай Бог, так и в жизни будет smile


ЗЫ: Я сейчас разбираюсь с X++ (Microsoft Axapta), так там вообще доступа к переменным класса извне нет! Только через методы. Причём нет разделения на гет и сет -- один метод с необязательным параметром smile

Это сообщение отредактировал(а) Дрон - 20.6.2005, 20:18


--------------------
Да. Именно так.
PM   Вверх
Domestic Cat
Дата 20.6.2005, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 9
Всего: 172



Цитата(arilou @ 20.6.2005, 11:17)
Поэтому и создана отдельная сущность "свойство", которая выглядит как поле, но дает возможность определять поведение


Дык я и хочу сказать, что в таком случае это выглядит как изменение поля, тогда как на самом деле это отсылка сообщения объекту, т.е. то же самое, что и метод.
Добавлено @ 20:30
Цитата
Только что-то я не припомню метода Resize. Проперти Size -- есть


Это для примера было, хотя вообще-то и такое есть:
http://www.bluebit.gr/NET/Library/index.as...tor-Resize.html

Вот другой пример: Control.Focus() - метод. Почему он не свойство (Focus = true) ?
С др. стороны: Control.Size - свойство, почему оно не метод?
В чем принципиальное отличие? И Focus, и Size меняют некие характеристики объекта - его размер и наличие фокуса.


--------------------

PM   Вверх
AntonSaburov
Дата 20.6.2005, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: 6
Всего: 118



Меня лично смущает только одно - я не вижу точно, что я делаю. Вызываю ли я метод или меняю переменную.

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

Но вся штука в том, что неоднократно встречал открытые поля, которые менять хорошо бы через методы, но тем не менее их видно. Бывает, что поле вообщем-то и хорошо, что открыто.
И вот тут возникает неоднозначность - все-таки что я меняю ? Проперть или просто поле. Каждый раз я должен быть внимателен и осторожен. И если проперти делались для того, чтобы в какой-то степени облегчить мою жизнь, то я как раз вижу обратное.
Без пропертей все ясно и очевидно - это поле или метод. Никаких неоднозначностей.
PM MAIL WWW ICQ   Вверх
arilou
Дата 20.6.2005, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Великий МунаБудвин
****


Профиль
Группа: Экс. модератор
Сообщений: 2646
Регистрация: 15.7.2004
Где: город-герой Минск

Репутация: 21
Всего: 61



Интересная штука получается...
Цитата(AntonSaburov @ 20.6.2005, 20:32)
я не вижу точно, что я делаю

Ну ты же сам принимаешь решение о том, чтобы сделать свойство или метод, так? Т.е. ты чувствуешь, когда нужно одно, а когда другое?

Вот например у меня. Есть реестр инстансов определенных классов. Мне нужно достать оттуда какой-нить инстанс по ключу. Я определяю индексатор (обычное свойство с параметром), и внутри него достаю нужный мне объект из hashtable. Почему свойство? Потому что
1) мне кажется, что данная операция не является посылкой сообщения классу
2) индексатор в данном случае - понятийное свойство реестра, его характеристика вида "содержимое реестра для данного ключа" (постарайтесь понять мою мысль прежде чем спорить о том, характеристика это или нет)

Другой пример. У меня есть бизнес-объекты. Они ссылаются на другие бизнес-объекты. Например, есть сущность User, которая содержит ссылку на сущность Role. Role в данном случае - характеристика User, а это значит, что она реализуется в виде свойства Role, а не метода getRole(). Соответственно, если я хочу сменить роль пользователю, то я меняю его характеристику, а не посылаю ему сообщение "смени роль", это я решаю выполнить эту оперецию, а не сама сущность "пользователь".

Вот если бы я хотел сделать, чтобы пользователь мог сменить роль какого-то другого пользователя, то я бы сделал метод setUserRole(user, newRole), а в нем проверял бы, может исполнитель сменить роль другого пользователя, или нет. Или более того, я бы вынес это в сервисный класс, и сделал бы метод там setUserRole(performedBy, targetUser, newRole)

Вот мое видение свойств. Буду ждать комментов.


--------------------
user posted imageuser posted image
PM WWW ICQ   Вверх
Domestic Cat
Дата 20.6.2005, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 9
Всего: 172



Цитата(arilou @ 20.6.2005, 12:03)
Role в данном случае - характеристика User, а это значит, что она реализуется в виде свойства Role, а не метода getRole().


Не понимаю. Свойство - это то же что и метод, реализация свойства в IL - это методы get_XXX, set_XXX.
И в ООП ничего, кроме отсылки сообщений нет.
Объясни мне разницу между Role и getRole?
Цитата(arilou @ 20.6.2005, 12:03)
Соответственно, если я хочу сменить роль пользователю, то я меняю его характеристику, а не посылаю ему сообщение "смени роль", это я решаю выполнить эту оперецию, а не сама сущность "пользователь".

Ну так нигде в ООП нет разделениай на то, что, кто и как должен делать. Ты отсылаешь сообщение - а далее ОБъЕКТ решает какие действия предпринять. И в случае с методами, и в случае со свойствами.


Цитата(arilou @ 20.6.2005, 12:03)
Вот если бы я хотел сделать, чтобы пользователь мог сменить роль какого-то другого пользователя, то я бы сделал метод setUserRole(user, newRole),


Давай так: каковы четкие правила, где применят; свойство, а где - метод. И объясни мне тода мои примеры насчет реализаций в FCL smile
И какие выгоды дает это разделение.


--------------------

PM   Вверх
Domestic Cat
Дата 20.6.2005, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 9
Всего: 172



Цитата(arilou @ 20.6.2005, 12:03)
Ну ты же сам принимаешь решение о том, чтобы сделать свойство или метод, так? Т.е. ты чувствуешь, когда нужно одно, а когда другое?

Кстати, ведь не всегда пользуешь код, который сам писал. Да и невозможно в любом случае упомнить все. Просто обозначения для изменения паблик полей и свойств одинаковые, а суть-то разная.


--------------------

PM   Вверх
Дрон
Дата 20.6.2005, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 24
Всего: 92



Цитата(AntonSaburov @ 20.6.2005, 21:32)
Без пропертей все ясно и очевидно - это поле или метод

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

Цитата(Domestic @ 20.6.2005, 22:15)
Объясни мне разницу между Role и getRole?

Читать приятней smile
role = SomeUser.Role; читается как: присвоить переменной role значение Role объекта SomeUser
С методом оно читалось бы: присовить переменной роль, значение возвращаемое методом getRole, что ИМХО уже не так естественно.


--------------------
Да. Именно так.
PM   Вверх
mr.DUDA
Дата 20.6.2005, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Domestic Cat, одна из выгод от применения пропертей состоит в том, что "свойство" воспринимается как "поле", и наоборот, т.е. я в любой момент могу заменить любое public-поле или константу класса на вычисляемое св-во, не переписывая ни строчки кода.

Ещё пример. Свойство может представлять из себя ресурс "по требованию", т.е. инициализировать и возвращать значение при первом запросе.

Другой пример. Паттерн "singleton" с использованием свойств воспринимается в коде намного естественнее, чем с использованием методов: Class.Instance.DoSomething() против Class.getInstance().DoSomething().

Наконец, пиная майкрософт, нужно обратить внимание на open-source разработчиков: почему-то все поголовно используют проперти на шарпе, см. хотя бы CodeProject.


--------------------
user posted image
PM MAIL WWW   Вверх
Domestic Cat
Дата 21.6.2005, 01:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 9
Всего: 172



Цитата(mr @ 20.6.2005, 14:37)
Class.Instance.DoSomething() против Class.getInstance().DoSomething().


Обясняю позицию:
myObject.methodA().methodB() расшифровывается так:

Взять объект myObject и отослать ему сообщение methodA(), возвращаемому значению отослать сообщение methodB()

myObject.A.methodB()
Свойству объекта myObject отослать сообщение methodB().

Теперь вот такой вопрос: первая реализация через методы абсолютно абстрагируется от природы возвращаемого значения после вызова methodA. Вторая реализация фактически читается как "взять нечто, принадлежащее объекту myObject и передать ему сообщение".
Заметьте, вторая ситуация ограничивает девелопера - это будет "правильно" только если A является действительно полем объекта myObject. Но ведь если например мы меняем реализацию, и теперь А хранится не как поле, а создается в методе set{} - все, проперти перестало быть свойством и должно по логике стать методом.
ТЕперь, какие преимущества?
1. Удобство?
Разница между Class.Instance.DoSomething() и Class.getInstance().DoSomething() - две скобки.
2. Что еще? Ну хорошо, свойство говорит мне о том, что А - это некое поле объекта. Ну и что? Собственно, мне не должно быть никакого дела, поле это, или еще что. Логика ведь не зависит от того, присваиваю я значение пропертям или вызываю методы.

Цитата(mr @ 20.6.2005, 14:37)
Наконец, пиная майкрософт, нужно обратить внимание на open-source разработчиков: почему-то все поголовно используют проперти на шарпе, см. хотя бы CodeProject.

Дык, мало ли что используют. Вижуал Васик 6 тоже довольно популярен smile Это шутка, я не сравниваю Васик со свойствами, просто если добавить в язык что-то, это что-то обязательно будут пользовать.


--------------------

PM   Вверх
mr.DUDA
Дата 21.6.2005, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(Domestic @ 21.6.2005, 01:19)
myObject.methodA().methodB() расшифровывается так:

Взять объект myObject и отослать ему сообщение methodA(), возвращаемому значению отослать сообщение methodB()

Ну почему обязательно "сообщения"?

Цитата(Domestic @ 21.6.2005, 01:19)
myObject.A.methodB()
Свойству объекта myObject отослать сообщение methodB().

Не "свойству объекта", а "возвращаемому свойством значению" отослать сообщение. Что же здесь "не так" ?

Цитата(Domestic @ 21.6.2005, 01:19)
... просто если добавить в язык что-то, это что-то обязательно будут пользовать.

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

Кстати, почему бы нашим уважаемым оппонентам не вспомнить о линейке продуктов Borland (CBuilder, Delphi), о языках, средах разработки, визуальных и прочих компонентах, завязанных на свойства?



--------------------
user posted image
PM MAIL WWW   Вверх
Domestic Cat
Дата 21.6.2005, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 9
Всего: 172



Цитата(mr @ 21.6.2005, 00:12)
Ну почему обязательно "сообщения"?

Потому, что это принятая в ООП терминология.

Цитата(mr @ 21.6.2005, 00:12)
Не "свойству объекта", а "возвращаемому свойством значению" отослать сообщение. Что же здесь "не так" ?

"возвращаемому свойством значению" - звучит очень похоже на "возвращаемому методом значению" smile То есть по-твоему свойство - это скорее метод ?

Цитата(mr @ 21.6.2005, 00:12)
Неправда, те же индексаторы на том же шарпе используются ну очень редко, т.к. весч довольно специфичная, чего не скажешь о properties.

Ну почему, в FCL много чего на них, особенно АДО, ДатаГрид, и пр.

Цитата(mr @ 21.6.2005, 00:12)
Кстати, почему бы нашим уважаемым оппонентам не вспомнить о линейке продуктов Borland (CBuilder, Delphi), о языках, средах разработки, визуальных и прочих компонентах, завязанных на свойства?

Мы же не о них говорим, правильно? Да и что это доказывает?


--------------------

PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0830 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.