Проблема в том, что рефакторинг кода никогда не запланирован в проекте. Когда код заработал, тестовая группа отчитлась, и менеджер ставит следующее задание о добавлении функционала. Рефакторинг в среде менеджеров (и уж тем более клиентов) — вещь немодная, и воспринимается как оправдание. В итогде код быстро обрастает говном как снежный ком. И наступает этап, когда рефакторить уже обросший функционалом код не представляется возможным. А поддержку этого дерьма делать приходится. Время на поиск ошибки увеличивается в разы, а при добавлении нового функционала всегда что-нибудь отваливается. Поэтому изначально нужно продумать хорошо скелет и прототип системы, что называтся, положить рельсы.
Тем не менее, можно идти и вашим путем, если запланировать полный рефакторинг (читай — переписать с нуля) с версии 2.0. Новая архитектура будет разработана с учетом опыта и потребностей реально работающей системы.
1. Позволяет прозрачно добавить пулинг объектов или кеш в любой момент, или сконвертировать в singleton.
2. При комбинации более понятные названия методов лучше, чем перегрузка в разных конструкторах. Например, такие:
Color.newRGB(...)
Color.newHSL(...)
Color.fromString( String name )
Color.fromCSS( String style )
3. Позволяет подменить возвращаемый объект его специфической имплементацией.
4. Позволяет не писать дважды generics-параметры при инициализации:
Pair<String,Integer> pair = new Pair<String,Integer>( «test», 1 )
Pair<String,Integer> pair = Pair.create( «test», 1 )
где factory method:
public static <T1,T2> Pair<T1,T2> create( T1 v1, T2 v2 );
5. Многие фреймворки требуют дефолтный no-args конструктор для java beans. Если Вы создали свой конструктор с параметрами, также требуется добавить дефолтный no-args. Если же у вас factory methods, то дефолтный конструктор присутствует всегда.
Композиция очень хорошая штука, но в Java нет автоматического delegate. В итоге приходится для каждого метода вручную писать вызов к delegate.
По возможности использовать только immutable объекты. Особенно там, где дело касается POJO. Помнить, что для сложных структур данных Java Beans — худшее, что можно только придумать, поскольку не делают различия между ссылкой и значением. Геттеры, возвращающие коллекции, должны либо врапить их в unmodifiable() либо создавать копию коллекции.
Использовать преимущественно static factory methods, а не конструкторы для создания новых экземпляров.
Клонирование имеет смысл, когда оно глубокое (весь граф). Его проще сделать через сериализацию-десериализацию.
При использовании EventBuses не обязательно разрегистрироваться, хотя и желательно, например EventBus из Guava регистрирует WeakReference на listener. Eсли правильно использовать IoC контейнер, то все мероприятия по сборке/разборке component assembly должен делать именно он. Компонент не должен вручную контролировать свой lifecycle. Для этого существуют Scopes.
MediaTomb транскодинг не поддерживает. Так что читаться мало что будет. Я дома держу Serviio — наверное лучший DLNA сервер. Огромная база профайлов под различные устройства, транскодинг практически из коробки. Из недостатков — java.
Просто так к теме… Когда-то мой преподаватель, работавший ранее на оборонку, утверждал, что мировые производители электроники специально оставляют подобные вещи в своих продуктах, дабы при необходимости парализовать системы неприятеля…
Но даже при выключенной паранойе кажется странной реакция кода на один единственный байт со значением именно 2 или 3.
У меня на работе тоже монитор повернут на 90 градусов. Текст програмы очень удобно редактировать. Только там это дешевый Dell 4:3. А для панорамного монитора вертикаль получается непропорционально большой.
Сайлоны были созданы человеком. Они восстали. Они развивались. Они выглядят и чувствуют как люди. Некоторые из них запрограммированы думать, что они люди. Существует множество копий. И у них есть план.
Теоретически пользователь может переустановить программу на свой компьютер, или переустановить всю систему. Интересуюсь потому что к нам в компанию (крупная мультинациональная) время от времени приходят комплейны от разных производителей по поводу лицензий с именами машин и IP, где установлн нелицензионный софт. Это нормально, инциденты устраняются, лицензии покупаются. Вопрос в том, как они узнают и не является ли это потенциальной дырой в безопасности? Особенно отличается TOAD, которая по-видимому тупо шпионит за пользователями.
> Скажите, а что конкретно вам не нравится в том, что ради единичных, «государственной важности» ресурсов будут сделаны исключения?
Не нравится именно вот это:
> Непосредственно ответ на мой вопрос выглядел примерно следующим образом: «Мы не знаем на каком основании зарегистрирован данный домен. За информацией обращайтесь в координационный центр».
Как и любое государственное ведомство оно должно следовать четким правилам документооборота. То есть на любой сторонний вопрос типа: «Какого хрена?» должен быть четкий ответ: «На основании такого-то постановления такой-то комиссии от такого-то числа ввиде исключения то-то и то-то» и ссылка на документ. Панибратские отношения между государственными структурами, типа «Михалыч, а зарегь-ка мне такой-то домен», не предусмотрены настоящим законодательством. Более того, любой интересующийся может потребовать расследоваиня по факту нарушения/несоответствия, и ведомтво обязано будет отчитаться или предоставить необходимые документы.
> Тем-не менее не бывает языков со статической и динамической типизаций одновременно. Хотя забегая вперед скажу, что тут я вру — они действительно существуют, но об этом позже.
Groovy имено такой язык. Не просто поддерживает динамику, а именно задумывался как язык одновременно со статической и динамической типизацией.
> Преимущества статической типизации…
Основное и главное (для меня) преимущество статической типизации — это поддержка IDE. Не нужно при вызове API каждый раз бегать в документацию, сверять имена и типы параметров. IDE сама показывает необходимые варианты, исходя из контекста. В итоге работа со сторонними API убыстряется в разы.
Два вопроса: КАК и ЗАЧЕМ? На первый вопрос Вы ответили.
Пытаясь приспособить абстрактные функциональные идиомы для вещей, для которых уже имеются более конкретные и удобоваримые средства, мы теряем читаемость кода и резко увеличиваем градус абсурда. Я не думаю, что фигурирование в контексте методов right() и left() имеют какую-то серьезную смысловую нагрузку для решаемой задачи. А соответствено это мусор, от которого нужно избавиться. Я понимаю, что количество методов для решения задачи и сложность оных не ограничено сверху. Но лично я за простоту и лаконичность.
P.S. В Guava есть поддержка функциональных идиом. Там же дается четкая рекомендация не использовать их в Java:
Excessive use of Guava's functional programming idioms can lead to verbose, confusing, unreadable, and inefficient code. These are by far the most easily (and most commonly) abused parts of Guava, and when you go to preposterous lengths to make your code «a one-liner,» the Guava team weeps.
> whereEqual(«genres.item.name», «Rock»)
Ссылаться на поля строковыми параметрами как-то противоречит идеологии typesafe.
Есть фреймворк QueryDsl. Это не ORM, но надстройка над ним для typesafe запросов. ORM-backend-ом может являться все что угодно — JPA/JDO/MongoDB/SQL. Изначально сделан под Java, но есть порт под Scala: blog.mysema.com/2010/09/querying-with-scala.html
Холст я вообще считаю некоей искусственной подпоркой для внезапно открывшегося рынка. Мне это сильно напоминает возврат в 90-е годы, когда я писал подобные игрушки на турбо-паскале под ДОС. Все приходится делать вручную — крутить цикл, опрашивать ввод, организовывать объектный граф, вычислять дельты и перемещения, компоновать и рисовать, etc… Есть конечно фреймворки, упрощающие задачу. Но все-таки основная тенденция всегда была к декларативному описанию сцены, а не императивному. Канвас хорошо подходит для битблитовых динамичных игр. Я занимаюсь программированием настольных игр типа шахмат, карт и т.д. И на канвасе реализовывать драг-дроп или простую анимацию фигуры или падения карты весьма сложно по сравнению с транзишном.
> Вполне же можно задать одному элементу несколько переходов для разных свойств.
Можно-то оно можно, но синхронно для всех свойств. Нельзя одновременно задать, чтоб объект ехал вправо 2 секунды, а при этом вращался только одну. Вообще сложные транзишны без JS не сделать.
> работает уже давно, кроме IE, в котором и переходы-то в новинку
Тем не менее, программируя игру для масс, приходится равняться именно на IE9 (т.е. по худшему). Потому как пользователю абсолютно наплевать что и как там поддерживается в его браузере. Если он заходит на сайт и игра не работает, то он делает логичный вывод, что игра-дерьмо, а вовсе не его браузер ;)
На фоне всех технологий очень понравился SVG. Несмотря на то, что он еще не очень приспособлен для динамики и сложных сцен, функционал достаточно широкий. Однако на данный момент аппаратное ускорение поддерживается, как ни странно, только IE 9. Плюс у андроида поддержка только от версии 3.0 (и то фиговенько). Так что пока CSS шустрее и «поддерживаемей». Но думаю, будущее именно за SVG.
Опа. У меня лет 5 такой же стоит. Летом, когда дома температура поднимается до 30+, регулярно зависает. Ставил мониторинг температуры, показывал нормальную. Помогло залочить вентилятор на максимальной скорости.
Как-то делал игру на CSS. Из опыта использования CSS-анимаций:
— Работает реально плавнее, чем JS-анимация, ибо используется GPU.
— Скейлинг работает быстро, но некачественно. Поскольку объект не перерисовывается, а скейлится только его отрендереный bitmap. Особенно заметно на шрифтах.
— Какой-то браузер, кажется Safari Mobile, не использовал GPU, если анимировались свойства left и top. С трансформами все работало.
— Transitions задаются на уровне элемента, а не на уровне свойств. Поэтому для одного элемента нельзя создавать различные независимые таймлайны для разных свойств. Как вариант врапать элемент несколькими div-ами, у каждого из которых менять только одно свойство.
— Нет стандартного способа для callback-ов по завершению анимации. Transitionend в половине браузеров не работает. Приходится callback тупо вешать на таймер.
— До сих пор нет массовой поддержки keyframe-анимации. Составные анимации приходится контролировать на JS.
— Отсутствует path-анимация, которая есть в SVG. Также нет возможности задать свою функцию интерполяции. Поэтому невозможно задавать достаточно сложные траектории движения объекта.
— На работе Chrome иногда выдает какие-то странные артефакты при перерисовке, либо вообще не работает. Скорей всего проблема в видеокарте/драйвере. С другой стороны, в Safari/Firefox работает хорошо.
Вывод: для сложных игровых сцен CSS-анимация еще не готова. Везде приходится юзать JS. Для простых же эффектов на странице — это самое то.
P.S. Был эксперимент как подружить CSS и JS анимацию. Фишка в том, что JS контролировал анимацию и просчитывал только ключевые фреймы с достаточно большим интервалом. А промежуточная интерполяция осуществлялась CSS. Но бросил раньше, чем удалось довести это до ума.
Тем не менее, можно идти и вашим путем, если запланировать полный рефакторинг (читай — переписать с нуля) с версии 2.0. Новая архитектура будет разработана с учетом опыта и потребностей реально работающей системы.
2. При комбинации более понятные названия методов лучше, чем перегрузка в разных конструкторах. Например, такие:
Color.newRGB(...)
Color.newHSL(...)
Color.fromString( String name )
Color.fromCSS( String style )
3. Позволяет подменить возвращаемый объект его специфической имплементацией.
4. Позволяет не писать дважды generics-параметры при инициализации:
Pair<String,Integer> pair = new Pair<String,Integer>( «test», 1 )
Pair<String,Integer> pair = Pair.create( «test», 1 )
где factory method:
public static <T1,T2> Pair<T1,T2> create( T1 v1, T2 v2 );
5. Многие фреймворки требуют дефолтный no-args конструктор для java beans. Если Вы создали свой конструктор с параметрами, также требуется добавить дефолтный no-args. Если же у вас factory methods, то дефолтный конструктор присутствует всегда.
По возможности использовать только immutable объекты. Особенно там, где дело касается POJO. Помнить, что для сложных структур данных Java Beans — худшее, что можно только придумать, поскольку не делают различия между ссылкой и значением. Геттеры, возвращающие коллекции, должны либо врапить их в unmodifiable() либо создавать копию коллекции.
Использовать преимущественно static factory methods, а не конструкторы для создания новых экземпляров.
Клонирование имеет смысл, когда оно глубокое (весь граф). Его проще сделать через сериализацию-десериализацию.
Но даже при выключенной паранойе кажется странной реакция кода на один единственный байт со значением именно 2 или 3.
А commons — это как раз велосипед. Просто на порядок сложнее.
Простите, а это как? Шпионите потихоньку? А это прописано в лицензионном соглашении?
Не нравится именно вот это:
> Непосредственно ответ на мой вопрос выглядел примерно следующим образом: «Мы не знаем на каком основании зарегистрирован данный домен. За информацией обращайтесь в координационный центр».
Как и любое государственное ведомство оно должно следовать четким правилам документооборота. То есть на любой сторонний вопрос типа: «Какого хрена?» должен быть четкий ответ: «На основании такого-то постановления такой-то комиссии от такого-то числа ввиде исключения то-то и то-то» и ссылка на документ. Панибратские отношения между государственными структурами, типа «Михалыч, а зарегь-ка мне такой-то домен», не предусмотрены настоящим законодательством. Более того, любой интересующийся может потребовать расследоваиня по факту нарушения/несоответствия, и ведомтво обязано будет отчитаться или предоставить необходимые документы.
Groovy имено такой язык. Не просто поддерживает динамику, а именно задумывался как язык одновременно со статической и динамической типизацией.
> Преимущества статической типизации…
Основное и главное (для меня) преимущество статической типизации — это поддержка IDE. Не нужно при вызове API каждый раз бегать в документацию, сверять имена и типы параметров. IDE сама показывает необходимые варианты, исходя из контекста. В итоге работа со сторонними API убыстряется в разы.
Пытаясь приспособить абстрактные функциональные идиомы для вещей, для которых уже имеются более конкретные и удобоваримые средства, мы теряем читаемость кода и резко увеличиваем градус абсурда. Я не думаю, что фигурирование в контексте методов right() и left() имеют какую-то серьезную смысловую нагрузку для решаемой задачи. А соответствено это мусор, от которого нужно избавиться. Я понимаю, что количество методов для решения задачи и сложность оных не ограничено сверху. Но лично я за простоту и лаконичность.
P.S. В Guava есть поддержка функциональных идиом. Там же дается четкая рекомендация не использовать их в Java:
Excessive use of Guava's functional programming idioms can lead to verbose, confusing, unreadable, and inefficient code. These are by far the most easily (and most commonly) abused parts of Guava, and when you go to preposterous lengths to make your code «a one-liner,» the Guava team weeps.
Ссылаться на поля строковыми параметрами как-то противоречит идеологии typesafe.
Есть фреймворк QueryDsl. Это не ORM, но надстройка над ним для typesafe запросов. ORM-backend-ом может являться все что угодно — JPA/JDO/MongoDB/SQL. Изначально сделан под Java, но есть порт под Scala: blog.mysema.com/2010/09/querying-with-scala.html
> Вполне же можно задать одному элементу несколько переходов для разных свойств.
Можно-то оно можно, но синхронно для всех свойств. Нельзя одновременно задать, чтоб объект ехал вправо 2 секунды, а при этом вращался только одну. Вообще сложные транзишны без JS не сделать.
> работает уже давно, кроме IE, в котором и переходы-то в новинку
Тем не менее, программируя игру для масс, приходится равняться именно на IE9 (т.е. по худшему). Потому как пользователю абсолютно наплевать что и как там поддерживается в его браузере. Если он заходит на сайт и игра не работает, то он делает логичный вывод, что игра-дерьмо, а вовсе не его браузер ;)
На фоне всех технологий очень понравился SVG. Несмотря на то, что он еще не очень приспособлен для динамики и сложных сцен, функционал достаточно широкий. Однако на данный момент аппаратное ускорение поддерживается, как ни странно, только IE 9. Плюс у андроида поддержка только от версии 3.0 (и то фиговенько). Так что пока CSS шустрее и «поддерживаемей». Но думаю, будущее именно за SVG.
— Работает реально плавнее, чем JS-анимация, ибо используется GPU.
— Скейлинг работает быстро, но некачественно. Поскольку объект не перерисовывается, а скейлится только его отрендереный bitmap. Особенно заметно на шрифтах.
— Какой-то браузер, кажется Safari Mobile, не использовал GPU, если анимировались свойства left и top. С трансформами все работало.
— Transitions задаются на уровне элемента, а не на уровне свойств. Поэтому для одного элемента нельзя создавать различные независимые таймлайны для разных свойств. Как вариант врапать элемент несколькими div-ами, у каждого из которых менять только одно свойство.
— Нет стандартного способа для callback-ов по завершению анимации. Transitionend в половине браузеров не работает. Приходится callback тупо вешать на таймер.
— До сих пор нет массовой поддержки keyframe-анимации. Составные анимации приходится контролировать на JS.
— Отсутствует path-анимация, которая есть в SVG. Также нет возможности задать свою функцию интерполяции. Поэтому невозможно задавать достаточно сложные траектории движения объекта.
— На работе Chrome иногда выдает какие-то странные артефакты при перерисовке, либо вообще не работает. Скорей всего проблема в видеокарте/драйвере. С другой стороны, в Safari/Firefox работает хорошо.
Вывод: для сложных игровых сцен CSS-анимация еще не готова. Везде приходится юзать JS. Для простых же эффектов на странице — это самое то.
P.S. Был эксперимент как подружить CSS и JS анимацию. Фишка в том, что JS контролировал анимацию и просчитывал только ключевые фреймы с достаточно большим интервалом. А промежуточная интерполяция осуществлялась CSS. Но бросил раньше, чем удалось довести это до ума.