Как правильно использовать свойства (properties)?
От: 24  
Дата: 27.08.10 17:11
Оценка:
Если свойство представляет собой геттер и сеттер, которые просто читают и пишут в приватную переменную — это и выглядит, и работает в точности, как публичное поле. Публичные поля — не есть хорошо.

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

Ещё один неприятный момент. Если геттер возвращает структуру по значению, то при записи

obj.size.x = 5;

изменится не то, что ожидается, а поле x временной возвращённой структуры, что не изменит obj. А чтоб изменило, надо писать как-то так (что убивает все преимущества "сахарности" свойств):

Rect size = obj.size;
size.x = 5;
obj.size = size;


При этом, если не использовать свойства, то в случае такого аналога первой записи

obj.getSize().setX(5);

намного лучше видно, что может произойти не то, что хотелось.

Собстенно, а зачем нужны свойства? Пока я вижу только недостатки. Как их правильно использовать, чтоб они приносили упрощение, а не усложнение?
Re: Как правильно использовать свойства (properties)?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 27.08.10 17:33
Оценка:
Здравствуйте, 24, Вы писали:

24>Ещё один неприятный момент. Если геттер возвращает структуру по значению, то при записи


24>
24>obj.size.x = 5;
24>

24>изменится не то, что ожидается, а поле x временной возвращённой структуры, что не изменит obj.

В C# и VB.NET такое не скомпилируется.
Re: Как правильно использовать свойства (properties)?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.08.10 17:34
Оценка: +1
Здравствуйте, 24, Вы писали:

24>Если свойство представляет собой геттер и сеттер, которые просто читают и пишут в приватную переменную — это и выглядит, и работает в точности, как публичное поле. Публичные поля — не есть хорошо.

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

24>Если в геттере и сеттере производится что-то ещё, кроме записи и чтения переменной, то нарушается "принцип наименьшего удивления" — оно выглядит, как присваивание, а на самом деле это вызов функции. По-моему, лучше не вносить дополнительные сложности — если что-то выглядит как присваивание, это и должно работать, как просто присваивание. А если это вызов функции, то он должен выглядеть как вызов функции, а не маскироваться под что-то ещё.

Оно обычно так и делается.

24>Ещё один неприятный момент. Если геттер возвращает структуру по значению, то при записи


24>
24>obj.size.x = 5;
24>

24>изменится не то, что ожидается, а поле x временной возвращённой структуры, что не изменит obj.
Компилятор C# ругнется на такое.

24>Собстенно, а зачем нужны свойства? Пока я вижу только недостатки. Как их правильно использовать, чтоб они приносили упрощение, а не усложнение?

В чем усложнение? В том что если вдруг свойство будет возвращать сложный изменяемый value type то придется написать лишнюю строчку? Посчитай сколько изменяемых value type в .NET FW (довольно мало), кроме того гайдлайны говорят что и не надо такие делать.

Если ты считаешь что неиспользование свойств даст упрощение, то попробуй реализовать таким образом MVVM паттерн.

Или напиши без свойств выражение x.A = (y.B += 1) + 2;
Re[2]: Как правильно использовать свойства (properties)?
От: 24  
Дата: 27.08.10 17:52
Оценка:
Здравствуйте, gandjustas, Вы писали:

24>>Если в геттере и сеттере производится что-то ещё, кроме записи и чтения переменной, то нарушается "принцип наименьшего удивления" — оно выглядит, как присваивание, а на самом деле это вызов функции. По-моему, лучше не вносить дополнительные сложности — если что-то выглядит как присваивание, это и должно работать, как просто присваивание. А если это вызов функции, то он должен выглядеть как вызов функции, а не маскироваться под что-то ещё.

G>Оно обычно так и делается.
Что так и делается?

G>Если ты считаешь что неиспользование свойств даст упрощение, то попробуй реализовать таким образом MVVM паттерн.

Я не знаю, что это за паттерн. А в чём именно выражается сложность его реализации без свойств?

G>Или напиши без свойств выражение x.A = (y.B += 1) + 2;

