Re: Класс DAL и много функций в нем
От: . Великобритания  
Дата: 30.09.13 10:26
Оценка: 8 (2)
Здравствуйте, Flem1234, Вы писали:

F>Какие еще аргументы за и против (технического плана, а не организационного) вы можете привести?

F>Кикие из приведенных аргументов кажутся неубедительными?
Попробуй ещё это:
http://www.javacodegeeks.com/2013/04/package-your-classes-by-feature-and-not-by-layers.html
http://www.javapractices.com/topic/TopicAction.do?Id=205

Вообще, странно почему pbf настолько нелюбим. Я вот помню тоже пытался это продвинуть, но все противятся, делая вот таких 400-методных монстров.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[13]: Класс DAL и много функций в нем
От: . Великобритания  
Дата: 03.10.13 13:15
Оценка: 4 (1)
Здравствуйте, GreenTea, Вы писали:

GT>А, ну в чем то вы правы. Так же у нас есть еще QueryDao, который предоставляет методы поиска через getCurrentSession(). Таким образом сервиса и бизнес обьекты, если им нужны только CRUD — инжектят BaseDao, если еще запросы QueryDao. Наверно это дань традиции так делать. + немного меньшая завязанность всего кода на Hibernate. Хотя, код и так прилично завязан из-за использования DetachedCriteria.

Кстати, рекомендую взглянуть на querydsl — на порядок лучше DetachedCriteria.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Класс DAL и много функций в нем
От: Flem1234  
Дата: 27.09.13 10:40
Оценка:
Всем привет.

У нас есть несколько класссов модулей (около 80ти) . Все они делают некоторые запросы, читают данные из БД. И все они принимают ссылку на объект класса DAL, который содержит все методы доступа к БД. Итого около 400 методов.

Я хочу сделать следующий рефакторинг: для каждого модуля определить интерфейс, который будет содержать только необходимое подмножество методов из всего множества, содержащегося в классе DAL, и передавать уже его в модуль. Мне кажется, это позволит без изучения реализации модуля узнать, какие функции доступа к базе он использует. Сейчас этого сделать невозможно, потому что модуль получает ссылку на ДАЛ, в котором хранятся все методы.

Но вот беда: мои коллеги не поддерживают мое начинание
Они говорят, что нужно выделять лишние сущности — интерфейсы со списком методов, и надо следить, чтобы в классах доступа к данным небыло неиспользуемых в модулях методов.

К тому же они не видят проблемы в изучении реализации модуля для того, чтобы понять, какие запросы он делает к базе.

Какие еще аргументы за и против (технического плана, а не организационного) вы можете привести?
Кикие из приведенных аргументов кажутся неубедительными?

Спасибо большое,
Игорь
Re: Класс DAL и много функций в нем
От: IT Россия linq2db.com
Дата: 28.09.13 05:27
Оценка:
Здравствуйте, Flem1234, Вы писали:

F>Но вот беда: мои коллеги не поддерживают мое начинание


Для начала спросите себя и своих коллег какие проблемы решают их ДАЛы и как ваши решения помогают их вам устранить.
... << RSDN@Home 1.2.0 alpha 5 rev. 69>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Класс DAL и много функций в нем
От: Flem1234  
Дата: 28.09.13 11:26
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Flem1234, Вы писали:


IT>Для начала спросите себя и своих коллег какие проблемы решают их ДАЛы и как ваши решения помогают их вам устранить.


У меня скорее другая ситуация: коллеги не видят проблемы в том, что каждый модуль принимает класс, в котором описаны все методы доступа к БД. Более того, они считают, что это полезно, потому что позволяет при написании модуля быстро узнавать, что такая функциональность уже есть и переиспользовать ее.

Короче, они себе представляют так:

Надо писать новый модуль:
Передал объект со всеми методами в модуль, поставил после него точку, выбрал из предложенных методов подходящий, если такого нет, то добавил в него (и в его интерфейс, и в его мок, потому что у нас есть мок для этого объекта для тестов) новый метод.
Надо фиксить или изменять старый: просмотрел реализацию модуля, нашел все методы, которые вызываются для нашего большого ДАЛ, поменял его, пофиксил мок, пофиксил интерфейс.

