Читаемость, обслуживание и соблюдение проверенных объектно-ориентированных парадигм были бы наиболее важными аспектами построения приложения ColdFusion с использованием истинного уровня обслуживания CFC / объектов, а не множества cfinclude, которое в лучшем случае любительский, а в худшем может вызвать кошмары по сбору мусора.
читаемость
Допустим, у вас есть файл cfinclude _queries.cfm, который включает все вызовы для вашего приложения. Затем в верхней части страницы вашего сотрудника, непосредственно перед выводом всех сотрудников, вы делаете следующее:
<cfinclude template="_queries.cfm" />
<cfoutput query="employeeQry">
Откуда служащий? Это один из запросов в этом шаблоне? Что оно делает? Нужно ли включать этот шаблон, когда мне нужны только сотрудники? Что если в нем есть все запросы на сайте ... нужно ли включать их все каждый раз ?
Почему бы не что-то более читаемое, например:
<cfset employeeQry = request.model.queries.getEmployees() />
<cfoutput query="employeeQry">
Ааа, вот и мы. С первого взгляда, ничего не зная о нюансах вашей системы, я сразу могу определить:
- Откуда произошла переменная employeeQry
- Из какого кэшированного CFC я звоню по запросу с
- То, что я вызываю один и только один запрос, а не массовый, включая массив запросов, ни один из которых не требуется для страницы.
Инкапсуляция бизнес-логики в сервисном слое (CFC) повышает читабельность вашего кода, что будет иметь значение, когда вы перейдете к следующей теме.
Техническое обслуживание
Вы получаете новое приложение CF, за которое отвечаете, и открываете страницу сотрудника, чтобы найти шаблон <cfinclude template="_queries.cfm">
выше.
Внутри этого первоначальный разработчик оставляет комментарий, в котором говорится что-то вроде: «Давайте не будем выполнять все запросы, давайте просто запустим определенный запрос на основе параметра», и тогда вы увидите что-то вроде этого:
<cfswitch case="#param#">
<cfcase value="employee">
<cfinclude template="_employeeQry.cfm">
</cfcase>
<cfcase value="employees">
<cfinclude template="_employeesQry.cfm">
</cfcase>
<cfcase value="employeesByDept">
<cfinclude template="_employeesByDept.cfm">
</cfcase>
</cfswitch>
... так что вы посмотрите на это и подумаете, ну ... мне нужно изменить запрос employeeByDept, чтобы вы взломали этот шаблон и обнаружили:
<!--- employees by department --->
<cfif args.order_by is "ASC">
<cfinclude template="_employeeQryByDeptOnASCOrder.cfm">
<cfelse>
<cfinclude template="_employeeQryByDeptOnDESCOrder.cfm">
</cfif>
... и к этому моменту вы хотите выстрелить себе в лицо.
Это преувеличенный пример, но он слишком знаком в мире ColdFusion; менталитет любителей при разработке приложений уровня предприятия. Этот кошмар "включай в себя включай и включай" - это то, с чем разработчики CF сталкиваются чаще, чем вы думаете.
Решение простое!
Один CFC, который инкапсулирует бизнес-логику создания запросов для ваших сотрудников.
<cfcomponent>
<cffunction name="getEmployees" returntype="query">
<cfquery name="tmp">
select employeeID, name, age
from employees
</cfquery>
<cfreturn tmp />
</cffunction>
<cffunction name="getEmployeesByDept" returntype="query">
<cfargument name="deptID">
<cfargument name="order_by" required="false" default="ASC">
<cfquery name="tmp">
select employeeID, name, age
from employees e
inner join empToDept etd on (e.employeeID = etd.employeeID)
where etd.deptID = #arguments.deptID#
order by name #iif(arguments.order_by is 'asc',de('asc'),de('desc'))#
</cfquery>
<cfreturn tmp />
</cffunction>
</cfcomponent>
Теперь у вас есть единая точка отсчета для всей информации, которую вы хотите получить при запросе к базе данных вашего сотрудника, и вы можете параметризовать / настроить ее все сразу, без необходимости копаться в горах включений внутри включений .. . который громоздок, и его трудно держать прямо (даже при адекватном контроле источника).
Он элегантно позволяет написать одну строку:
<cfset empQry = request.model.queries.getEmployees() />
или
<cfset empQry = request.model.queries.getEmployeesByDept(14,'DESC') />
и упрощает работу с кодом .
Соблюдение проверенных объектно-ориентированных парадигм
Ваш босс объявляет, что рок-звезда Java присоединилась к команде. Вы очень хотите и взволнованы, чтобы сесть с ним, так как вы в первую очередь застряли в МВ в течение последних нескольких лет, и вы хотите, чтобы показать ему некоторые свои вещи, и, возможно, учиться у него.
"Итак, как приложение получает доступ к данным?" он спрашивает тебя.
«О, у нас есть ряд запросов, которые мы вызываем на разных страницах, и на основе параметров мы будем получать информацию разного типа».
«Хорошо», - говорит он, - «Итак ... у вас есть сервисный уровень для модели объектов данных, это здорово».
Не совсем , как вы думаете. Это просто включает в себя включает в себя ... но он продолжает идти,
"Это отлично, потому что одна из новых вещей, которые мы добавим, это объект Contractor, который в основном является подмножеством Employee, у него будет несколько разных функциональных возможностей, но в целом он будет действовать очень похоже на Сотрудник. Мы просто перейдем к подклассу Сотрудник и переопределим некоторые из этих запросов ... "
... и теперь вы потерялись. Потому что нет подкласса включения. В включении нет наследования. Включение не знает ни домена, ни бизнес-объекта, ни того, как оно должно взаимодействовать с другими объектами.
Cfinclude - это удобство для повторного использования общих элементов, таких как верхний или нижний колонтитул. Они не являются механизмом для отражения сложностей бизнес-объекта.
Когда вы проектируете / конструируете / внедряете CFC как объекты, отражающие сущности вашего приложения, вы говорите на общем языке: OO . Это означает, что он не предлагает вам возможность проектировать систему на основе проверенной структуры, он распространяет этот язык «OO-ness» на программистов в других технологиях. Java-программисты, C ++ / C # -программисты и т. Д. Любой, кто обладает достаточными знаниями в области объектно-ориентированной разработки, автоматически говорит на вашем языке и сможет работать с вами и вашей системой.
Обратите внимание на это последнее замечание: не каждое приложение должно быть объектно-ориентированным. Если ваш начальник хочет, чтобы вы быстро собрали XML-дамп таблицы сотрудников и разместили ее на веб-сайте - да, вы, вероятно, можете отказаться от целой модели для этого. Но если вы создаете приложение с нуля, и оно будет содержать сотрудников, пользователей, отделы, запросы, роли, правила, заявки ... короче: сущности в домене, будет время отложить в сторону в качестве основного инструмента для повторного использования кода.
Да, и PS: Эта небольшая заметка о сборке мусора, которую я оставил наверху, - не шутка. Я видел неправильно созданные приложения CF, поэтому сам Application.cfc вызывает cfinclude , а после подключения CF к JVM , которая может отслеживать создание / уничтожение объектов в GC * 1100 в реальном времени. * Я видел, как память выглядит как монитор ЭКГ.
Не хорошо.