Сергей Протько: не совсем понял почему вы решили что user manager должен менятся. В моем случае есть классы UserEntity (DTO), UserDao (DAO), UserManager (Business Logic Controller), понятно что они в какой-то степени связаны: в entity определены поля и связь с хранилищем данных, в DAO логика чтения/записи в хранилище данных, manager - нужен для того чтоб определять бизнеса логику для user. Само по себе изменение одного из них не принуждает к обновлению других, но если у вас добавилось новое поле в табличке то в DAO вам нужно его записать в (вычитать из) хранилище(а) данных, в бизнесс логике откуда-то вытянуть/куда-то положить.
p.s. В моем случае DAO это native sql
p.s. Если же речь идет о Java, и вы используете ORM или JPA то возможно есть смысл в доменных обьектах "User" а-ля EJB 2.0. Правда JPA с EntityManager в принцыпе покрывает большую половину того что вы описали (по функционалу). Правда я предпочитаю jdbc всяким orm фреймворкам.
p.s. single responsibility я трактую дословно - у класса одна ответственность - одна простая задача/цель. Entity (model) - отвечает за представление данных, Dao (controller) - за операции над entity с хранилищем данных, Manager (controller) - только за бизнес логику которая относится только к user. Создавая класс User который будет одновременно и DAO и Entity (контроллером и моделью) я возлагаю на него 3 задачи: модель данных, сохранение данных, это будет подобие active record. Если же "скрестить" Entity и Manager получится domain object, в котором модель данных будет смешана с бизнесс логикой. При наличии сложной бизнесс логики этот обьект рано или поздно постигнет участь god-class, как минимум проблемы с конкурентыми модификациями, постоянные мерджи. Возможно у вас получится локализировать изменения в одном классе, но в целом количество изменений в коде будет такое же как и в моем случае, просто у вас классы будут потолще. Я буду утверждать что ваш подход хуже но мне кажется он имеет место быть только в случае использования ORM фреймвоков у которых нет явно выраженного data access layer или для маленьких проэктов которым плевать на перфоманс.
p.s. и еще, разделение на model и conroller это не я придумал, и взято это не из паттерна MVC а с "еще одна умная книжка", в оригинале речь шла о Dto/VO и controller/manager, я просто упростил для понимания используя слова из MVC паттерна (еще когда читал так запомнил, давно это было поэтому данные о источнике давно утеряны, соль - осталась)
Сергей Протько: мы практически говорим об одном и том же только... если речь идет о enterprise приложении то классы должны попадать в одну из категорий: model, controller. Их роли такие же как и в паттерне MVC, модель хранит данные а контроллер управляет состоянием модели. Поэтому класса User который хранит данные и имеет набор операций для манипуляции над ними - быть не должно (single responsibility). А все остальное, - это лишь вопрос выбора наименования (пары модель/контроллер): UserDto/User, UserData/User, User/UserManager итд итп... лично я пользуюсь вариантом наименованием схожим на последнюю пару.
p.s. о active record: последний раз пользовался подобным API лет 8 назад, в мире java такое уже давно не актуально... как в других языках обстояит дела я не в курсе
1) названия можно было выбрать получше:
-) is_account_available... --> has_account
-) create_new_account --> create_account - new совсем не нужен т.к. вы не будете создавать уже существующий аккаунт.
-) log_in_user --> login - неужели когда-либо в жизни вы будете логинить что-то еще?
-) remove_authentication_for_user --> logout - аутентификация это процесс ее нельзя удалить.
3) управление аккаунтами и управление сессиями это разные вещи, а значит как минимум 2 класса: AccountManager, SessionManager
4) API предложенный вами на самом деле не очень удачный, тот кто им будет пользоватся всегда будет писать шаблонный код: если аккаунта нету - создаем его. В идеале достаточно AccountManager.get(accountName) - внутри которого уже будет зашит бойлерплейт код.
5) account != user, первое это учетная запись, второе - пользователь. Количество связей между ними определяется самим приложением (1 аккаунт - много юзеров, или много аккаунтов - 1 юзер) , но все таки это не одно и тоже
Сергей Протько: в теории вы правы, но если предположить что ваши классы "User, Product, Order" по каким-то причинам имеют суффикс Manager... то результат будет тот же.
в этой строчке не только x может быть null, а еще entityManager. Скорее за все проблема именно в нем, т.к. исправляется рестартом. Смею предположить что вы неправильно инициализируете ссылку или еще что-то
типичная ошибка всех програмистов, опишите сначала задачу которую пытаетесь решить а потом уже проблему которая возникла а то со стороны как дон кихот и мельницы...
kicumkicum: касательно ветки - даже если ветки нету все равно ее состояние сохранилось в истории девелопа или же мастера. В девелопе/мастере должен быть коммит merged release branch 0.1, 0.3, 0.5 итд итп
kicumkicum: Merge добавляет коммиты в конец истории, rebase перезатирает всю историю встраивая коммиты в середину дерева (что иногда может упростить задачу мерджа, но может и усложнить т.к. придется мержить всю историю c возникшим конфликтом). Поэтому лучше тренироватся в бранчах-клонах. Иногда хотфикс проще заново прикрутить в новой версии чем 3 дня мерждить историю изменений за пол года из за конфликта с хотфиксом.
все что вам нужно это транзакции на стороне сервера, все изменения сделаны внутри одной транзакции приложения приходят одной транзакцией в субд, если что-то пойдет не так субд применит всю транзакцию или же не применит ничего. гуглить: java transaction management
p.s. транзакции на стороне сервера могут быть вложенными поэтому не всегда одна транзакция приложения = одна транзакция на стороне базы данных
Cоветую почитать о java ee, все сервера реализуют эту спецификацию, каждый по своему но это уже нюансы. Вы узнаете что они умеют делать. Каким образом они это делают можно посмотреть на их официальном сайте.
ваш случай это обычный hotfix, делается hotfix бранча с release/0.1, делаются все необходимые изменения и хотфикс мерджится обратно в бранчу. Далее стоит задача обновить другие бранчи которые ушли далеко вперед: develop, master другие релиз бранчи. Если разница небольшая (по коду не по версиям), то можно просто замержить (merge) хотфикс бранчу прямо в бранчу с релизом, dev, master. Если разница существенная то придется таргет бранчу ребейзить (rebase) на бранче хотфикса (т.е обновлять всю историю). Чтоб не решать одни и те же проблемы с мердж конфликтами можно мержить так (если первая проблемная бранча 0.2):
0.2 = 0.2 + hotfix (merge), 0.3 = 0.3 + 0.2 (уже с hotfix, rebase), 1.0 = 1.0 + 0.3 (уже с hotfix, rebase) итд итп.
sirs: мы пользовались обеими подходами, метод для маппинга данных внутри дао выглядит как-то так:
protected ResultEntity map (Object row) { // row - api specific object
Integer id = row.getField (Integer.class, "id", null); // type, column name, default value
Boolean nullableField = row.getField(Boolean.class. "nullableField", Boolean.FALSE);
ResultEntity e = new ResultEntity();
e.setId (id);
e.setNullableField (nullableField.booleanValue());
return e;
}
Павел Дуденков: есть несколько моментов : 1) вычитка данных должна быть только с пейджингом 2) читаем только primary keys 3) по возможности используем апи для выборки только primary keys вместо апи для обычных select
если смотреть на код, ваш уровень - junior, не пытайтесь устроится на позицию мидла, позиция это не только деньги это еще и требования. Лучше устроится на позицию джуна в нормальную компанию, - поработать, набратся опыта, чем непойми куда на позицию мидла. Чем ниже ответственность возложенная на вас тем проще задания и тем больше времени будут тратить на ваше обучение
"понимание" - слишком абстрактное понятие, я б выделил несколько этапов разработки. проэктирование
1) разработка схемы с учетом нормальных форм
2) создание индексов (обычно под те запросы которые планируете использовать)
пост-оптимизация:
2) анализ перфоманса запросов на реальных данных, смена типов индекса (итд итп)
3) денормализация данных (в тех редких случаях когда перфоманс важнее)
p.s. В моем случае DAO это native sql
p.s. Если же речь идет о Java, и вы используете ORM или JPA то возможно есть смысл в доменных обьектах "User" а-ля EJB 2.0. Правда JPA с EntityManager в принцыпе покрывает большую половину того что вы описали (по функционалу). Правда я предпочитаю jdbc всяким orm фреймворкам.
p.s. single responsibility я трактую дословно - у класса одна ответственность - одна простая задача/цель. Entity (model) - отвечает за представление данных, Dao (controller) - за операции над entity с хранилищем данных, Manager (controller) - только за бизнес логику которая относится только к user. Создавая класс User который будет одновременно и DAO и Entity (контроллером и моделью) я возлагаю на него 3 задачи: модель данных, сохранение данных, это будет подобие active record. Если же "скрестить" Entity и Manager получится domain object, в котором модель данных будет смешана с бизнесс логикой. При наличии сложной бизнесс логики этот обьект рано или поздно постигнет участь god-class, как минимум проблемы с конкурентыми модификациями, постоянные мерджи. Возможно у вас получится локализировать изменения в одном классе, но в целом количество изменений в коде будет такое же как и в моем случае, просто у вас классы будут потолще. Я буду утверждать что ваш подход хуже но мне кажется он имеет место быть только в случае использования ORM фреймвоков у которых нет явно выраженного data access layer или для маленьких проэктов которым плевать на перфоманс.
p.s. и еще, разделение на model и conroller это не я придумал, и взято это не из паттерна MVC а с "еще одна умная книжка", в оригинале речь шла о Dto/VO и controller/manager, я просто упростил для понимания используя слова из MVC паттерна (еще когда читал так запомнил, давно это было поэтому данные о источнике давно утеряны, соль - осталась)