Часто ты такое пишешь в рабочем коде? Имхо, выражения типа += внутри других не стоит использовать. Тем более, что названия полей обычно не А и В (да и объекты не х и у), а слова подлиннее, поэтому у такой одной строчки есть шансы стать слишком длинной.

Хоть пример достаточно искусственный, но без свойств примерно так:
y.addB(1);
x.setA(y.getB() + 2);
Re[2]: Как правильно использовать свойства (properties)?
От: 24  
Дата: 27.08.10 17:57
Оценка:
Здравствуйте, nikov, Вы писали:

N>В C# и VB.NET такое не скомпилируется.


В Objective-C кажется скомпилится, но точно не помню. Как доберусь до макоси, проверю.
Re: Как правильно использовать свойства (properties)?
От: tripol  
Дата: 27.08.10 18:44
Оценка:
Здравствуйте, 24, Вы писали:

24>Если свойство представляет собой геттер и сеттер, которые просто читают и пишут в приватную переменную — это и выглядит, и работает в точности, как публичное поле. Публичные поля — не есть хорошо.


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

Свойства вводят дополнительный уровень независимости классов друг от друга и это положительно
сказывается на модели приложения.
Re[2]: Как правильно использовать свойства (properties)?
От: 24  
Дата: 27.08.10 19:14
Оценка:
Здравствуйте, tripol, Вы писали:

T>Свойство в отличие от полей может выражать комплексное состояние объекта, описание

T>которого излишне выражать с помощью дополнительных переменных, кроме того с помощью
T>свойства это состояние может изменяться внешне очень легко.

T>Свойства вводят дополнительный уровень независимости классов друг от друга и это положительно

T>сказывается на модели приложения.

То же самое можно сказать применительно к геттерам/сеттерам, только они это делают более явно, а не прячутся за синтаксисом обычной переменной.
Re[3]: Как правильно использовать свойства (properties)?
От: tripol  
Дата: 27.08.10 19:20
Оценка:
Здравствуйте, 24, Вы писали:

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


T>>Свойство в отличие от полей может выражать комплексное состояние объекта, описание

T>>которого излишне выражать с помощью дополнительных переменных, кроме того с помощью
T>>свойства это состояние может изменяться внешне очень легко.

T>>Свойства вводят дополнительный уровень независимости классов друг от друга и это положительно

T>>сказывается на модели приложения.

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


Ну так как мы по обычным правилам ООП переменные не расшариваем, то в этом случае очевидно, что используется
свойство а не переменная.
Re[4]: Как правильно использовать свойства (properties)?
От: 24  
Дата: 27.08.10 19:41
Оценка:
Здравствуйте, tripol, Вы писали:

T>Ну так как мы по обычным правилам ООП переменные не расшариваем, то в этом случае очевидно, что используется

T>свойство а не переменная.

1. Обычные правила ООП может кто-то нарушить, поэтому нельзя полностью полагаться, что они всегда выполняются.
2. А если запись в виде свойства использована внутри самого класса? Там-то доступ есть ко всему.
С явными вызовами get*() и set*() путаницы не возникает в обоих случаях: если это выглядит, как переменная — это гарантированно переменная, независимо от того, все ли выполняют правила ООП, и где это записано (внутри класса или снаружи.)
Re[5]: Как правильно использовать свойства (properties)?
От: tripol  
Дата: 27.08.10 19:51
Оценка:
Здравствуйте, 24, Вы писали:

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


T>>Ну так как мы по обычным правилам ООП переменные не расшариваем, то в этом случае очевидно, что используется

T>>свойство а не переменная.

24>1. Обычные правила ООП может кто-то нарушить, поэтому нельзя полностью полагаться, что они всегда выполняются.


Даже если кто то и откроет переменную, то тут скорее его проблема, конечно get/set функции дают несколько больше гарантий,
однако если подумать, то и, допустим, set*() может быть реализован некорректно или не по каким правилам.

24>2. А если запись в виде свойства использована внутри самого класса? Там-то доступ есть ко всему.

24>С явными вызовами get*() и set*() путаницы не возникает в обоих случаях: если это выглядит, как переменная — это гарантированно переменная, независимо от того, все ли выполняют правила ООП, и где это записано (внутри класса или снаружи.)

