Pull to refresh

Почему не стоит использовать двухуровневую архитектуру при разработке клиент-серверных приложений

Reading time4 min
Views17K
Поблагодарим моего знакомого за то что он рассказал мне о своей новой лабораторной работе, в университете, по дисциплине связанной с базами данных. В противном случае статья просто бы не увидела бы света.

Сутью данной лабораторной работы было написать n-ое количество валидаций, хранимых процедур и триггеров в MS SQL. Все триггеры, валидации и хранимые процедуры очень просты, но это лишь первая лабораторная и дальше будет хуже, будут многоэтажные sql запросы и хранимые процедуры очень большого объёма.

Как мне кажется тратить время на изучение подобных вещей в 2018 году очень не практично, а именно то что никто не использует просто голую базу данных и сразу вывод на клиент. Все приложения имеют бизнес логику и подвергаются постоянному масштабированию и изменению. И завязывать всё на базе данных не правильно так как может возникнуть ряд проблем которые невозможно решить используя лишь СУБД в качестве серверной стороны.

Примерами таких проблем могут быть:

  • Возникновение необходимости использования другой базы данных
  • Необходимость вывода данных в нескольких видах для разных клиентских сторон(JSON, HTML, XML и др)
  • Добавление и изменение таблиц, колонок или изменения их имён, что повлечёт за собой изменение всего связанного с каждой таблицей или колонкой
  • Необходимость получения данных так же из других баз данных установленных на сервер, либо вообще получение данных из других сервисов

Рассмотрим типичный пример того что нам нужно отправить письмо по email


Как это выглядит если отправлять сообщение через MS SQL

DECLARE @tableHTML  NVARCHAR(MAX) ;  

SET @tableHTML =  
    N'<H1>Work Order Report</H1>' +  
    N'<table border="1">' +  
    N'<tr><th>Work Order ID</th><th>Product ID</th>' +  
    N'<th>Name</th><th>Order Qty</th><th>Due Date</th>' +  
    N'<th>Expected Revenue</th></tr>' +  
    CAST ( ( SELECT td = wo.WorkOrderID,       '',  
                    td = p.ProductID, '',  
                    td = p.Name, '',  
                    td = wo.OrderQty, '',  
                    td = wo.DueDate, '',  
                    td = (p.ListPrice - p.StandardCost) * wo.OrderQty  
              FROM AdventureWorks.Production.WorkOrder as wo  
              JOIN AdventureWorks.Production.Product AS p  
              ON wo.ProductID = p.ProductID  
              WHERE DueDate > '2004-04-30'  
                AND DATEDIFF(dd, '2004-04-30', DueDate) < 2   
              ORDER BY DueDate ASC,  
                       (p.ListPrice - p.StandardCost) * wo.OrderQty DESC  
              FOR XML PATH('tr'), TYPE   
    ) AS NVARCHAR(MAX) ) +  
    N'</table>' ;  

EXEC msdb.dbo.sp_send_dbmail @recipients='yourfriend@Adventure-Works.com',  
    @subject = 'Work Order List',  
    @body = @tableHTML,  
    @body_format = 'HTML' ;  


Прекрасный код, согласитесь?

Редактирование и изменение данного кода будет доставлять нам анальные боли неудобства. А это лишь простая табличка, в которой нет стилей и ничего сложного, просто текст. А теперь представим что мы в реальном мире и нам надо отправлять нормальные, красивые сообщения, с картинками, вложениями и стилями. Перейдя по ссылке, вы собственными глазами увидите какими могут быть большими html шаблоны писем. И редактирование чего либо подобного будет тратить тонну вашего времени и сил.

А в случае если бы вы использовали трехуровневую архитектуру, вам бы не пришлось использовать столь изощрённые методы оформления писем. Был бы использован какой либо фреймворк с шаблонизатором, и дело с концом.

Усложненный функционал


Существует множество ситуаций когда нам необходимо создать в приложении возможности которые база данных сама по себе просто не сможет реализовать, так как в ней не предусмотрено подобное. К примеру в вашем приложении заказчик попросил реализовать чаты с отображением новых сообщений в режиме реального времени. Подумав совсем чуть чуть вы сразу скажете что необходимо использовать websockets, но придя к такому решению вы встанете в тупик, так как база данных просто не поддерживает ничего подобного, и вам придётся расширять ваше приложение до трехуровневой архитектуры и обеспечивать работу websockets на новом уровне, разграничивающим базу данных и клиентскую часть.

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

Но поспешу вас поправить что серверная часть реализованная на более высокоуровневых системах чем просто база данных упрощает вам жизнь и скорость разработки, позволяет более гибко выстраивать настройки под ту или иную ситуацию. Если где-то нужно воспользоваться сторонним сервисом, вы используете соответствующую библиотеку предоставленную этим самым сервисом.

Вам не нужно изобретать вечно всевозможные велосипеды переписывая логику библиотек в SQL. Если вы будете использовать клиент-сервер-база данных, то перед вами раскроется огромное море возможностей, всё станет максимально кастомизируемым и простым.

  • Поменялось название поля в таблице — вам нужно будет просто описать в модели, что данное свойство теперь ссылается на другое поле, и вам не нужно будет менять логику приложения и все места где используется данное поле.
  • Нужно использовать данные из другой СУБД — просто делаете запрос в другую БД и спокойно работаете с этими данными.
  • Нужно обратиться к стороннему сервису и получить данные от туда перед тем как делать к примеру INSERT — не беда, это очень просто сделать в любом фреймворке.
  • Нужна асинхронность при выполнении запросов — берём тот же NodeJS с его расхваленной ансинхронностью и дело в шляпе.
  • Надо поменять базу данных — вам не придётся переписывать все хранимые процедуры для новой БД, вы просто смените драйвер базы данных и забудете об этом.

И таких примеров тысячи, если не десятки тысяч.

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

Эта статья призывает вас, развиваться в правильном направлении и изучать более продвинутые вещи, ведь с каждым годом функционал приложений становятся всё более и более сложным и продвинутым. Сейчас современные фреймворки все SQL запросы напишут за вас. И не пропустят точку с запятой. От вас же требуется грамотно использовать все те инструменты которые предоставляет фреймворк, а не придумывать велосипеды.

Так же хотелось бы чтобы преподаватели ВУЗов смотрели на реалии в которые попадает студент на работе, и давали реальные задачи, а не задачи валидации мобильного телефона на уровне БД.

UPD 13.02.2018
Поблагодарим speshuric за прекрасно аргументированный комментарий к данной статье
Tags:
Hubs:
+10
Comments144

Articles