вопрос по ООП

С.

Продвинутый новичок
Давайте вместо:

$i = 0;
...
$arr[$i]= ...;

Везде в программах писать:

setI(0);
...
setArr(getI(), ...);

а то вдруг когда-нибудь кому-нибудь побнадобится сделать что-нибудь при изменении переменной $i. Или того хуже -отрефакторить этот кусок кода.

Против рефакторинга, как кодеровского аргумента-лома, нет приема.
 

Rammstein

PHPClub::News
Я использую методы только потому, что можно в @return указать тип возвращаемого объекта :)
На самом деле редко приходится переделывать get и set методы (т.е. впрнципе можно пользоваться полями).
Другой момент заключается в том, что возможно (вследствии какого-то внешнего фактора) придётся менять имя поля, и тогда...
А какая собстна сложность написать
PHP:
$UD->getUserId();
вместо
PHP:
$UD->user_id;
? Это проявление лени? :)

P.S> Изначально могу заблуждаться, т.к. читал только вторую часть 4 страницы.
 

С.

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

А если человеческими конкретными "микроскопами", то:

1) да, увы, его свойства "связывают/фиксируют", этот объект будет плохо применим для рассматривания кораблей на горизонте, надо писать другой.

2) нет, во внутренности к нему никто не даст лезть и ничего не связывает. Он может оказаться внутрях и оптическим, и электронным. А интерфейс всегда остается прежним, независимо от того, построен ли он на свойствах или методах.

3) практика написания классов типа "Новое устройство с электронно-графическо-оптическими настраиваемыми алгоритмами и характеристиками" (сокращенно НУЕГОНАХ) популярностью не пользуются.

-~{}~ 13.01.07 20:59:

Другой момент заключается в том, что возможно (вследствии какого-то внешнего фактора) придётся менять имя поля, и тогда...
Реальный пример?
 

Rammstein

PHPClub::News
С.
ORM. Автоматом мапит поля БД на поля объекта. Переходим на другую БД - имя поля зарезервировано, меняем имя в БД, меняется и имя поля объекта => переделываем всё что раньше обращалось к свойству (это слово мне больше нравится) объекта.
Если бы всё было в функции, там работы на пару секунд.
Т.е. это яркий пример, когда интерфейс отделён от данных и это оправдано. Так же, возможно понадобится вместо значения возвращать объект, основанный на этом значении (DateTime яркий пример).
 

Bermuda

Новичок
Следует помнить, что "технолигии" с неба не падают и не переданы нам внеземной цивилизацией. Все это придумано людьми и для людей. Не зря класс называется классом, объект объектом, свойства свойствами и методы методами. Классы это проекция _реального_ мира на язык программирования.

А потому вернемся в реальный мир.

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

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

А вот если бы можно было самого кота попросить изменить свой цвет, а также рассказать какого он цвета в данный момент, если бы у него были методы "покрасить" и "узнатьЦвет", то эти методы уж помогли бы выкрутится, уж чего-нибудь натрындели. Но разве это логично? Более того, разве котов это волнует?
 

ran

Новичок
Автор оригинала: Bermuda
Но разве это логично? Более того, разве котов это волнует?
Если я правильно понял про котов, то нелогично пользоваться методами.
Хорошо, а как быть, когда понадобится для хранения цвета использовать объект?
Если раньше все нормально работало
PHP:
cat::getColor(){
    return color;
}
То сейчас вернет объект и везде, где это используется придется добавлять color->getColor();
А использоваться это может в многих местах кода.
Аналогичная ситуация и с set методом класса. Также при установке может понадобится дополнительная валидация или наложение какого-то фильтра на тот же цвет(например, преобразование из RGB в CMYK), да и все что угодно.
Если обращаться в большом проекте к public полям, то какая может быть уверенность в том, что данные, которые не должны меняться и проходить обязательную валидацию, какой-то незнакомый в достаточной степени с кодом программист не испортит и на нахождении ошибки будет потрачено лишнее время.
 

hermit_refined

Отшельник
Автор оригинала: grigori
Много лет писал
...
if ($UserData->isRegistered()) ...

Пол-года назад плюнул, теперь пишу
if ($UserData->user_id)
очень жаль. раньше вы писали легко читаемый, понятный без комментариев и независимый от реализации код.

Автор оригинала: С.
Давайте вместо:

$i = 0;
...
$arr[$i]= ...;

Везде в программах писать:

setI(0);
...
предлагается всё-таки не ходить по кругу, и не приплетать опять массивы (я уже отвечал на эту тему grigori). вообще, вы название темы видели?..

С.
grigori
Bermuda
ok. вы упорно опровергаете все аргументы против public свойств (а их вам была уже уйма высказана), насколько успешно - оставим в стороне. вы можете привести разумный аргумент "за"? кроме лени, конечно.
 

Bermuda

Новичок
Автор оригинала: ran
То сейчас вернет объект и везде, где это используется придется добавлять color->getColor();
А использоваться это может в многих местах кода.
Аналогичная ситуация и с set методом класса. Также при установке может понадобится дополнительная валидация или наложение какого-то фильтра на тот же цвет(например, преобразование из RGB в CMYK), да и все что угодно.
Если обращаться в большом проекте к public полям, то какая может быть уверенность в том, что данные, которые не должны меняться и проходить обязательную валидацию, какой-то незнакомый в достаточной степени с кодом программист не испортит и на нахождении ошибки будет потрачено лишнее время.
В данном случае можно сказать, что класс котов был спроектирован неверно. Не буду споорить с тем, что использование сеттеров/геттеров могло бы спати ситуацию, но никто не будет спорить с тем, что подобное решение проблемы это _заплатки_. Не люблю я заплатки. Раньше думать нужно было...

hermit_refined
Классы сделаны людьми и для людей. Классы проекция реальной жизни на программирование. Следовательно, меня интересует вопрос, почему неестественные в реальной жизни вещи, оказываются вполне логичными в программировании. Ведь сами объекты в зависимости от системы координат в которой их рассматривают, не меняются! Пересмотрите пример с котами.
И вообще, не опровергаю я ничего. Пытаюсь играть роль "адвоката дьявола".
 

hermit_refined

Отшельник
Bermuda
вы не высказали аргумента "за", но опять - опровергаете услышанные.
Классы проекция реальной жизни на программирование.
Если коротко - это не так. Да, можно проводить какие-то аналогии, можно даже найти какие-то соответствия в реальном мире таким паттернам, как Singleton, Strategy, Visitor, но при пристальном рассмотрении к ним так же легко придраться, как и придумать. Ключевые понятия ООП - инкапсуляция и полиморфизм, однако в реальности мы всегда знаем, кто перед нами - кот или медведь, даже если нам это и безразлично. Но главное - реальности как таковой не существует, есть лишь наше восприятие неё, и у каждого оно - своё.

Возьмём ваш пример с котами. Раньше меня интересовали только одноцветные коты, а теперь - захотелось коллекционировать и пятнистых. Люди вообще склонны меняться, а уж про их желания и потребности и говорить нечего.

Разумеется, у этих котов появится дополнительный метод - узнать точное распределения пятен и их цвет, но это необходимо лишь при просмотре дополнительной информации о них, в основном же меня интересует только усреднённый цвет, высчитываемый как поверхностный интеграл по всей поверхности кота (если для вас более ценной была бы другая информация - не волнуйтесь, просто у нас с вами разное отношение к реальности). Операция - сами понимаете - затратная, и устанавливать ваше public свойство при загрузке из бд каждого кота (а не все коты достаются, чтобы на них посмотреть, иные - чтобы их накормить и т.д.) - расточительно. Порекомендуете приписывать коту этот усредненный цвет, когда его помещают в бд? Увы, нельзя, раскраска у котов постепенно меняется, особенно у пятнистых, особенно когда они лежат в бд.

И вот - если у котов есть метод getColor() - в переопределенном методе (для класса пятнистых котов) осуществляется lazy loading карты пятнистости, вычисляется результат, кешируется в объекте и отдается. И всё мое предприятие по выращиванию и переработке котов, над развитием которого я трудился без малого 10 лет, работает теперь с пятнистыми котами без малейших изменений.

Класс котов был спроектирован неправильно? Нет, у него был метод getColor(), и объекты создавались Factory. И не только у котов, но и медведей, etc, благо это не требовало никаких усилий. Было бы предусмотрительнее изначально использовать не цвет, а окраску, и представлять её объектом? Увы, мы никогда не знаем, что нам потребуется завтра. Можно, отправляясь в поездку, набирать 10 чемоданов вещей, на случай, если что-то порвётся или погода не оправдает наших ожиданий (но ведь вы сами не будете этого делать, как не будете представлять все элементарные типы объектами). А можно захватить с собой немного лишних денег, чтобы в случае чего - чего-нибудь прикупить...

;-)
 

С.

Продвинутый новичок
Rammstein
ORM. Автоматом мапит поля БД на поля объекта.
Я просил пример когда меняется название свойства, а не название поля в базе.

Если я пишу абстрактный класс, где названия свойств могут меняться, то я и не забиваю их названия в программу константно. Только как тут сеттеры/геттеры помогут?

Если есть некое стандартное общее свойство, но без предопределенного имени, то обращаться к нему надо через метод, это и козе понятно. Причем тут ООП, если даже обычный mysql_insert_id() по тому же принципу работает.

Вообще мне кажется, что здесь проявляется еще одна проблема кодера -- непонимание разницы между абстрактным и конкретным. В абстрактном мы не знаем, что и как будет называться, поэтому ни имен конкретных свойств ни сеттеров/геттеров к ним просто не существует. В конкретном (concrete - англ. бетон) все определается заранее и делается неизменным. Понятно, что иногда приходится подтесывать. Но тогда ручками по программе... Поиск по нескольким файлам названия одного свойства - работы на 7 минут. Где вы видели, чтобы дома строились с возможностью замены блоков?
 

