Шрифт:
Но главная причина того, почему эта идея не сработала для обобщенных типов, - они стали крупным прибавлением к системе типизации, и без того сложной. С системами типизации нужно обращаться осторожно, поскольку это может повлечь далеко идущие и непредсказуемые последствия для языка.
А урок таков: если вы совершенствуете зрелый язык, нужно больше чем когда-либо задумываться над балансом возможностей и сложности. Сложность во многих разделах языка растет квадратично: прибавив всего одно свойство, вы получаете куда более сложную структуру. Если язык близок к тому, чтобы превысить уровень понимания программистов, усложнять дальше просто нельзя - все пойдет прахом.
Если же все-таки усложнять, исчезнет язык или нет? Нет, не исчезнет. Мне кажется, C++ давно превысил этот уровень, а сколько народу им пользуется! Но тем самым вы побуждаете людей разбивать его на части. И почти в каждой известной мне лавочке, где используют C++, говорят: “Да, мы используем C++, но не применяем ни множественное наследование, ни перегрузку операторов”. Есть свойства, которые вы не используете, потому что код тогда получается слишком сложным. Думаю, не стоит и пытаться. Каждый программист должен иметь возможность читать код любого из своих коллег, а в нашем случае эту возможность легко утратить.
Сейбел: Не кажется ли вам, что Java без обобщенных типов был бы сегодня лучше?
Блох: Не знаю. Обобщенные типы по-прежнему мне нравятся - они находят за меня ошибки в моем коде. Эти средства помогают найти мне вещи, которые обычно включаются в комментарии, и перенести их в код, где компилятор может обеспечить их корректность. С другой стороны, когда я вижу сообщения об ошибке, связанные с параметризованными типами, а потом нахожу сделанные для этих типов обобщенные объявления, вроде моего Enum - class Enum<E extends Enum<E>>”, то понимаю, что обобщенные типы не были достаточно хорошо проработаны, чтобы их включить.
Программист должен или быть оптимистом, или застрелиться. И мы говорим: “Конечно, мы это умеем. Мы знаем все об обобщенных типах еще с тех пор, как познакомились с языком CLU. Это технология 25-летней давности. То же самое сегодня можно слышать про замыкания, правда, о них говорят, что им уже 50 лет. “Это легко и не усложняет язык”.
Черт возьми, конечно усложняет! Но, думаю, обобщенные типы послужили для нас хорошим уроком. Нельзя добавлять что-то к языку, пока не поймешь, как поведет себя концептуальная поверхность, пока не будет веских доводов в пользу того, что программисты смогут эффективно пользоваться новым свойством и оно облегчит им жизнь.
Если бы мы знали, как простые люди отреагируют на обобщенные типы, то, конечно, придумали бы что-нибудь другое. Значит ли это, что эти средства вообще не надо было изобретать? Наверное, все-таки не значит. Думаю, они полезны. Главный аргумент в их пользу - раз большинство коллекций однородны, а не разнородны, работать с однородными коллекциями должно быть легче. Кроме того, приведение типов вообще не очень хорошая штука. Оно не всегда срабатывает и не делает вашу программу красивой. Поэтому, полагаю, должна быть возможность задавать тип коллекции, и он должен проверяться автоматически. Но нужны ли для этого страдания из-за переусложненности средств? Нет. Видимо, нам все же стоило сделать их попроще.
Сейбел: Скажите, а пользователи требовали обобщенных типов? Кто-нибудь жаловался, что их отсутствие мешает писать программы?
Блох: Ну, что касается разработчиков, ответ, увы, отрицательный. Пожалуй, виноват здесь я - эта штука казалась мне красивой, и я думал, что стою на правильном пути.
Но при разработке программ мы часто чуем какие-то вещи нутром. Кто-нибудь просил меня о fоreach? Опять же нет. Но я знал, что стою на правильном пути, и это оказалось так - многие пользуются этим. Но большой грех для разработчика - создавать программы, которые просто отлично смотрятся, хорошо сделаны и так далее. Если вы не решаете реальные проблемы реальных пользователей - в нашем случае Java-программистов, - то не надо ничего добавлять.
Есть чудесное выступление Гослинга “The Feel of Java” (Почувствовать Java); в нем он говорит, что нужно трижды ощутить необходимость чего-то, прежде чем внедрять это. Нельзя добавлять программу только из-за ее красоты.
Но люди все равно добавляют. Что делают разработчики? Пишут код. И, работая над библиотекой или языком, они хотят добавить туда что-то свое. Некий внутренний голос должен подсказывать, какое сочетание свойств будет работать хорошо, что нужно добавлять, а чего не нужно. Ведь чаще всего вы можете добавить к языку больше, чем должны. Это означает не то, что ваши программы плохи, а лишь то, что надо правильно выбирать, не валя все в кучу.
Сейбел: Я читал книги “Java Puzzlers” и “Java Concurrency in Practice”. Меня удивило, что в языке, который изначально был очень простым, столько секретов.
Блох: Секреты есть, но это неизбежно, они есть во всех языках. Можно было бы написать книгу “Си: головоломки”.
Сейбел: Ну, этот язык - сплошная трудность.
Блох: Да, тут понадобилась бы целая книжная полка. В Java такие случаи особенно нужно отмечать, ведь его считают простым языком. В каждом языке свои проблемы, в Java их не так много, и они по большей части довольно забавны и интересны.