В случае мелких даллов, спроектированных для каждого модуля отдельно, не надо искать поиском по реализации модуля, а можно просто пофиксить интерфейс маленького дала и исправить то место, в котором ошибка была найдена компилятором. Плюс проще понимать код — изучив интерфейс для конкретного маленького дала, можно понять какие методя работы с БД он использует.

На это мне говорят, что реализацию модуля все равно надо изучать, потому что непонятно по сигнатуре метода, что он делает (хотя если настолько непонятно, как они собираются переиспользовать метод, который непонятно что делает) + что труднее поддерживать много интерфейсов, чем один интерфейс, хоть количество методов в них и равно.

На этом дискуссия зашла в тупик.

Спасибо за помощь, я выговорился и не полегчало
Re: Класс DAL и много функций в нем
От: MozgC США http://nightcoder.livejournal.com
Дата: 29.09.13 09:39
Оценка:
У меня в большинстве случаев классы DAL — статические. Примерно по классу на каждую таблицу в БД (CustomerAccessor, OrderAccessor и т.д.). Тесты работают с реальной БД (так все устроено уже несколько лет) и меня это устраивает.
Re: Класс DAL и много функций в нем
От: pavel783  
Дата: 29.09.13 12:14
Оценка:
дробить dal на более мелкие части имеет смысл в случае распределенной среды Data Access Layer, как например в случае rest сервиса — когда есть ресурсо ориентированный сервис который может хоститься отдельно от другой части сервиса. плоскостей как можно поделить dal много- можно делить по компонентам или по интерфейсам или типу connection — ssl/tcp итд, особой пользы конечно от такого деления не будет если это не было заранее запланировано и оценено
Re: Класс DAL и много функций в нем
От: GreenTea  
Дата: 29.09.13 13:46
Оценка:
Здравствуйте, Flem1234, Вы писали:

...

400 методов это конечно бред, и надо рефакторить. Только я бы это делал не по используемым внутри модуля функциям — типа 1 интерфейс на 1 модуль, а сгруппировал бы методы в отдельные сервиса. Так, что-бы сервис работал с одной (или несколькими связанными) сущностями. Потом каждый модуль инжектит себе нужные сервиса через спринг, ejb или что у вас там используется. Так же обратите внимание, что если у вас очень много методов поиска скажем сущности AAA (с разыми фильтрами поиска), то можно порефакторить это собрав все фильтры поиска в отдельный класс AAASearchCriteria, тогда будет только один метод принимающий серч критерию.
Как убедить коллег? То что сейчас у вас есть — явно быдлокод. Сделайте нормально и почувствуете себя людьми. Потом дальше работать будет приятнее, новички не будут шарахаться и бежать из такого проекта. Есть у нас тоже один страшный проект где годами за кодом никто не следил. Так текучка там дай боже, т.к. новенькие не выдерживают треша.
Re[2]: Класс DAL и много функций в нем
От: Nikolay_P_I  
Дата: 30.09.13 05:40
Оценка:
Здравствуйте, GreenTea, Вы писали:

GT>400 методов это конечно бред, и надо рефакторить.


Иногда некуда У нас тут есть БД в 51 таблицу. Только CRUD к ней даст эти самые 400.
Re[3]: Класс DAL и много функций в нем
От: GreenTea  
Дата: 30.09.13 15:20
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Здравствуйте, GreenTea, Вы писали:


GT>>400 методов это конечно бред, и надо рефакторить.


N_P>Иногда некуда У нас тут есть БД в 51 таблицу. Только CRUD к ней даст эти самые 400.


Хм, у нас таблиц почти столько же. 1 CRUD интерфейс для всех сущностей на 8 методов. Используем java/hibernate.
Re[4]: Класс DAL и много функций в нем
От: Nikolay_P_I  
Дата: 01.10.13 04:12
Оценка:
Здравствуйте, GreenTea, Вы писали:

N_P>>Иногда некуда У нас тут есть БД в 51 таблицу. Только CRUD к ней даст эти самые 400.


GT>Хм, у нас таблиц почти столько же. 1 CRUD интерфейс для всех сущностей на 8 методов. Используем java/hibernate.


А это как ? Я имею ввиду — реально методов, а не то, что только наружу как T Select<T> выставлено, а внутри кучу точных private вызывает.
Re[2]: Класс DAL и много функций в нем
От: Nikolay_P_I  
Дата: 01.10.13 04:17
Оценка:
Здравствуйте, ., Вы писали:

.>Вообще, странно почему pbf настолько нелюбим. Я вот помню тоже пытался это продвинуть, но все противятся, делая вот таких 400-методных монстров.


Ну мне, вот, например, с ходу не понятно — как там с взаимодействием. Типа 3 сущности апдейтятся с оглядкой друг на друга (порядок, ссылки)
Re[3]: Класс DAL и много функций в нем
От: . Великобритания  
Дата: 01.10.13 06:55
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

.>>Вообще, странно почему pbf настолько нелюбим. Я вот помню тоже пытался это продвинуть, но все противятся, делая вот таких 400-методных монстров.

N_P>Ну мне, вот, например, с ходу не понятно — как там с взаимодействием. Типа 3 сущности апдейтятся с оглядкой друг на друга (порядок, ссылки)
Не понял. Пример покажи.
pbf это распределение классов во пакаджам (неймспейсам), и ничего более. Обычный SRP, но разделение идёт не по красивым словам DAO, DAL, Service, понятным только программистам, а по логике бизнес-области User, Order, Account.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: Класс DAL и много функций в нем
От: GreenTea  
Дата: 01.10.13 07:51
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Здравствуйте, GreenTea, Вы писали:


N_P>>>Иногда некуда У нас тут есть БД в 51 таблицу. Только CRUD к ней даст эти самые 400.


GT>>Хм, у нас таблиц почти столько же. 1 CRUD интерфейс для всех сущностей на 8 методов. Используем java/hibernate.


N_P>А это как ? Я имею ввиду — реально методов, а не то, что только наружу как T Select<T> выставлено, а внутри кучу точных private вызывает.


Вот что я имел в виду:
public interface IBaseDao extends IService
{   
   public <T extends IEntity> void save(T instance) throws EntityConstraintException;
   public <T extends IEntity> void update(T instance) throws EntityConstraintException;
   public <T extends IEntity> void delete(T instance);
   public <T extends IEntity> void delete(Class<T> type, Long identifier);
   public <T extends IEntity> T read(Class<T> type, Long identifier);
   public <T extends IEntity> void saveOrUpdate(T instance) throws EntityConstraintException;
   public <T extends IEntity> void refresh(T instance);
   public <T extends IEntity> boolean isAttached(T instance);
}
Re[6]: Класс DAL и много функций в нем
От: GreenTea  
Дата: 01.10.13 08:02
Оценка:
Здравствуйте, GreenTea, Вы писали:

GT>Здравствуйте, Nikolay_P_I, Вы писали:


N_P>>Здравствуйте, GreenTea, Вы писали:


N_P>>>>Иногда некуда У нас тут есть БД в 51 таблицу. Только CRUD к ней даст эти самые 400.


GT>>>Хм, у нас таблиц почти столько же. 1 CRUD интерфейс для всех сущностей на 8 методов. Используем java/hibernate.


N_P>>А это как ? Я имею ввиду — реально методов, а не то, что только наружу как T Select<T> выставлено, а внутри кучу точных private вызывает.


Дошла суть вопроса.. Внутри тоже все примитивно



@Transactional
public class BaseDao extends AbstractDao implements IBaseDao
{
   @Override
   public <T extends IEntity> void save(T instance) throws EntityConstraintException
   {
      getCurrentSession().save(instance);      
   }