Если внутри класса, то тут уже нужно ориентироваться самому что где или не лезть, кроме того переменные члены класса
обычно обозначаются как m_*

Подведя итог, можно сказать, что как и в обычном языке больше "слов" дает возможность более лаконичней и богаче
выражаться что есть гуд.
Re[6]: Как правильно использовать свойства (properties)?
От: 24  
Дата: 27.08.10 20:03
Оценка:
Здравствуйте, tripol, Вы писали:

T>Даже если кто то и откроет переменную, то тут скорее его проблема

Тут моя проблема, т.к. я буду думать, что это свойство.

T>Если внутри класса, то тут уже нужно ориентироваться самому что где или не лезть, кроме того переменные члены класса

T>обычно обозначаются как m_*
Опять же, тут мы рассчитываем на выполнение неких дополнительных требований. И если они вдруг не выполнятся, то можно очень долго искать ошибку, т.к. она будет находиться в наименее ожидаемом месте.

T>Подведя итог, можно сказать, что как и в обычном языке больше "слов" дает возможность более лаконичней и богаче

T>выражаться что есть гуд.
Я бы не причислял это однозначно к преимуществам, т.к. больше "слов" вносит больше путаницы. Нам же не эмоции надо выражать, а строго описать алгоритм. По-моему лучше иметь один наиболее простой и очевидный способ решения задачи, чем несколько разных (с одной стороны из них можно выбрать один самый удобный для себя, но с другой стороны их всё равно прийдётся знать все, т.к. их могут использовать другие члены команды.)
Re: Как правильно использовать свойства (properties)?
От: fddima  
Дата: 27.08.10 22:03
Оценка: +2
Здравствуйте, 24, Вы писали:

24>Собстенно, а зачем нужны свойства? Пока я вижу только недостатки. Как их правильно использовать, чтоб они приносили упрощение, а не усложнение?

1) Если ваши свойства ничем не отличимы от публичных полей и ведут они себя именно так же как и публичные поля и в дальнейшем не планируется, что-то отличное — то ничего плохого в них нет. Любой DTO — это такой.
2) К сожалению реалии жизни всё равно бывает да стрельнет и нужно вдруг не менять поведение а узнавать о изменении этих самых свойств. — Вот тут-то и красота.
3) Свойства призваны и могут скрывать неинтересную для клиента логику. Например XmlNode.OwnerDocument всегда возвращает документ владеющий данным узлом, но то как оно вычисляется очень зависит от реального объекта.
4) JIT простые свойства очень отлично инлайнит. В итоге это явно удобнее и нагляднее чем тыща get/set методов.
Re[2]: Как правильно использовать свойства (properties)?
От: fddima  
Дата: 27.08.10 22:45
Оценка: +2
Извините, добавлюсь:

obj.getSize().setX(5);

Это чистый бред. Не обижайтесь. get... set... acquire... put... push! pull! эээ и де мы?!?
У obj есть X и Y.
Size — составное свойство из X и Y. Если вы хотите работать с размером то и работайте именно со структурой Size (т.е. и с X и Y сразу). Иногда это имеет смысл. А в вашем примере даже неискушенному пользователю неясно что происходит. Точнее говоря что происходит как раз ясно — мы у obj получаем структуру Size, и методом структуры Size устанавливаем её значение X, которое никак не корреллирует с obj.X. Извиняюсь за кучу ненужных слов. Пьян. =)
Re[3]: Как правильно использовать свойства (properties)?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.08.10 23:33
Оценка: +1
Здравствуйте, 24, Вы писали:

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


24>>>Если в геттере и сеттере производится что-то ещё, кроме записи и чтения переменной, то нарушается "принцип наименьшего удивления" — оно выглядит, как присваивание, а на самом деле это вызов функции. По-моему, лучше не вносить дополнительные сложности — если что-то выглядит как присваивание, это и должно работать, как просто присваивание. А если это вызов функции, то он должен выглядеть как вызов функции, а не маскироваться под что-то ещё.

G>>Оно обычно так и делается.
24>Что так и делается?
Используется принцип. Можно Framework Design Guidelines почитать.

G>>Если ты считаешь что неиспользование свойств даст упрощение, то попробуй реализовать таким образом MVVM паттерн.

