суббота, 25 апреля 2009 г.

Каким должен быть правильный BL и DAL?

Не так давно нашел на ряд постов, которые сформировали у меня определенное видение решения классической задачки по передачи данных через ряд уровней - Data access layer -> Business layer -> Presentation layer.

Первым был пост Repository is the new Singleton от Oren Eini aka Ayende Rahien.

В этом посте Ayende говорит что ему не очень нравится непосредственно сам паттерн Repository, более того от отмечает что в большистве случаев этот паттерн еще и не совсем правильно используют.

Дествительно, с появлением LINQ и NHibernate/LinqToSql/ADO.NET Entity Framework подход к получению данных довольно сильно изменился.

И я придерживаюсь того мнения что нужно постепенно уходить от практики написания огромного количества методов вида GetCustomer(id), GetCustomerWithAddresses(id) и начинать использовать механизм запросов даже на верхних уровнях.

Если этого не делать, то мы очень быстро прийдем к достаточно некрасивому Data access layer'у - Kobe – Data Access done wrong.

В своем следующем посте - "The DAL should go all the way to UI" Ayende развивает идею и очень наглядно показывает какую цену приходится платить за неудачную реализацию Data access layer'а.

Действительно, если делать sorting и paging по-честному, через Business Layer, то приходится вручную писать кучу методов, которые похожи друг на друга как близнецы браться, что как раз нарушает принцип DRY (Don't Repeat Yourself).

Подход Ayende мне показался очень уместным, однако меня смутило отсутствие ограничений по извлечению даных на UI-уровне. Возможно, я параноик, но я бы хотел все вызовы по извлечению данных прокидывать через Business Layer. Как минимум это даст возможность прикрутить Caching/Logging/Security на query-методы.

В ответ на пост Ayende, другой блоггер Justin Etheredge сделал пост в котором привел достаточно удачную на мой взгляд реализацию paging'а и сортировки.

В результате, однозначно для себя я решил несколько моментов:
- Классы IRepository должны быть максимально небольшими и простыми
- При получении данных необходимо иметь возможность строить цепочку из filtering, paging, sorting, поскольку это дает намного больше гибкости
- Presentation Layer не должен работать с чрезмерно богатым интерфейсом, этот уровень должен использовать только то, что предоставляет ему Business Layer
- Все большие либо нетривиальные запросы стоит инкапсулировать в отдельные Query-объекты

Интересно, насколько удобно будет использовать это решение когда у нас пользовательский интерфейс написан на Silverlight? Ведь в таких случаях мы Business Layer не видим напрямую в своем Silverlight-приложении, а работаем с удаленными WCF-сервисами.

Комментариев нет: