Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
О_о. Пишу на курсач ИС Электронная библиотека на JSP + MySQL. Названия похожи. Подход не тот 😀
return жесткий. Хочу из этого же проекта классы реализующие запросы к БД.
Ну да, я собственно из-за return'а и запостил. Если ни одного автора
не найдется, bookList итак null'ом будем. Ещё забавляет попытка экономии
памяти с отложенной инициализацией, но это уже другая история...
1. Ещё вместо List возвращается ArrayList, привязка к реализации.
2. Вообще возвращать null - дурацкая идея, для этого есть Collections.emptyList()
3. Напрягает алгоритм перебора с квадратичной сложностью
1. Скорее всего, придётся менять/как минимум пересобирать код в других местах, когда этот метод будет переписан по-нормальному (for more answers read Bloch)
2. К примеру, в моём проекте 80% критических ошибок связано с NPE
3. Использовать для поиска БД
мои соображения. в модели используется ArrayList<String>. Выглядит очень странно, но если подумать, то в целом можно придумать обоснование. Я придумал такое: JPA1 поверх гибера. Отсутствует @ElementCollection. Соответственно коллекцию простых типов хрен замапишь. В гибере прокатывает такой вот фокус с ArrayList. Т. к. он Serializable, то сохраниться в базу как blob. И восстанавливается стандартными средствами сериализации. Соответственно, использовать для поиска БД не получится. Отсюда все эти выкрутасы.
зависит от размера приложения. не все приложения работают с миллионами записей, некоторые работают с хорошо если с 2-3 тысячами. в таком случае вообще можно всю базу в память спокойно засасывать.
П. С. Хотя в данном примере наверное все-таки логично было бы создать сущность. Ибо Пушкин написал далеко не одну книгу.
Для автора следует создавать отдельную сущность независимо от размера БД. Кто будет следить за тем, что один и тот же автор не встречается два раза под немного разными именами?
1. По этому пункту есть встречный вопрос: а вы всегда в апи, где вам возвращается List делаете копию, если хотите его модифицировать?
2. В целом соглашусь. Сам предпочитаю никогда не возвращать null. Использую emptyList().
С другой стороны это может быть логика: либо Null, либо в списке по крайней мере один элемент. Отчасти дело вкуса.
3. Описал чуть выше, когда это сделать не получится
а может поверх этого списка сразу применяется фильтрация через iterator.remove()? Просто фильтр результатов, никаких изменений в БД и не должно происходить.
Если честно, то после тесного знакомства со Scala модифицируемые структуры данных вызывают у меня подозрения. Чем раньше умник, фильтрующий данные с помощью remove, наткнётся на IllegalStateException, тем лучше.
Scala фактически создана для этого 🙂
Ещё часто вижу примеры, где Lisp бы идеально подошёл для создания DSL (последнее, что приходило в голову - генерация MathML-кода). Поэтому подумываю поближе посмотреть Clojure в ближайшем будущем.
вот-вот, семантика. Вообще, по всем правилам, все List надо воспринимать как unmodifiable, если в документации явно не указано обратное. И для добавления или удаления элементов всегда использовать копию.
Я, например, иногда пишу небезопасный код: в API возвращается List, а я его модифицирую, зная, что его можно модифицировать, т. к. возвращается копия да к тому же изменяемая.
Так почему же возвращать ArrayList - это плохо? Вроде как сразу явная декларация намерений происходит =)
Разработчик должен всегда оставлять себе пространство для последующего манёвра. Иначе потом могут появиться невзрачные костыли или deprecated методы. Указывая конкретный класс, ты связываешь себя по рукам и ногам. Если завтра придёт адекватный человек и перепишет это безобразие на вызов DAO, придётся создавать новый ArrayList и запихивать туда значения из DAO. А делов-то было - не писать префикс Array.
> явная декларация намерений
когда я вижу метод, который возвращает ArrayList, я скорее буду воспринимать это как неопытность автора кода, чем как декларацию намерений. И, скорее всего, полезу в сорцы. Не проще ли написать по-человечески и задокументировать семантику?
> Ещё вместо List возвращается ArrayList, привязка к реализации.
да нет, как раз-таки это нормально - возвращать конкретный подкласс - так больше возможностей манипуляции с ним.
а вот на вход хорошая практика подавать интерфейсы
а return может и не так уж и плох. по коду, конечно, масло масленное, а по читаемости может даже и неплохо. по крайней мере, при беглом взгляде вы сразу сможете увидеть, что может возвращаться как null, так и не null. И не придется для этого просматривать весь код метода, разбираясь где, что и как инициализируется.
А просто "return bookList;" не дает ответа может ли возвращаться null или нет.
Я студентота.
Поэтому, если меня просят что-то посмотреть требую описание методов. Хотя бы на любом сленге, которым обладает индивид. Вот это и есть "документация". Но, сами понимаете, еще надо найти понимающих свою же логику студентов 😀
1. Нет, этот код должен быть практически эквивалентен по скорости выполнения и потребления памяти коду из топика. Можно уменьшить потребление памяти, получив ленивое view коллекции книг.
2. В Scala не принято вообще использовать null. Пустые списки, как правило, инициализируются значением Nil, что в некотором роде аналогично Collections.emptyList(). Если результат поиска может быть неопределён (find в примере), возвращается инстанс класса Option, который может содержать, а может и не содержать значение (вызов isDefined в примере). Null в любом случае не возвращается.
не то чтобы пропогандист... Если все начнут писать на Scala, она станет более популярной и работу Scala-программиста будет легче найти. Не всю же жизнь быдлокодить на Java... 🙂
а вообще писать на функциональных языках - огромное удовольствие.
ц:S D P?U$S.A$B$N)ON.L:J!E"U$I N:Q!H:X"J(GL(J HE K G!Y,I"T(Y)O?R:G:C!O)M:H.A(S O)V?Y:T$F"W(P:T.H.F.R"QC(I"A?J)R$Z$R)D(T:Q.A(U D)Y"A"I)G"L!W:E"F L"P?WZ:P(OL)J H:T?C U(O:G.Y$F$IT.S.A.I.W K,N U!M!P,I!K$X.L,B!B"V!F.C.T,O:B(W:J?B,CZ)L?R"I:GF(P A)M.H,H"O)P:Q(M:E)AR,ML.H.E:IШOZWDSHVOYEHKLJDNACEOHRMPMSBIOUPEPDNSLGJEXRZBSHYLJPWTWFEFSFBPKGWSTTLYNJXFWADDBWBPUHVYAUGXZHGSIBJXITDQBGVSVFMLLGDZMFXEBGSPOKSVGTMSAHKTPMUQWQCZRJZGZTRF
return жесткий. Хочу из этого же проекта классы реализующие запросы к БД.
не найдется, bookList итак null'ом будем. Ещё забавляет попытка экономии
памяти с отложенной инициализацией, но это уже другая история...
2. Вообще возвращать null - дурацкая идея, для этого есть Collections.emptyList()
3. Напрягает алгоритм перебора с квадратичной сложностью
2. Почему возвращать null плохо?
3. Как улучшить алгоритм?
2. К примеру, в моём проекте 80% критических ошибок связано с NPE
3. Использовать для поиска БД
Ну да, а ждать, пока нажатие на "Другие книги этого автора" будет выполнять поиск по БД с квадратичной сложностью - не спорно. Ну-ну.
П. С. Хотя в данном примере наверное все-таки логично было бы создать сущность. Ибо Пушкин написал далеко не одну книгу.
2. В целом соглашусь. Сам предпочитаю никогда не возвращать null. Использую emptyList().
С другой стороны это может быть логика: либо Null, либо в списке по крайней мере один элемент. Отчасти дело вкуса.
3. Описал чуть выше, когда это сделать не получится
Зависит от семантики. Однозначного ответа быть не может.
Не вижу ничего зазорного в некоторых случаях возвращать конкретную реализацию, вместо интерфейса.
П. С. Вообще в беседе пока только мы вдвоем учавствуем как-то =)
именно потому, что в жаве хрен так просто что-то отфильтруешь.
Ещё часто вижу примеры, где Lisp бы идеально подошёл для создания DSL (последнее, что приходило в голову - генерация MathML-кода). Поэтому подумываю поближе посмотреть Clojure в ближайшем будущем.
Что это?
Is Google broken today?
Я, например, иногда пишу небезопасный код: в API возвращается List, а я его модифицирую, зная, что его можно модифицировать, т. к. возвращается копия да к тому же изменяемая.
Так почему же возвращать ArrayList - это плохо? Вроде как сразу явная декларация намерений происходит =)
> явная декларация намерений
когда я вижу метод, который возвращает ArrayList, я скорее буду воспринимать это как неопытность автора кода, чем как декларацию намерений. И, скорее всего, полезу в сорцы. Не проще ли написать по-человечески и задокументировать семантику?
И вообще этот больше смахивает на метод модели.
>когда я вижу метод, который возвращает ArrayList, я скорее буду воспринимать это как неопытность автора кода
в public методах пожалуй соглашусь
>написать по-человечески и задокументировать семантику
код по сути тоже может являться документацией. ведь юнит-тесты по сути документация.
да нет, как раз-таки это нормально - возвращать конкретный подкласс - так больше возможностей манипуляции с ним.
а вот на вход хорошая практика подавать интерфейсы
А просто "return bookList;" не дает ответа может ли возвращаться null или нет.
Поэтому, если меня просят что-то посмотреть требую описание методов. Хотя бы на любом сленге, которым обладает индивид. Вот это и есть "документация". Но, сами понимаете, еще надо найти понимающих свою же логику студентов 😀
> bookList.add(author);
Оно будет работать раз в 5 медленней, верно?
Как скала обрабатывает пресловутые nullы?
2. В Scala не принято вообще использовать null. Пустые списки, как правило, инициализируются значением Nil, что в некотором роде аналогично Collections.emptyList(). Если результат поиска может быть неопределён (find в примере), возвращается инстанс класса Option, который может содержать, а может и не содержать значение (вызов isDefined в примере). Null в любом случае не возвращается.
а вообще писать на функциональных языках - огромное удовольствие.
от слова "поганый"?
fixed? 🙂
Что, в данном случае, обозначает символ _ ?
Глобальное пространство имен?