24>Я не знаю, что это за паттерн. А в чём именно выражается сложность его реализации без свойств?
Ну узнай что такое MVVM и быстро догадаешься.

G>>Или напиши без свойств выражение x.A = (y.B += 1) + 2;

24>Часто ты такое пишешь в рабочем коде?
Дае чаще, чем mutable структуры

24>Имхо, выражения типа += внутри других не стоит использовать. Тем более, что названия полей обычно не А и В (да и объекты не х и у), а слова подлиннее, поэтому у такой одной строчки есть шансы стать слишком длинной.


24>Хоть пример достаточно искусственный, но без свойств примерно так:

24>y.addB(1);
24>x.setA(y.getB() + 2);
Но у нас операции addB нету, есть get\set, и как ты сам сказал названия полей обычно не А и В.
Re[7]: Как правильно использовать свойства (properties)?
От: tripol  
Дата: 28.08.10 03:45
Оценка:
Здравствуйте, 24, Вы писали:

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


T>>Даже если кто то и откроет переменную, то тут скорее его проблема

24>Тут моя проблема, т.к. я буду думать, что это свойство.
Если переменная открыта, то значит ее можно использовать открыто (а вдруг — нарушение принципа инкапсуляции)
и за это в большинстве случаев руки надо отбивать или вообще такой процедурно-ориентированный код не использовать.

T>>Если внутри класса, то тут уже нужно ориентироваться самому что где или не лезть, кроме того переменные члены класса

T>>обычно обозначаются как m_*
24>Опять же, тут мы рассчитываем на выполнение неких дополнительных требований. И если они вдруг не выполнятся, то можно очень долго искать ошибку, т.к. она будет находиться в наименее ожидаемом месте.
Если лезешь в класс изнутри, то тут проблема имхо не в том, что можешь зацепить не ту переменную,
а смысл в том, что на хрена туда полез и тем более сразу видно в интерфейсе класса что есть что, при этом
это гораздо быстрее обозревается чем понимание самой логики работы класса.

T>>Подведя итог, можно сказать, что как и в обычном языке больше "слов" дает возможность более лаконичней и богаче

T>>выражаться что есть гуд.
24>Я бы не причислял это однозначно к преимуществам, т.к. больше "слов" вносит больше путаницы. Нам же не эмоции надо выражать, а строго описать алгоритм. По-моему лучше иметь один наиболее простой и очевидный способ решения задачи, чем несколько разных (с одной стороны из них можно выбрать один самый удобный для себя, но с другой стороны их всё равно прийдётся знать все, т.к. их могут использовать другие члены команды.)
Не факт, человек знает очень много слов и в этом не вижу особого ограничения для языка программирования — выигрыш
больше по сравнению с более сложным использованием меньшего количества языковых конструкций (одним словом с уменьшением
количества языковых элементов задача передачи информации усложняется)...
Re[3]: Как правильно использовать свойства (properties)?
От: 24  
Дата: 28.08.10 08:29
Оценка:
Здравствуйте, fddima, Вы писали:

F>obj.getSize().setX(5);


F>Это чистый бред. Не обижайтесь. get... set... acquire... put... push! pull! эээ и де мы?!?

F>У obj есть X и Y.
F>Size — составное свойство из X и Y. Если вы хотите работать с размером то и работайте именно со структурой Size (т.е. и с X и Y сразу). Иногда это имеет смысл. А в вашем примере даже неискушенному пользователю неясно что происходит. Точнее говоря что происходит как раз ясно — мы у obj получаем структуру Size, и методом структуры Size устанавливаем её значение X, которое никак не корреллирует с obj.X. Извиняюсь за кучу ненужных слов. Пьян. =)

Этот пример я как раз и приводил, как неправильный. Понятно, что так писать не нужно.
Re[4]: Как правильно использовать свойства (properties)?
От: 24  
Дата: 28.08.10 08:43
Оценка:
Здравствуйте, gandjustas, Вы писали:

24>>>>Если в геттере и сеттере производится что-то ещё, кроме записи и чтения переменной, то нарушается "принцип наименьшего удивления" — оно выглядит, как присваивание, а на самом деле это вызов функции. По-моему, лучше не вносить дополнительные сложности — если что-то выглядит как присваивание, это и должно работать, как просто присваивание. А если это вызов функции, то он должен выглядеть как вызов функции, а не маскироваться под что-то ещё.

G>>>Оно обычно так и делается.
24>>Что так и делается?
G>Используется принцип. Можно Framework Design Guidelines почитать.
Какой принцип? Можешь в двух словах сформулировать?

G>>>Если ты считаешь что неиспользование свойств даст упрощение, то попробуй реализовать таким образом MVVM паттерн.

24>>Я не знаю, что это за паттерн. А в чём именно выражается сложность его реализации без свойств?
G>Ну узнай что такое MVVM и быстро догадаешься.
Ок, посмотрю, что это, может что-то прояснится.

G>>>Или напиши без свойств выражение x.A = (y.B += 1) + 2;

24>>Часто ты такое пишешь в рабочем коде?
G>Дае чаще, чем mutable структуры
Ответ в стиле "Где мы? — На воздушном шаре."
"Чаще, чем ххх" мне ни о чём не говорит, т.к. я не знаю, как часто используется ххх, да и насколько часто тоже неясно.

24>>y.addB(1);

24>>x.setA(y.getB() + 2);
G>Но у нас операции addB нету, есть get\set, и как ты сам сказал названия полей обычно не А и В.
Кто мешает эту операцию добавить, или в зависимости от задачи, написать по-другому? Я же не призываю бездумно заменить свойства на явный вызов их гет и сет меторов. С использованием свойств и без них нужно применять разные подходы, вот мне и интересно, в каких именно случаях свойства принесут удобство и упрощение.
Re[8]: Как правильно использовать свойства (properties)?
От: 24  
Дата: 28.08.10 08:50
Оценка:
Здравствуйте, tripol, Вы писали:

T>и за это в большинстве случаев руки надо отбивать или вообще такой процедурно-ориентированный код не использовать.

Согласен, надо. Но задача выявления таких случаев усложняется, если используются свойства.

T>на хрена туда полез

Полез туда, чтоб написать логику класса (или дописать.) Классы же сами не появляются.

T>выигрыш больше по сравнению с более сложным использованием меньшего количества языковых конструкций

Далеко не всегда меньшее кол-во языковых конструкций вносит бОльшую сложность.
Re[9]: Как правильно использовать свойства (properties)?
От: tripol  
Дата: 28.08.10 09:11
Оценка:
Здравствуйте, 24, Вы писали:

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


T>>и за это в большинстве случаев руки надо отбивать или вообще такой процедурно-ориентированный код не использовать.

24>Согласен, надо. Но задача выявления таких случаев усложняется, если используются свойства.
Вообще задача такая хитро не стоит, поскольку как правило библиотеки сопровождаются документацией
а без нее хитрый звиздец появляется

T>>на хрена туда полез

24>Полез туда, чтоб написать логику класса (или дописать.) Классы же сами не появляются.
Ну первое что надо смотреть — интерфейс класса и тут крайне сложно не заметить публичных переменных.

T>>выигрыш больше по сравнению с более сложным использованием меньшего количества языковых конструкций

24>Далеко не всегда меньшее кол-во языковых конструкций вносит бОльшую сложность.
Из теории информации что бы передать то же количество информации меньшим набором символов(слов),
то необходимо больше их комбинаций — отсюда большая сложность конструкции (так сказать
попробуй объясни африканцу что такое снег, если он не знает такого слова)...
Re[10]: Как правильно использовать свойства (properties)?
От: 24  
Дата: 28.08.10 10:34
Оценка:
Здравствуйте, tripol, Вы писали:

24>>Далеко не всегда меньшее кол-во языковых конструкций вносит бОльшую сложность.

T>Из теории информации что бы передать то же количество информации меньшим набором символов(слов),
T>то необходимо больше их комбинаций — отсюда большая сложность конструкции
Чрезмерное количество символов (слов) к упрощению не приведёт, нужно соблюдать какой-то баланс. Станет ли проще, если в алфавите будет не 33 буквы, а миллион, и средняя длина слова — один-два символа?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.