| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Религиозные войны > презумпция инкапсуляции |
| Автор: Pawl 30.5.2014, 09:17 | ||||||||||
Каждый маленький программист, можно сказать, с молоком матери впитывает идею постоянного сокрытия данных, и, если в методах класса с модификатором public ему приходится мириться, то вот поля обязательно должны быть private или уж на крайняк protected! Со временем это переходит в ритуал, благодаря которому для простого доступа или изменения полей класса надо писать еще дополнительный код стандартных геттеров/сеттеров. Веселуха начинается при написании какого-либо java-класса PODJO типа сущностей для доступа к таблицам в БД с десятком-другим полей в каждой, или action'ов из фрэймворка Struts2. Тогда программа обрастает прям километрами кода. Честно, не понимаю, зачем для простого получения/изменения значения поля обязательно нужны некие костыли? Допускаю необходимость инкапсуляции - в разумных пределах, но писать код типа
и потом обращаться к х и у через point.getX() / point.setX(х) считаю явным излишеством. В этом случае гораздо проще использовать для полей модификатор public и обращаться к ним напрямую:
В С#, на сколько я знаю, для этого есть сахарные костыли, называемые свойствами, которые имитируют прямой доступ к переменной: point.х = х. Для этого класс Point надо оформить так:
Данный код выглядит значительно короче, чем в java, но по поведению также практически ничем не отличается от кода
Видимо, java-сообщество просекло фишку и создало библиотеку lombok, с помощью которой можно сократить код до
Имхо, все эти телодвижения происходят из-за проблемы, которую сами себе и создали. А насколько было бы проще жить, если не возводить инкапсуляцию данных в священную догму! |
| Автор: Alexeis 30.5.2014, 09:49 |
| А я не парюсь при использовании тривиальных полей, пихаю их в паблик и пошло оно все лесом. На крайняк всегда есть рефракторниг и ctr+shift+f . |
| Автор: Pawl 30.5.2014, 10:03 | ||
И в чём же плюс? |
| Автор: LSD 30.5.2014, 10:18 |
Возможность быстро создать пропертю, в которую потом при необходимости легко добавить, без рефакторинга и перекомпиляции, нужные проверки. |
| Автор: Pawl 30.5.2014, 10:38 | ||||
Согласен, это плюс. Но, к примеру, в классах-сущностях проверки можно осуществлять и при помощи аннотаций к полям:
|
| Автор: diadiavova 30.5.2014, 11:01 | ||||
| Pawl, а чем не устраивает то объяснение, которое дается в любом пособии для начинающего программиста? 1. При тестировании может выяснится, что некоторые значения переданные полю, приводят к некорректной работе класса. В данном случае может возникнуть необходимость либо корректировать налету полученное значение либо отклонять изменение значения. 2. Существует вероятность того, что в процессе развития проекта может возникнуть необходимость уведомлять заинтересованные стороны о том, что значение поля изменилось, либо кто-то пытается его изменить. 3. Для оптимизации работы класса может понадобиться, к примеру, ленивая инициализация значения (то есть объект создается при первом обращении к свойству, в противном случае не создается вообще). Во всех этих случаях прямое обращение к полю может привести к необходимости переписывать туеву хучу кода.
Не имитируют. То, что ты привел - это т.н. автоматически реализуемое свойство. Его объявление мало чем отличается от объявления поля, но фактически компилятор создает обычные акцессоры свойства со стандартным кодом. Для них всегда можно описать реализацию вручную с тем же успехом. Надо сказать, что автоматическая реализация - сама по себе очень крутая штука и сильно сокращает количество кода. Но, в то же время, даже когда ее не было (в шарпе она появилась в 2005-м, а в бейсике в 2008-м), свойства все равно отчасти решали описанную тобой проблему. Дело в том, что в языках, где есть свойства, инкапсуляция доступа к полям в принципе не так критична. Несмотря на то, что во всех учебниках пишут о том, что публичные поля - зло, тем не мене, в языках со свойствами поле почти всегда можно совершенно безболезненно заменить свойством, если такая необходимость возникла(есть пара случаев исключения, но в основном они не критичны).
А если ты пишешь библиотеку, которую используют десятки других разработчиков, которые обращаются к полю класса в сотне различных мест, а потом всякий раз, когда оказалось, что поле надо заменить методами, будешь предлагать и им тоже все это дело рефакторить? А если все так начнут делать? |
| Автор: Pawl 30.5.2014, 11:14 | ||||||
Ну так вы, можно сказать, сами и ответили на свой вопрос:
Т. е. Можно написать так:
и при необходимости заменить поля свойствами с необходимыми проверками. При этом доступ из других классов как был point.х, так и останется point.х, т. е. их модифицировать не понадобится. |
| Автор: diadiavova 30.5.2014, 11:20 |
Я не задавал вопросов, а попытался ответить на твой. Ну так на C# можно. Это не будет работать при обращении к свойствам через рефлексию, а так же, если код вызывается из проекта написанного на языке, в котором нет свойств. Например был в семействе дотнет-языков такой язык как J# (на заре развития технологии с его помощью пытались привлечь ява-программистов). В нем свойств нет, и обращаться приходится к методам-акцессорам непосредственно. Но такие языки мало распространены, так что большой проблемы в этом нет. А так вообще да, свойства в принципе для этого и существуют. Когда я интересовался явой, то одной из причин, по которой я оставил эти попытки было именно отсутствие свойств, поскольку к хорошему быстро привыкаешь. |
| Автор: Pawl 30.5.2014, 12:23 | ||
Думаю теперь, когда Оракл обязался выпускать по новой версии java не реже, чем раз в 2 года, свойства в ней тоже появятся и причины для принудительной инкапсуляции со временем исчезнут |
| Автор: LSD 30.5.2014, 12:45 | ||||
Перекомпиляция все же потребуется.
Метода акцессоры можно мокать, а вот доступ к полям фиг замокаешь. |
| Автор: Alexeis 30.5.2014, 15:27 | ||
Pawl привел тривиальный случай и я, собственно, в этом контексте комментировал. То что ты описал никак нельзя назвать тривиальным случаем. Это только быдло кодеры пишут класс и не представляют себе как его потом будут использовать. При конструировании программы от простого к сложному заранее понятно, что точка это пассивный объект из 2-3 полей и из нее никто не будет строить в последствии объект с виртуальными функциями и т.д. В С++ есть даже такое понятие как POD тип Plain Old Data, т.е. тип, который устроен так как описан. На самом деле, очень здорово, когда простые вещи устроены простым образом, это делает код прозрачным. Программист, который читает такой код не вынужден каждый раз обращаться в реализации функции GetX чтобы убедиться в том, что ее реализация тривиальна. Экономиться куча времени на чтении и куча времени на компиляции. |
| Автор: diadiavova 30.5.2014, 16:29 | ||||||||||
Автоматически реализуемые свойства вообще никаких проблем с разрастанием кода не создают, так что лучше уж их использовать, если они есть. Да и не факт, что свойства появятся. Насколько мне известно, Сан не добавлял новые фичи в язык потому, что считали все это веяниями моды и не хотели засорять ими язык. Что будет делать Оракл - неизвестно, хотя, вроде кое-что уже сделал полезное(лямбды замыкания и прочее).
Даже в яваскрипте есть уже Да. Но она обычно и так выполняется время от времени. Хотя согласен, что лучше такими заменами не злоупотреблять.
Он вроде там приводил пример с сущностями для доступа к объектам датабазы. Ну так такие классы обычно генерируются автоматически, а писать их руками - чистой воды извращение
Я не об этом написал. Я написал о том, что код, который пишешь ты, возможно будут использовать другие разработчики и просить их каждый раз, чтобы они рефакторили свой код из-за того, что ты поленился описать акцессоры можно до поры до времени, но если делать это постоянно, то тебе могут устроить "тёмную"
А вообще, при наличии нормальных инструментов, тривиальный код генерируется автоматически. Думаю, что для любой ява-иде такие инструменты, которые ну по крайней мере код акцессоров генерят, найти вполне можно. Поэтому проблемы в этом не вижу. |
| Автор: Alexeis 30.5.2014, 20:48 | ||||||||
Простые классы просто рефракторятся, но этого как правило и не требуется.
Тебе наверное редко приходиться читать чужой код без комментов. Иногда берешь чужую прогу и хочется убить автора. Там где можно написать решение в 100 строк, обнаруживаешь 1500 вот таких вот пустых строк и вдобавок непонятные иерархии, наследования виртуальные функции и т.д. Раздувают общее решение для узкой задачи. Программист не должен быть заложником ООП. ООП нужен там где он нужен, а там где не нужен, то нужно писать простой компактный читабельный код, который не нуждается в документировании и даже комментариях.
У меня нет проблем со скоростью печати. Пока обдумываешь решение хватает времени не то что гетеры с сетерами налепить руками, а еще сделать выравнивания, отступы пробелы и прочий марафет облегчающий восприятие кода.
Нетривиальный код, который будут читать другие люди, вообще желательно строить на абстрактных классах, чтобы человек видел только то что ему может понадобиться. Но в этой теме поднят вопрос целесообразности применения ООП в тривиальных ситуациях. Я поддерживаю автора. Фтопку ООП когда оно не нужно. |
| Автор: diadiavova 30.5.2014, 23:55 | ||||||||
Да, но как я уже написал, делать это, возможно, придется не только тебе одному. А если все будут поступать так же, то работенки прибавится всем и немало. Я тут вообще ни при чем. В случае со мной публичное поле объявляется так
А у меня есть, да и отступы руками делать не привык, поскольку иде с этим прекрасно справляется. И вообще, чем меньше кнопок приходится жать - тем лучше Я писал о коде, который используют другие. Вот ты при необходимости взял да и заменил публичное поле акцессорами. Отрефакторил все те места, где ты к этому полю обращался и вроде все нормально. Только проблема в том, что если и у других разработчиков имеется код, где они обращались к этому же полю, то и им придется в каждой такой ситуации делать то же самое. Я говорил только об этом и тут не имеет ровны счетом никакого значения степень тривиальности кода. А если каждый начнет делать так же как и ты, то это может обратиться в серьезную проблему. |
| Автор: Pawl 1.6.2014, 09:38 | ||||||
В плане свойств да, тут безусловно большой профит, убедили!
Автоматически генерируемый код - это, конечно, хорошо, но его А ИДЕ иногда такого нагородит, что потом сам можешь не понять, что к чему. Не будем уточнять, из какого! |
| Автор: diadiavova 1.6.2014, 13:45 | ||
Я уже сказал, что ООП здесь вообще ни при чем. Если ты уверен, что ситуации, в которой это может стать проблемой, не может возникнуть в принципе, то поступай как тебе удобно. Но ведь не все же от тебя зависит.
Тут есть несколько возражений: 1. Изначально мы говорили о тривиальных случаях, а с ними любой инструмент кодогенерации справляется на ура, да и читается все хорошо. 2. Читать сгенерированный код в принципе не обязательно, обычно он используется как внешняя библиотека и проблем это не создает. 3. Много зависит от того, что именно ты используешь для кодогенерации, насколько надежен инструмент и какие возможности дает тебе язык, на котором ты пишешь. К примеру в C# и VB.Net есть такая штука как partial-классы. То есть код одного класса можно описать в разных файлах. Кроме того в одном файле может быть несколько классов, среди которых могут быть и частичные. Такой подход позволяет безболезненно использовать инструменты кодогенерации, посколько автоматически генерируемый код можно легко отделить от ручного. Таким образом сгенерированные файлы вообще даже открывать не обязательно, а на их содержимое можно влиять только через визуальный дизайнер к примеру и при любом изменении в дизайнере файл переписывается полностью. Обычно это работает достаточно надежно. В данном случае речь шла об акцессорах, но почему-то меня вовсе не удивляет, что у тебя выражение "одно место" вызывает совсем другие ассоциации. Мало того, я даже догадываюсь какие именно. |
| Автор: Pawl 1.6.2014, 22:03 | ||||
Согласен, удобная штука. Надо будет как-нить обсудить достоинства и недостатки шарпа, но не в этой теме - тут это будет оффтопик.
С этим не соглашусь: ты должен отвечать за выдаваемый тобой код, а как ты будешь отвечать за что-то, чего даже не видел? |
| Автор: LSD 2.6.2014, 10:41 | ||
Ты вот без гугла можешь сказать, хотябы как посмотреть на то, что из твоего байткода сделал JIT? (это к вопросу об отвечать за то что даже не видел) |
| Автор: Pawl 2.6.2014, 18:37 | ||
За это пусть Oracle отвечает. |
| Автор: LSD 3.6.2014, 10:12 | ||
Тогда на вопрос
ответ аналогичный, это пусть <разработчик генератора кода> отвечает. |
| Автор: Pawl 3.6.2014, 16:49 |
Ну и будешь в ответ на претензии к своему коду отсылать заказчиков прямо туда! |
| Автор: LSD 3.6.2014, 17:29 | ||
Туда это туда же куда тебя пошлет Оракл с твоим багов в JIT (при условии конечно что у тебя не куплен VIP саппорт)? |
| Автор: Pawl 3.6.2014, 17:58 | ||
Разница тут в том, что ты можешь залезть в дебри автосгенерированного IDE java-кода, разобраться в нём, потратив n-ное количество времени, и, найдя там лажу, хлопнуть себя по лбу с воплем "Семён Семёнович!" А потом самостоятельно эту лажу исправить. А баги JDK исправить можешь? |
| Автор: LSD 3.6.2014, 19:17 | ||
1. Про "автосгенерированного IDE" это твоя личная фантазия, diadiavova не уточнял чем генерируется код. А так, сгенеренный код подправить то конечно можно, но как ты предлагаешь это (исправление) автоматизировать? 2. И я о том же, баги в JIT JDK имеют гораздо более серьезные последствия и устраняются на порядок сложнее, чем баги в автосгенеренном коде. Но тебя почему-то сильно пугает "автосгенерированный IDE" код, а код сгенерированный JIT не беспокоит вообще. |
| Автор: Pawl 3.6.2014, 20:12 | ||||||
А чем еще при разработке может быть автосгенерирован код?
Никак, только тщательная проверка и правка ручками
Я вообще стараюсь не беспокоиться о вещах, на которые повлиять не в силах! |
| Автор: diadiavova 3.6.2014, 22:58 |
Я уточню. 1. Инструменты рефакторинга. Сами по себе они вряд ли могут считаться инструментами кодогенерации, но, учитывая, что какой--то код они генерируют, в них нередко встраивают дополнительные функции, которые выполняют разовые операции по кодогенерации. Например для списка объявленных полех можно сгенерировать методы-акцессоры или в свиче описать кейсы для перечисления и т.п. Существуют и отдельные инструменты такого рода(без рефакторинга), но их я отношу к этой же группе. Код, генерируемый такими инструментами, можно и нужно не только читать, но и писать дописывать. Зачастую (как в случае со свичами) они просто создают заготовку кода и не более. 2. Инструменты визуального моделирования. Суть их состоит в том, что вся работа выполняется в дизайнере, а сохраняться результат может в том числе в виде программного кода. Наиболее очевидный пример такого генератора - инструменты для создания классов модели предметной области из сущностей базы данных. То есть в дизайнере создаются модели табличек связей и т. д. а сохраняется это в виде готовых классов. Если используется вполне надежный инструмент, то заглядывать в код, сгенерированный такой тулзой - зачастую просто противопоказано. Код может оказаться с виду достаточно мудреным, но на самом деле он вполне шаблонный и автоматический генератор кода с такой задачей справляется на ура. Любые ошибки, которые при этом могут возникать - обычно являются ошибками, допущенными в дизайнере и исправляются там же. Правда справедливости ради надо отметить, что иногда ошибки выявляются во время отладки, так что в код в этот период заглядывать иногда приходится, но исправлять все равно придется в дизайнере, поскольку все изменения, выполненные вручную будут утрачены при следующем сохранении дизайнера или при следующей сборке проекта. 3. Код, порождающий код. Обычно это какой--то вариант текстовых шаблонов, где код смешивается с операторами языка программирования, которые будут выполняться. http://msdn.microsoft.com/en-us/library/bb126445.aspx. Несмотря на то, что этот пример похож на предыдущий (только там визуальный дизайнер, а здесь код), тем не менее здесь ты имеешь дело не с проверенным инструментом, а с собственным кодом, поэтому смотреть, что получилось все-таки надо, по крайней мере пока код шаблона не проверен со всех сторон. Понятно, что я имел в виду в основном второй вариант, когда используется надежный инструмент, а твои действия ограничены возможностями дизайнера. Кроме того, если речь идет о датабазе, то ее сущности нередко можно просто импортировать оптом и сгенерировать туеву кучу кода. Обычно код проверяется на предмет корректной работы, но сам код изучать - это лишнее. |
| Автор: LSD 4.6.2014, 12:10 | ||||||
Вообще-то генерация кода с помощью IDE, это очень плохая практика. Как минимум по тому что такой билд, нельзя автоматизировать и гонять на CI сервере. Ну или придется комитить сгенерированный код в VCS, то тоже не айс.
Я так и представляю, как ты берешь какой нибудь prtobuf, и вдумчиво читаешь все те тонны кода которые он генерирует
А это тогда тут при чем
? Ты или "должен отвечать" и за компилятор и рантайм и автогенерацию или "не беспокоиться о вещах ...". |
| Автор: Pawl 4.6.2014, 15:27 | ||||
Ну, тут ты меня поймал! |
| Автор: LSD 4.6.2014, 17:00 | ||||||
1. Нефиг генерированный код коммитить. 2. Хотел бы я посмтреть на реализованный тобой protobuf сериализатор/десериализатор 3. Не знаю в какой *** конторе ты работаешь, но у нас за баги никого премии не лишают. |
| Автор: Pawl 4.6.2014, 17:58 | ||
Золотые слова!
Такого не делал, но, если я правильно тебя понял, самому его написать невозможно? Т. е., если его коммитить, то только в генерированном виде? А как же тогда пункт 1? Или его не коммитить? А если не коммитить, за него заплатят? Ой, а к вам можно? Пожалуйста-пожалуйста, я честное слово, вам такого бажного ###кода быстро-быстро наворочу! |
| Автор: LSD 5.6.2014, 13:33 | ||||
Имелось в виду, реализованный руками.
Тебе в Люксофт. |
| Автор: Pawl 5.6.2014, 22:54 |
Так. На сколько я понимаю, есть код, реализованный руками и есть код, сгенерированный ИДE. Поправьте меня, если ошибаюсь: protobuf сериализатор/десериализатор не пишется руками и не генерится? Как же он тогда получается? А я хочу к вам! А то вдруг там за баги наказывают! |
| Автор: LSD 6.6.2014, 11:05 | ||||||
У него немного другая идеология, есть язык описания доменных обхектов, на котором ты описываешь их, а дальше он генерирует классы для нужного языка (стандартно поддерживаются Java, C++, Python, и есть сторонние реализации практически для всех остальных языков).
Вот такой кодик Наказывают |
| Автор: Pawl 6.6.2014, 17:18 | ||||
Ага, идея понятна. Пожалуй, я бы сам такое действительно не написал.
А как наказывают? Если не лишают премии, то что делают, порят розгами? Или подвергают моральному унижению? |
| Автор: LSD 9.6.2014, 14:38 | ||
Я смотрю ты уже заинтересовался |
| Автор: Pawl 9.6.2014, 17:32 |
Я в душе мазохист |
| Автор: diadiavova 9.6.2014, 18:09 | ||
А когда из душа выходишь? |
| Автор: Pawl 10.6.2014, 07:35 |
Тогда я программист А вообще спасибо всем откликнувшимся, благодаря вам я стал по-другому (надеюсь, более непредвзято) смотреть на некоторые вещи. |