zerkms

TDD infected
Команда форума
WP
в контексте моей фразы

которая являлась вопросом на фразу nerezus'а
$b - ссылка.
естественно, PHP5.
а если ещё и посмотреть код до этого, то понятно, что упоминание о cow будет неуместно, ибо не при делах. посему - чушь ;)
 

denver

?>Скриптер
[вырезано цензурой]

Ой, незаметил новой страницы, отстал от спора. Ну вас всех нафиг :)
 

Bermuda

Новичок
hermit_refined
Почти убедил :)
Я не пытаюсь спорить, я лишь ставлю под вопрос истинность некоторых взлядов, дабы понять все плюсы и минусы.
Плюсы и минусы обращения к свойствам класса напрямую мне ясны, также мне ясны плюсы обращения к свойствам класса через методы.

В чем я хочу убедиться, так это в отсутствии минусов (или хотя бы в минимальном их количестве) при обращении к свойствам класса через методы.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Автор оригинала: zerkms
grigori в PHP любое копирование - ссылка.
чушь
Да, сказал некорректно. В PHP обычное копирование тоже является созданием ссылки.

-~{}~ 15.01.07 04:17:

Автор оригинала: hermit_refined
очень жаль. раньше вы писали легко читаемый, понятный без комментариев и независимый от реализации код.
Теперь я пишу легко читаемый, понятный с комментариями код. :)
Что значит фраза "независимый от реализации код" - я не понимаю ... imho код - это и есть реализация.

предлагается всё-таки не ходить по кругу, и не приплетать опять массивы (я уже отвечал на эту тему grigori).
Отсутствие ответа на фразу "вы бредите ... разработчик класса ни в чем не виноват" значит, что её пропустили, как эмоциональный offtopic, а не то, что с постом согласились :)

ok. вы упорно опровергаете все аргументы против public свойств (а их вам была уже уйма высказана), насколько успешно - оставим в стороне. вы можете привести разумный аргумент "за"? кроме лени, конечно.
Хочется. Удобней. Логичней. Быстрее. Стремление к уменьшению объема кода и количества методов. Любовь к элегантным решениям. Неприятие догм.

-~{}~ 15.01.07 04:19:

hermit_refined, можно другой вопрос - С чем Вы НЕ спорите?
 

hermit_refined

Отшельник
Что значит фраза "независимый от реализации код" - я не понимаю
вполне понятно, что имелось в виду - независимый от реализации конкретного класса.
Хочется. Удобней. Логичней. Быстрее. Стремление к уменьшению объема кода и количества методов. Любовь к элегантным решениям. Неприятие догм.
любители eval и глобальных переменных говорят то же самое :)
Отсутствие ответа на фразу "вы бредите ... разработчик класса ни в чем не виноват" значит, что её пропустили, как эмоциональный offtopic, а не то, что с постом согласились
не передергивайте. это касалось вашего примера, и я свои эмоции вполне аргументировал, в чем легко убедится - мой комментарий никуда не делся. на ехидное же предложение использовать функции для доступа к элементам массива - я отвечал отдельно.

вообще, очень жаль, что вы в упор не замечаете высказываемые вам аргументы, отделываясь смешками. спорить не о чем, да.
hermit_refined, можно другой вопрос - С чем Вы НЕ спорите?
с тем, что не считаю неправильным.
 

Rammstein

PHPClub::News
С.
Когда изменение имени поля является самоцелью - это уже дебилизм. Я же привёл конкретный пример, когда имя поля объекта меняется вследствии изменений во внешней среде. И это далеко не абстракция - ORM мапит только на свойства, а функции пишем (переопределяем) ручками.

-~{}~ 15.01.07 12:38:

P.S> В случае с Propel, например, он создаст метод setИмя и getИмя, а мы можем определить setСтароеИмя и getСтароеИмя. Но Propel - разговор отдельный. Там реализован продвинутый маппинг, поэтому можно указать какое поле БД на какое поле объекта мапиться должно, но это трудоёмко в реализации (более трудоёмко, чем без этой фичи)
 

С.

Продвинутый новичок
Классно! Проектировщик базы решил немного поменять логику хранения данных и изменить поле "allow" на "deny".


Кодер сделал:

function GetAllow() {return $this->deny}
function SetAllow($x) {$this->deny=$x}
 

Rammstein

PHPClub::News
Ну вот, я о том же.

-~{}~ 15.01.07 19:17:

Ну вот, я о том же.

-~{}~ 15.01.07 19:19:

Или, если подъёб в том, что меняется смысл, то можно сделать так:
function GetAllow() {return !$this->deny}
function SetAllow($x) {$this->deny= !$x}
 
Сверху