- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
public class Settings {
public static String CURRENCY = "руб.";
public static void setCurrency(String currency) {
CURRENCY = currency != null ? currency : "руб.";
}
}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+78
public class Settings {
public static String CURRENCY = "руб.";
public static void setCurrency(String currency) {
CURRENCY = currency != null ? currency : "руб.";
}
}
Мой проект. Можно ли считать это ГК?
по коду будет верна, а по смыслу - нет.
Да и у одной и той же валюты может быть несколько обозначений ("р.", "руб.", "рубль").
а вообще имеет смысл изучить java i18n and l10n api:
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Currency.html
Не говоря уже о сомнительности нужности такого поля, вместо уже упомянутых стандартных средств. Но это зависит.
Вот делать нам нечего валюту нулом выворачивать. Имхо лучше перегрузка.
в огромных корпоративных приложениях, где коду за 30 лет, нельзя уследить за всеми трансформациями, придет нулл или нет.
проще в одном месте поставить проверку, нежели по 1000 местам дрожать, не пойдет ли нулл.
C# автоматически кидает NullReferenceException, если кто-то пытается обратиться к нулёвой ссылке
- NullPointerException
Что я должен был подумать, пусть даже и в топике Java раздела?
- java проглатывает нули?
- NullPointerException
Проект пишу один, и в ближайшее время новых людей не будет. Проект - толстый клиент, выполняющий кое-какие расчеты. Пишу уже полгода.
В системе потихоньку начинает возникать потребность в конфигурации, но как она должна выглядеть и как должна быть реализована на данный момент не до конца понятно.
Поставили задачу: в проекте должна быть возможность конфигурирования валюты (сейчас только рубли). Замечу, что настройка исключительно для пользовательского интерфейса, т. к. никакой мультивалютности в программе нет.
В итоге, было принято решение делать это обычной стрингой, т. к. дает достаточно много плюсов:
- пользователь может сам задать в каком он виде хочет видеть валюту (USD, $, р., руб., грн.).
- получаем дополнительную гибкость, т. к. ничто не обязывает использовать валюты. Например, можно задать у. е., или даже баллы.
В толстом клиенте был сделан обычный комбобокс с наиболее часто используемыми вариантами (3-4 значения), а также с возможностью ввода своего значения.
Теперь по реализации.
Так как полноценного конфига у меня нет (см. выше), то было принято решение использовать глобальную переменную - как наиболее быстрый вариант.
1. Почему поле, а не геттер?. По мне, Settings.CURRENCY выглядит лучше и короче, чем Settings.getCurrency(). В конце-концов, когда надо будет заменить Settings.CURRENCY на Settings.getCurrency проблем не возникнет, ибо любая IDE сможет провести такой рефакторинг.
2. Почему поле назвал CURRENCY, а не currency? Чтобы лишний раз подчеркнуть, что значение используется как константа, не подразумевает модификации. У меня, как я думаю и у любого нормального java-кодера, не возникает желания что-нить присваивать чему-то, что написано БОЛЬШИМИ буквами. Вряд ли вы спешите что-нить присвоить SomeClass.SOMETHING. И вряд ли вы смотрите стоит ли там final или нет.
4. Почему проверка на null? Использую jpa/hibernate, добавил колонку, гибер сам ее создаст в базе. @Column(columnDefinition="...") не люблю использовать, т. к. там надо полностью прописывать sql по созданию колонки, а другого способа задать дефолтное значение вроде как нет. Поэтому, после обновления у клиентов в колонке окажется null.
Вот собсна и все. Рабочее решение, полностью удовлетворяющее текущие потребности, было реализовано за 30 минут. Никакой дополнительной архитектуры (классов, интерфейсов) притянутой за уши не потребовалось. Когда в программе появится полноценный конфиг - тогда все на него и переведется, причем без особых усилий.
Подытоживая выше сказанное: очень сложно судить о качестве кода, когда ты не в контексте. Нельзя придираться к коду только за то, что он нарушает какие-то каноны (public fields, глобальные переменные, именование и т. п.). Надо быть проще, оверинжиниринг еще никому на пользу не шел.
П. С. Не будте разъяренными обезьянами =) (взято из книги Нил Форд "Продуктивный программист. Как сделать сложное простым, а невозможное - возможным")
break;
так будем присваивать? да/нет
setSomething(x) - да!
Убери сеттер НАХУЙ, или сделай уже геттер, а поле в private!
чел просто упертый баран,мол, "это мой код, и я хочу писать его через жопу, лишь бы сэкономить пару байт и наносекуд, а если бы это был не мой код, я бы подумал"
вы, наверное, не очень опытный программист... Вас будет жалко потом, когда вы будете гулять по заботливо положенным собой же граблям.
ох, как всё запущено... да нет никаких злоебучих правил, есть только инструменты и умение программиста их использовать. Вы, к примеру, пытаетесь ввернуть в стену гвоздь отвёрткой и радуетесь, что Вам такое пришло в голову, а все вокруг - унылое гавно, заворачивающее шурупы шуруповёртом.
По делу. Если честно - ничего толкового из вышесказанного я не увидел.
Был вариант от foGa (по ТЗ не прокатит), от вас с вводом интерфейса (я бы глянул на него) или юзания стандартных средств (не подойдут). Была рекомендация ввести геттер вместо поля. Я объяснил в пункте 1 почему использую поле.
gegMOPO4 предложил ввести константу DEFAULT_CURRENCY. Ну, может быть стоит.
Вот и все. Фактически два варианта:
- Ну уж если это класс с настройками, то он должен знать обо всех значениях, какие ему можно присвоить. Точнее сказать, он должен знать у какого класса можно спросить эти значения (а еще возможно и на каком языке)
- Ну ведь логично было бы сделать интерфейс Currency с методами типа getSymbol(), getShortName() и getFullName() и enum с реализациями этого интерфейса, а в конфиге хранить текущую реализацию интерфейса
Если объясните как они будут заинтегрированы и чем они лучше, буду очень признателен. Хотите поговорить про ваш вариант? Я буду просто задавать вопросы, а вы отвечать =)
Как-то это некошерно. Но если уж надо, то кто мешает добавить еще пару методов типа
Не обязаны. Вот static они факт должны быть (так и есть), а вот immutable нифига. Мож у меня конфиг в процессе работы приложения будет расширяться в рамках данной сессии.
Так никто не будет завязан на ограниченный набор валют и сможет писать собственные реализации.
А вообще я думаю, что любые конфиги на клиенте должны отражать специфику его машины: URL для соединения с сервером, прокси сервера, предпочитаемые размеры окон, настройки логгирования. Валюты же - часть предметной области (вероятно, аттрибуты операций) и, скорее всего, должны храниться в БД. Но я не знаю деталей вашей работы и меня нет ни времени, ни желания разбираться глубже.
enum Currency {
RUB("руб.", "рубль", "р."),
EUR("eur", "евро", "не р.");
private String name_short;
private String name_long;
private String default_short_name;
Currency(String name_short, String name_long, String default_short_name) {
this.name_short = name_short;
this.name_long = name_long;
this.default_short_name = default_short_name;
}
public String getSortName() { return this.name_short; };
public String getLongName() { return this.name_long; };
public void setSortName(String name_short) { this.name_short = name_short; };
public void setLongName(String name_long) { this.name_long = name_long; };
public void setDefaultShortName() {
setShortName(this.default_short_name);
}
}
setDefaultShortName - не самое удачное этого название метода, лучше было бы что-нить в стиле restoreDefaultShortName.
Вообще для моего случая данная реализация не подходит.
>Вообще для моего случая данная реализация не подходит.
Ждем нового говнокода вашей реализации
Ключевая фраза "через GUI", пользователь приложения не будет править код.
П. С. Почему все фразу "не подходит" воспринимают как "ваш код говно"? Я ничего не говорил про код, все что я сказал, что он не подойдет.
тем более, что без отражения их в джаве нельзя расширять
В Модели же для хранения достаточно будет простого поля String currency; c аксессорами и списка вариантов List<String>, который можно будет сохранять и дополнять - по желанию.
кроме того, лучше Модель сделать сериализуемой, тогда ее будет очень просто сохранять и загружать.
Как организовать доступ к этому значению из произвольного места в приложении?
public String getCurrency() {return this.currency;}
public void setCurrency(String currency) {this.currency=currency;}
хотя лично мне еще нравится и "краткая" форма аксессоров:
public String currency(){return this.currency;}
public Settings currency(String currency){this.currency=currency;return this;}
кстати, и для общего развития в AOP не мешало бы нос сунуть
Класс больше месяца не проживет.
Вы по прежнему считаете, что в моем случае надо реализовать полноценный синглтон с полноценными названиями методов?
И везде в коде иметь Settings.getInstance().getCurrency() вместо Settings.CURRENCY?
тогда фтопку пляски с бубном, конечно.
А если писать реюзабельный код - тогда, бесспорно, Settings.getInstance().getCurrency()
эм, еще вопрос - у вас в классе Settings только одно поле CURRENCY?
именно так. сложно сказать, как лучше, не видя кода в глаза
1. ЗАГЛАВНЫМИ буквами следует называть только статические финальные поля, т.е. константы. Которые в коде НИКОГДА, ни через какие сеттеры, не меняются. Так привычно и всем, и мне же - исключения из правил очень легко забываются
2. Если нам не нужно контролировать доступ к обьекту(полю), его можно сделать публичным, но при этом иметь ввиду, что он в любой момент сможет держать некорректное значение
2.1. Иначе обязательно пользоваться инкапсуляцией
3. Нельзя доверять никому, в т.ч. себе, т.к.:
3.1.сложность проекта возрастет, дебаг станет мучительным
3.2.память человеческая коротка, к тому же все мы меняемся.
3.3.я не смогу код использовать повторно в других проектах или
3.4.отдать кому-то на поддержку или доработку
но, вы по прежнему считаете, что код говно или уже так не уверены, зная теперь о коде чуть больше: для чего он, как он появился, какую задачу решает и сколько по времени будет жить?
хочу короткий ответ:
"да" - по прежнему считаю что гавно,
"нет" - в свете дополнительно полученной информации в ДАННОМ случае такой код допустим.
далее видно, что непонятно ))
> хочу короткий ответ
экий вы максималист!
ДА, код говно
и я бы никогда не стал так делать, а лучше бы чуть подумал о других решениях, об изменении в архитектуре, ибо
ЕСЛИ ГОВНЯНОЕ РЕШЕНИЕ В ПРИЛОЖЕНИИ ВЫГЛЯДИТ ЛУЧШИМ, ЭТО ЗНАЧИТ, ЧТО ГОВНО ДАЛЕЕ, В АРХИТЕКТУРЕ
но: в ДАННОМ случае программирую не я, а вы, и вы же все равно сделаете по своему, и вам же потом расхлебывать
п.с. я бы никогда не взял ваш код на поддержку, "в свете дополнительно полученной информации" о том, что вы прибегаете к таким нестандартным решениям,
в ходе которых мне пришлось бы ломать голову, что вы здесь имели ввиду, и на каждой строчке спрашивать вас, а можно ли так делать, ничего не поломав
Не лучшим, а обоснованым. Я нигде ни слова не написал, что это крутое решение. Что это единственное правильное решение. Я говорил лишь то, что это - приемлемое решение.
> и я бы никогда не стал так делать
т. е. то что вы писали в постах выше - это вам на ухо нашептали?
Не нужно кричать. Мы вас слышим.
Я в своём паскале или бейсике в лёгкую присвою в SOMETHING новое значение. У меня руки чешутся сделать какую-нибудь гадость, если это не запрещено.
Во-вторых. По вашему лучше что-то придумать, нах..чить кучу кода, чтобы потом все равно его переписывать?
вы как раз этим и занимаетесь.
вон, многие тоже думали, что никто не будет лазать по "секретным" урлам, а Яндекс взял, и проиндексировал все к чертовой матери.
в книге "Code Craft" даже отдельная глава была: не делайте предположений!
Если есть возможность сделать нехорошую вещь, будьте уверены, что вы сами или кто-то другой ее сделает. Сделайте, что бы вы НЕ МОГЛИ сделать глупость, позже не раз порадуетесь
А, в принципе, и чужими, если код придется допиливать кому-то другому.
JavaBeans, к примеру, групповая привычка. Причем почти никто не знает почему надо делать именно так, но все так делают.
И еще. У меня имена всех тестовых методов в юнит тестах написаны в руби-стиле: маленькими буквами через подчеркивание. Мне, как я полагаю, положен расстрел за такие святотатства!
С другой стороны: что легче читать?
authorNameShouldBeSpecified
или
author_name_should_be_specified
Не надо обвинять всех в собственных грехах. Почитайте Core Java для начала, если не знаете, зачем нужны соглашения JavaBeans.
> С другой стороны: что легче читать?
в контексте наличия в Java поддержки пространств имён в виде пакетов и классов оба имени - гавно. Больше двух-трёх слов в имени переменной практически никогда не нужно.
если бы вы внимательно прочитали написанное, то вы бы увидели " имена всех тестовых МЕТОДОВ".
Насчет JavabBeans. Для многих JavaBeans не более чем: если есть поле, то для чтения использовать getField, для записи использовать setField(value).
для которых класс является пространством имён, а для класса пространством имён является пакет
> для многих JavaBeans не более чем
Не любого более-менее квалифицированного Java-программиста JavaBeans - технология, включающая помимо соглашений об именовании (обычных и boolean полей, полей - массивов) механизмы интроспекции, редакторов свойств, событий смены состояния, интеграции с IDE и ещё очень много всего. Просто в промышленности из всего многообразия лучше всего прижились соглашения именования.
Из-за этой фразы я сделал акцент на слове "методов". Насчет имени переменной длинее 2-3 слов - соглашусь. Насчет названия тестового метода - не соглашусь. Думаю этот вопрос можно закрыть.
Насчет JavaBeans. Хорошо сказали =) Боюсь, что здесь все считают, что они как минимум "более-менее квалифицированные программисты". Надеюсь, ваш ответ подскажет некоторым из них куда надо посмотреть для общего развития. =)
Вопрос также закрыли, а то что-то от темы отошли.
Пример я привел лишь для того, чтобы показать, что каждый шаг был обдуман и обоснован.
встречаются и от Дьявола = )
http://ru.wikipedia.org/wiki/Русский_алгоритмический_язык
Я всего лишь хотел показать, что не всегда то, что на первый взгляд выглядит говном - действительно говно. Часто незнание контекста позволяет кричать, что код говно. Я, например, редко ставлю +/- в темах, т. к. однозначно определить качество кода чаще всего достаточно тяжело. А ставить "+" или "-" без аргументации - это несерьезно. А когда просишь объяснить или сказать конкретно как надо - все сводится к увиливаниям и всячески отмазкам.
>Какая вам суть разница, если вы тут...
Мне и нет никакой разницы =) Все это постилось только ради см. выше
>И на каждую уместную или не уместную попытку сказать вам, что же не так в вашем коде
Дайте пж номера комментов с уместными попытками, хотя бы парочку. Буду очень признателен.
Думаю, у вас это ни разу не получилось. Со временем и у вас произойдёт эволюция от "Бля, какой заебатый код я написал: теперь всё работает и всё, сука, так запутанно, я тащусь!" до "Фуф, надеюсь, теперь этот код поймёт даже дебил".
Проблема более-менее квалифицированного программиста в том, что он умный. И из-за этого ума он часто не видит простых решений, ему сразу видятся иерархии, он видит это в объектах, он уже видит архитектуру. И часто он ее внедряет. Он просто разучился думать просто. Ему обязательно надо чтобы было ООП, и максимальная гибкость для будущих поколений. Чтобы все конфигурялось вдоль и поперек, чтобы все расширялось без геммороя. Именно более-менее квалифицированый программист чаще всего при простой задаче "добавить возможность задавать мобильный телефон для клиента" сделает не такую реализацию:
class Person {
...
private String mobilePhoneNumber;
...
}
а такую:
class Person {
...
private List<Phone> phones;
...
}
class Phone {
private PhoneType type;
private String phoneNumber;
private String notes;
}
enum PhoneType {
MOBILE, HOME, WORK
}
потому что он уверен, что эта гибкость пригодится в будущем: ведь теперь можно задавать несколько телефонов разного типа да еще оставлять примечания для каждого из них!
Проблема в том, что в 90% это не нужно, а сопровождать это приходится. Причем согласитесь, что с 1-й реализации перейти на 2-ю не представляет особого труда. Самое интересное, что до 2-й реализации скорее всего дело никогда и не дойдет.
ООП и Java не пуп земли. Для многих задач python или ФЯП подходят лучше, чем Java.
>и программного инженера, который всегда выбирает наиболее с его точки зрения подходящие для работы инструменты и модели
не поверите - я их и выбрал. А вы почему-то считаете, что я неопытный программист, который наворотил говна и пытается вам доказать, что написал идеальный код =)
И, судя по всему, не я один так считаю. Может, стоит задуматься об этом?
А профессиональный программист свято следует заповеди "НЕ усложняй (без надобности)".
> нужно подбирать наиболее подходящее решение
именно этой мыслью я и закончил свой пост
Кстати, ГК - не лучшее место для демонстраций и доказательств. Сюда люди приходят поржать и расслабиться, а не читать "многабукаффные" рассуждения о мотивах, которые подвинули вас на говнокод.
А вообще - я несу добро, и буду активно пропагандировать отвечать за свои слова! =)
Да, за такое поведение - жизнь карает, но он пока молод и этого не знает.
Из него выйдет хороший программист и человек в будущем, но пока он наступит на все грабли, что только найдёт, тк учится не на чужих ошибках, а на своих.
Он хочет докопаться до сути вещей самостоятельно и дать своё предположительное объяснение происходящему, а не поверить голословно миру или следовать общепринятым правилам и все подряд бездумно копировать.
Через какое то время он сможет самостоятельно предсказывать последствия любых действий (в различных областях) и поступков с большой точностью и почти перестанет наступать на грабли, но пройдет ещё много времени и граблей.
ПС: А ещё он дрочет. Это одна из черт самодостаточности. Любая мания величия или независимости от общества подкрепляется этим "пороком".
Все дрочат
http://mf0.me/wps/2009/10/06/onanizm/
Спс, кэп. Может на этом основании автор пасты и сделал вывод)
типичное поведение подростка, который пытается быть "не как все", а в итоге сваливается в кучу "всех".
особенно вредно сначала привыкнуть что-то так делать, потом пойти вразрез с привычкой, потом опять делать по-старому (заставят же). А потом открыть код и смотреть в него как баран на новые ворота: "какого хера не работает??"
Что то кэпов последнее время развелось. Или вы хотите намекнуть, что tir подросток?
если в обществе принято жрать говно, я НЕ СОГЛАСЕН СЛЕПО КОПИРОВАТЬ от общества.
а понято сколько раз?
почитано, но не прочитано.
Я это в пасте уже написал.
формулируя иначе, он же скомбинировал разные подходы в одном,
1. выложил это на ГОВНОКОД(!), расписавшись при этом, что сделал говно
2. и с пеной у рта стал всем доказывать, что это решение оправдано, т.е. дрочить на него = )
это называется "психологический вампиризм"
Если вы испытываете раздражение - у вас комплекс. Займитесь самоанализом. Причина раздражения всегда находится внутри нас.
Было бы похеру - еще вчера закрыли тему.
На гитхабе с удовольствием посмотрю.
Мое мнение: выглядит так, как будто написано, чтобы как-то работало, чтобы можно было делать UI часть. Коду предстоят рефакторинги, допилы. И покрытие тестами. Сильно сомневаюсь, что это конечные варианты классов. Скоро будет причесывание этого всего.
Мне непонравился момент, что
try {
...
setHeadAsStart(repo, revWalk);
setUpFilter(revWalk, filter);
...
return results;
} catch (Exception e) {}
в методах setHeadAsStart и setUpFilter возникающие ошибки глушатся намертво (с логированием). При этом основной метод отрабатывает как ни в чем не бывало. Т. е. можно получить не те данные которые просили.
Любой код, даже хороший, постоянно модифицируется. Как только модификации закончились, проект начинает умирать.
Я не провозглашаю себя мессией. Мне не надо, чтобы вы сказали: "веди нас к свету", мне вообще глубоко параллельно какие чувства я у вас вызываю, меня это не волнует. Моя цель описана в 1-м абзаце. Я никого не учу.
Отвечаю по пунктам.
1. > расписавшись при этом, что сделал говно
Я нигде не писал, что накодил говно. Предложеное вами решение ничем принципиально не отличается от моего. Никто так и не смог предложить вообще никакого решения (кроме вас). Хотя это был бы лучший аргумент, вместо того чтобы переходить на личности.
2. Дрочить не надо - сотретесь. Я ничего никому не доказывал. Я просто сказал, ПОЧЕМУ код написан именно так. Почему из моего объяснения вы сделали вывод, что я вас учу - это ваша проблема, разбирайтесь в себе, почему вы так это воспринимаете.
Все чего я ожидал - это то, что после прочтения моего объяснения вы просто сделаете для себя какие-то выводы, и примите это или нет.
2. все это пройденный этап - я уже писал большими буквами.
В общем, тред клозет. поржали и разбежались
*trollface*
petrosyan.jpg
Автор - тролль.
Тема - хуйня.
унылый тролль
хуйовый флуд
Фабрики - рабочим.
Деньги - кондуктору.
Чаще обращай на мнения людей, но я тебя плюсую. Ты прав.
Ой-ой.
1. SOMETHING будет выглядеть константой в глазах пользователя и это правильно.
2. setSomething() будет изменять эту константу и этот метод нужен, т.к. необходима, нет, НЕОБХОДИМА проверка на null.
3. getSomething() совершенно не нужен! Something можно только устанавливать, а читать можно SOMETHING - независимую константу.
*trollface*