   @Override  
   public <T extends IEntity> void update(T instance) throws EntityConstraintException
   {
      getCurrentSession().update(instance);
   }

   @Override
   public <T extends IEntity> void delete(T instance)
   {
      if (null != instance) {
         getCurrentSession().delete(instance);
      }
   }
   
   public <T extends IEntity> void delete(Class<T> type, Long identifier)
   {
      delete(read(type, identifier));
   }


   @Override
   public <T extends IEntity> void saveOrUpdate(T instance) throws EntityConstraintException
   {
      try {         
         getCurrentSession().saveOrUpdate(instance);
      } 
      catch (HibernateException e) {
         processConstraintException(e, instance);
         throw e;
      }
   }

   @Override
   public <T extends IEntity> void refresh(T instance) {
      getCurrentSession().refresh(instance);
   }
   
   public <T extends IEntity> boolean isAttached(T instance) {
      return getCurrentSession().contains(instance);
   }
   
   private static void processConstraintException(HibernateException e, IEntity entity) throws EntityConstraintException {
      if (e instanceof PropertyValueException) {
         PropertyValueException z = (PropertyValueException)e;   
         throw new EntityConstraintException(z.getPropertyName(), null, entity);
      }
      else if (e instanceof ConstraintViolationException) {
            throw new EntityConstraintException(null, null, entity);
      }
   }
}
Re: Класс DAL и много функций в нем
От: Undying Россия  
Дата: 01.10.13 10:23
Оценка:
Здравствуйте, Flem1234, Вы писали:

F>Но вот беда: мои коллеги не поддерживают мое начинание


Не понял чем твое начинание им мешает? Ты же просто предлагаешь оставить тот же объект DAL, но навешать на него по интерфейсу на каждый модуль? Соответственно коллеги смогут продолжать передавать весь объект DAL там где нужно/хочется.

F>Они говорят, что нужно выделять лишние сущности — интерфейсы со списком методов, и надо следить, чтобы в классах доступа к данным небыло неиспользуемых в модулях методов.


Так ты коллег хочешь нагрузить что ли созданием интерфейсов? Если твоя инициатива, то сам и делай. И затем новый код пиши уже с передачей интерфейса, а не конкретного типа DAL. Старый код поначалу можно вообще не трогать. Затем когда коллеги начнут понимать, что так действительно удобней можно уже и старый код на передачу интерфейсов перевести.
Re[4]: Класс DAL и много функций в нем
От: Nikolay_P_I  
Дата: 01.10.13 12:14
Оценка:
Здравствуйте, ., Вы писали:

.>>>Вообще, странно почему pbf настолько нелюбим. Я вот помню тоже пытался это продвинуть, но все противятся, делая вот таких 400-методных монстров.

N_P>>Ну мне, вот, например, с ходу не понятно — как там с взаимодействием. Типа 3 сущности апдейтятся с оглядкой друг на друга (порядок, ссылки)
.>Не понял. Пример покажи.
.>pbf это распределение классов во пакаджам (неймспейсам), и ничего более. Обычный SRP, но разделение идёт не по красивым словам DAO, DAL, Service, понятным только программистам, а по логике бизнес-области User, Order, Account.

Например, при изменении TableOrder одновременно апдейтится TableOrderToUser (many-to-many) и логируются в TableJournal данные из TableAccount
Re[7]: Класс DAL и много функций в нем
От: Nikolay_P_I  
Дата: 01.10.13 12:22
Оценка:
Здравствуйте, GreenTea, Вы писали:

DAL над ORM ? А почему не просто ORM ? И еще — почему вы считаете нормальным получать из DAL бизнес-логику, унаследованную от объектов ORM ? Я про IEntity ? Я не в смысле флейма, это именно вопрос Как оно на практике ? Работа, рефакторинг и прочее ? А что есть бизнес-логика не ложится на ORM и БД прямо, например, бизнес-объект — это совокупность 2,5 объектов ORM ?
Re[8]: Класс DAL и много функций в нем
От: GreenTea  
Дата: 01.10.13 14:07
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Здравствуйте, GreenTea, Вы писали:


N_P>DAL над ORM ? А почему не просто ORM ?

Не понял этого вопроса.

N_P>И еще — почему вы считаете нормальным получать из DAL бизнес-логику, унаследованную от объектов ORM ? Я про IEntity ? Я не в смысле флейма, это именно вопрос Как оно на практике ? Работа, рефакторинг и прочее ? А что есть бизнес-логика не ложится на ORM и БД прямо, например, бизнес-объект — это совокупность 2,5 объектов ORM ?


Не, у нас интерфейс IEntity наследуют все DTO (в вашей терминологии OMR) — простые обьекты переносчики данных, они без бизнес логики. Но есть так же BusinessObject-ы. Бизнес обьект это обертка над DTO-шкой и содержит логику по манипулции ее содержимым (логика эта может затрагивать несколько DTO, если у них нет своих бизнес обьектов). В бизнес обьекте могут быть другие бизнес обьекты, которым делегируется часть работы. Кстати, бизнес обьекты создаются спрингом, с вживленными зависимостями (бизнес обьектами, dao, инфраструктурыми сервисами). Но есть так же и бизнес сервиса, которые реализуют логику над группой бизнес обьектов, или производят поиск по критериям. Такой сервис, как правило, работает с одним юз кейсом, например "запись пациента на прием".
Re[9]: Класс DAL и много функций в нем
От: GreenTea  
Дата: 01.10.13 14:17
Оценка:
Здравствуйте, GreenTea, Вы писали:

GT>Здравствуйте, Nikolay_P_I, Вы писали:


N_P>>Здравствуйте, GreenTea, Вы писали:


Были кстати у нас раньше (та и сейчас где-то есть) сервиса посвященные одной сущности, выполняющие сложные разлинчые варианты поиска этой сущности. Но стараемся от этого уходить в сторону билдеров критерии. Эти билдеры — обертка над хибернетовской DetachedCriteria и предсотавляющие более высокоуровные методы добавления всяких условий поиска. И потом уже эти высокоуровневые билдеры критерий по многу раз используем в бизнес сервисах. Но как начальный вариант — сервис на сущность, мне кажется подойдет, для автора темы. + более высокоуровные бизнес сервиса. Все равно лучше чем 400 методов в одном сервисе
Re[5]: Класс DAL и много функций в нем
От: . Великобритания  
Дата: 01.10.13 19:06
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Например, при изменении TableOrder одновременно апдейтится TableOrderToUser (many-to-many) и логируются в TableJournal данные из TableAccount

Как я понимаю это будет Service, т.к. бизнес-операция, а не DAO (доступ к бд).
Да и никто не мешает в один DAO-объект (OrderDaoImpl) заинжекитть другой (IJournalDao).
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[9]: Класс DAL и много функций в нем
От: LeonidV Ниоткуда http://vygovskiy.com
Дата: 01.10.13 20:04
Оценка:
Здравствуйте, GreenTea, Вы писали:

GT>Здравствуйте, Nikolay_P_I, Вы писали:


N_P>>Здравствуйте, GreenTea, Вы писали:


N_P>>DAL над ORM ? А почему не просто ORM ?

GT>Не понял этого вопроса.
ORM (Hibernate) это уже реализация DAO. Вопрос в том, зачем нужны отдельные методы. У вас разные БД поддерживаются и native sql?
http://jvmmemory.com — простой способ настройки JVM
Re[10]: Класс DAL и много функций в нем
От: GreenTea  
Дата: 02.10.13 13:33
Оценка:
Здравствуйте, LeonidV, Вы писали:

LV>Здравствуйте, GreenTea, Вы писали:


GT>>Здравствуйте, Nikolay_P_I, Вы писали:


N_P>>>Здравствуйте, GreenTea, Вы писали:


N_P>>>DAL над ORM ? А почему не просто ORM ?

