Xpoint
   [напомнить пароль]

Почему в Java нет полей типа "property" из Delphi

Метки: [без меток]
[арх]
2006-06-16 10:36:20 [обр] 30-ый(59/584)[досье]

По мотивам
Так ли страшны public-поля, как их малюют?
хочется спросить.

А почему собственно в Java нет properties? Т.е. виртуальных полей, обращение к которым Java сама превращает в getX и setX. Типа:

property int x public read getX() private write setX()

Это бы сразу решило проблему public-полей. Поля бы можно было в любой момент переделать в properties и поставить на них любую желаемую обработку.

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

спустя 2 часа 57 минут [обр] Давид Мзареулян(7/1003)[досье]
Меня там отсутствие пропертиз тоже всегда удивляло. Понятно, что при создании Явы как языка это ещё не было устоявшейся практикой. Но уж когда начали перелопачивать синтаксис в 1.5 — могли бы и сделать… архинужная же вещь, при том что никаких проблем ни с логикой ни с совместимостью, вроде бы, не видно.
спустя 3 минуты [обр] GRAy(14/259)[досье]
30-ый[досье] Вот тут обсуждение возможного решения этого вопроса. Соглашение это вышло из спецификации JavaBean`ов - это часть стандарта, но не стандарта языка. Паттерн, который стал настолько распространён, что теперь под него собираются подстроить синтаксис и компилятор языка. В обсуждении, ссылку на которое я привёл, выдвигаются достаточно аргументов как за этот подход, так и против, но лично мне кажется, что пока всё продумано не очень основательно и не все шишки набиты, надо исследовать этот вопрос.
спустя 24 минуты [обр] Давид Мзареулян(7/1003)[досье]
GRAy[досье] Да, в принципе, в Дельфи вполне пристойный синтаксис. По Вашей ссылке вариант, конечно, тоже имеет право на жизнь, но, ИМХО, можно и проще.
спустя 8 часов [обр] Даниэль Алиевский(35/125)[досье]

Мое личное мнение, что при создании Java разработчики пошли своим, достаточно оригинальным и интересным путем, сделав "минимальный" язык, позволяющий удобно решать поставленные задачи. Конечно, версия 1.0 была чрезвычайно "корява", но уже 1.1 была вполне изящна, обладая лишь хорошо известным набором недоработок и недоразумений (вроде public-полей у Dimension или дурацкого наследования Stack от Vector). А вот дальше пошли компромиссы и сомнительные улучшения. Единственное безусловно правильное новшество - Swing, но ведь и тот до сих пор не доведен до уровня элементарной безошибочности, по крайней мере под Windows. Коллекции Java 1.2 с самого начала вызывали некоторые сомнения, а в 1.5, "благодаря" generics, превратились в ужасающего непостижимого монстра, изучать который - отдельное хобби. При том, что область применения их, хотя и обширна, все же по сравнению со всеми применениями универсального языка довольно ограничена. Скажем, лично мне еще ни разу не понадобились возможности коллекций, которых не было в банальных Vector и Hashtable. А если бы понадобились, нужные добавки можно было бы легко реализовать самостоятельно, ценой сотых долей процента общего написанного мной кода. Это, конечно, отражает специфику моей области программирования (алгоритмику), но все же о чем-то говорит. Кому из присутствующих, действительно, на практике часто приходится применять отсортированные деревья? Или связные списки (с примитивной ресурсоемкой реализацией LinkedList, когда каждый узел - отдельный объект, а не элемент экономного массива целочисленных индексов)?

Что касается properties, это решение очень давно было в Delphi и отсутствовало в Java. Про несчастную судьбу продуманного Паскаля в руках Borland говорить не буду, но отсутствие properties в Java всегда было отличием, которое скорее можно было расценивать как преимущество языка в плане его "минимальности". Ведь методы доступа - при правильной архитектуре - почти не увеличивают размер кода, но при этом четко синтасически отличаются от обращений к полям, которые - опять же при правильном проектировании - всегда происходят в рамках класса или пакета. В Delphi меня иногда раздражало, что запись вроде MyObject.i++ в действительности могла обозначать все, что угодно, вплоть до форматирования диска. В Java же вызов вроде myObject.setIndex(myObject.getIndex()+1) является либо редчайшим исключением, либо свидетельствует о плохом проектировании класса, где нет специального метода для популярной операции инкремента индекса. Языки-то разные, с разной идеологией и уровнем защиты.

Могу еще так сформулировать. В Java уровня 1.1, как и в ассемблере (извините за парадоксальное сравнение), как правило, каждый оператор кода делает совершенно понятную и однозначную вещь. За исключением вызовов методов, действия которых, как и естественно предполагать, могут быть выяснены лишь из документации. Но в Java 1.5 это достоинство было утрачено: тот же unboxing может превратить простой оператор вроде ++ в манипуляции с объектом. В этом плане properties вовсе разрушат очевидность кода: простое обращение к сущности, выглядящей как переменная или поле, может вызвать совершенно произвольные побочные эффекты, неизвестные без знания документации.

Ergo: язык постепенно деградирует :) Как, впрочем, и все изначально гениальные изобретения, увы. Может быть, через некоторое время завоюет популярность новый язык...

спустя 59 минут [обр] GRAy(14/259)[досье]
Даниэль Алиевский[досье] А что вам мешает продолжать писать в стиле java 1.1? Большинство сомнительных нововведений, которые вы так ругаете (правильно ругаете, правильно) не затронули языкового ядра. Можете привести пример, чего вы лишились с переходом от версии 1.1 к 1.5? Всё-таки, java крайне редко используется как алгоритмический язык, больше для бизнес приложений, где важна не чистота идеологии, а скорость разработки и переработки с помощью имеющегося инструмента. Java не деградирует - она обрастает "фишечками", которые, возможно, задавят её своей тяжестью ;) поживём - увидим.
спустя 2 часа 13 минут [обр] 30-ый(59/584)[досье]

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

Гибкость emum'ов может и оставляет желать лучшего, да и автобоксинг - не самое лучшее изобретение, но на Generics прошу не катить - это сказка. Очень удобно, очень гибко и спасает от сотни ошибок. Вот еще бы проверку на NOT NULL на уровне компиляции добавить и про ошибки исполнения можно будет вообще забыть.

спустя 10 часов [обр] Даниэль Алиевский(35/125)[досье]

GRAy[досье]

А что вам мешает продолжать писать в стиле java 1.1?

А ничего не мешает, я всегда так и делаю :) И для проверки время от времени компилирую свои модули с ключом "-target 1.1". Для тех же 3-4 ценных возможностей, которые все же отсутствуют в 1.1 (прежде всего System.nanoTime и String.format), написал собственные заменители, которые в 1.4 и 1.5 через рефлексию вызывают подходящие методы, но делают нечто разумное и в 1.1.

Всё-таки, java крайне редко используется как алгоритмический язык, больше для бизнес приложений...

Пожалуй, это можно сказать почти про любой промышленный язык - просто потому, что бизнес-приложения или веб-скрипты пишутся чаще математических алгоритмов. Но критика моя относится почти к любым областям применения. Для каких областей созданы мощные коллекции Java 1.2? Вообще-то на 90% это как раз нетривиальная алгоритмика, причем специфическая - когда управляемые объекты-узлы не слишком мелкие либо их не очень много, и потеря лишних 10-20 байтов на создание экземпляра не принципиальны. Например, строки, как в алгоритмах обработки текстов или архиваторов. Чего стоит хотя бы сбалансированное (или красно-черное?) двоичное дерево, или что там они применили в TreeSet. Похоже, что Sun-овцы сделали их для себя, чтобы писать свои компиляторы и IDE :) А поскольку при этом погнались за универсальностью (классическая ошибка), то утратили контроль типов, насажали багов, и для устранения последствий в спешном порядке изобрели жуткие generics.

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

Этот тезис противоречив. Чистота идеологии - как раз важнейшее свойство для быстрой разработки и переработки больших систем. Именно поэтому "уровень" языков непрерывно повышается от Автокода и первого Fortran-а к современным языкам.

Давно уже известно - и мой опыт это абсолютно подтверждает - что "грязная" идеология, с изобилием инструментов и "фишечек", ускоряет разработку лишь очень коротких программ, вроде сервисных скриптов, "украшающих" веб-страницу или позволяющих сделать что-то несложное на сервере. Для таких целей, действительно, есть языки, которые я называю "write-only" - скажем, Perl. Какой-нибудь корректировщик группы текстовых файлов, скажем, заменяющих у них тег title, на Perl пишется за несколько минут. А когда нужно изменить логику Perl-скрипта, особенно написанного другим человеком, часто дешевле за полчаса написать новый.

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

30-ый[досье]

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

А вот это очень интересно. Расскажите, пожалуйста! Где вы применяли LinkedList, TreeMap, TreeSet? Все остальное, в сущности, было в 1.1, хотя и с некоторыми архитектурными ошибками вроде наследования Stack от Vector или недопустимости null-ключей (исправление этого, конечно, было полезно). HashSet, может быть, и имело смысл сделать, хотя это уже спорно: если очень нужно, множество всегда можно выразить через HashMap.

Уточню вопрос: не где вы применяли новые коллекции, а где вам реально было бы сложно обойтись возможностями Java 1.1 или эквивалентными - хэш-таблицей и массивом переменного размера (ArrayList или Vector)? Например, поиск по коду нашей большой системы показывает множество применений LinkedList, но в подавляющем большинстве мест ArrayList был бы ничем не хуже.

При этом, действительно нужных структур данных java.util не содержит вовсе! Например, списки очень часто применяются для эффективного представления больших структур, занимающих мегабайты. Поэтому я снова и снова вынужден проектировать списки в виде элементов-ссылок обычного int[]-массива индексов, требующих 4 байта на узел. Или писать функции для динамического увеличения размера массива float[] из миллионов элементов. Ничего подобного элементарному дереву, графу, сети или даже простейшему двусвязному списку в коллекциях нет - а ведь при ручном программировании таких структур легко наврать, и нужны они в множестве разнообразных приложений. Но есть деревья в Swing или DOM :)

Самое смешное, что толком даже нет сортировки: я не могу "сказать" сортировщику (с помощью некоторого интерфейса), что именно следует сделать, чтобы обменять два элемента массива в моем представлении. Как прикажете отсортировать массив точек по расстоянию до начала координат, если реально он хранится в виде 2 float-массивов x[], y[]? Хранить точки в виде объектов, если их миллионы - безумное расточительство памяти и времени на создание экземпляров. (Это вам не C++.) Напомню, что алгоритм сортировки слиянием, реализованный в Java, рассчитан как раз на миллионы элементов - ибо для нескольких тысяч метод Шелла, требущий всего десятка строк кода, работает ничуть не хуже.

Powered by POEM™ Engine Copyright © 2002-2005