GT>>Не понял этого вопроса.
LV>ORM (Hibernate) это уже реализация DAO. Вопрос в том, зачем нужны отдельные методы. У вас разные БД поддерживаются и native sql?

Извините, все равно не понятно. Какие отдельные методы? Мы используем MySQL, но так же пробовали PostgreSQL (менять код для этого не потребовалось). Нативный sql не используем.. Только DetachedCriteria
Re[11]: Класс DAL и много функций в нем
От: . Великобритания  
Дата: 02.10.13 13:45
Оценка:
Здравствуйте, GreenTea, Вы писали:

N_P>>>>DAL над ORM ? А почему не просто ORM ?

GT>>>Не понял этого вопроса.
LV>>ORM (Hibernate) это уже реализация DAO. Вопрос в том, зачем нужны отдельные методы. У вас разные БД поддерживаются и native sql?

GT>Извините, все равно не понятно. Какие отдельные методы? Мы используем MySQL, но так же пробовали PostgreSQL (менять код для этого не потребовалось). Нативный sql не используем.. Только DetachedCriteria

Я вроде понимаю что он спрашивает, и действительно интересно. Hibernate сам по себе уже предоставляет DAL, вы же поверх его накручиваете ещё один абстрактный слой, который в общем-то ничего не делает, просто зовём методы сессии:
   public <T extends IEntity> void save(T instance) throws EntityConstraintException
   {
      getCurrentSession().save(instance);      
   }

ещё непонятно накой там generics? Ведь тип T нигде не используется. Поэтому можно упростить:
   public void save(IEntity instance) throws EntityConstraintException
   {
      getCurrentSession().save(instance);      
   }

И тут уже становится совсем очевидно, что этот код ничего не делает — надо просто hibernate.Session.save() звать да не мучиться.

Короче, с KISS у вас там проблемы.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[12]: Класс DAL и много функций в нем
От: GreenTea  
Дата: 03.10.13 10:08
Оценка:
Здравствуйте, ., Вы писали:

.>Здравствуйте, GreenTea, Вы писали:


N_P>>>>>DAL над ORM ? А почему не просто ORM ?

GT>>>>Не понял этого вопроса.
LV>>>ORM (Hibernate) это уже реализация DAO. Вопрос в том, зачем нужны отдельные методы. У вас разные БД поддерживаются и native sql?

GT>>Извините, все равно не понятно. Какие отдельные методы? Мы используем MySQL, но так же пробовали PostgreSQL (менять код для этого не потребовалось). Нативный sql не используем.. Только DetachedCriteria

.>Я вроде понимаю что он спрашивает, и действительно интересно. Hibernate сам по себе уже предоставляет DAL, вы же поверх его накручиваете ещё один абстрактный слой, который в общем-то ничего не делает, просто зовём методы сессии

А, ну в чем то вы правы. Так же у нас есть еще QueryDao, который предоставляет методы поиска через getCurrentSession(). Таким образом сервиса и бизнес обьекты, если им нужны только CRUD — инжектят BaseDao, если еще запросы QueryDao. Наверно это дань традиции так делать. + немного меньшая завязанность всего кода на Hibernate. Хотя, код и так прилично завязан из-за использования DetachedCriteria.
Re[14]: Класс DAL и много функций в нем
От: GreenTea  
Дата: 04.10.13 11:53
Оценка:
Здравствуйте, ., Вы писали:

.>Здравствуйте, GreenTea, Вы писали:


GT>>А, ну в чем то вы правы. Так же у нас есть еще QueryDao, который предоставляет методы поиска через getCurrentSession(). Таким образом сервиса и бизнес обьекты, если им нужны только CRUD — инжектят BaseDao, если еще запросы QueryDao. Наверно это дань традиции так делать. + немного меньшая завязанность всего кода на Hibernate. Хотя, код и так прилично завязан из-за использования DetachedCriteria.

.>Кстати, рекомендую взглянуть на querydsl — на порядок лучше DetachedCriteria.

Спасибо, любопытная штука В текущем проекте наврятли, но в новом можно попробовать изспользовать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.