Предполагается, что вы не используете какую-то инфраструктуру MVC ... пока ...
Я использовал несколько различных методов для обработки подобных ситуаций.
В зависимости от того, что кажется различным и одинаковым между ХФУ, вы можете:
1) использовать наследование
Если подавляющее большинство вашего кода одинаковое, но у каждого проекта есть только несколько отличий, то преобразовайте общий код в базовый CFC, который вы расширяете для каждого проекта. Это позволяет вам поддерживать единый набор тестов для большинства функций, а затем просто добавлять дополнительные тесты для кода, который отличается для каждого проекта.
Недостатком этого является то, что требуется некоторое планирование и дисциплина для обеспечения прямой совместимости при изменении базовых классов. По сути, вы определяете API, и делать это хорошо - непростая задача.
2) использовать дополнения
Если то, что вы, кажется, дублируете каждый раз, является функциональностью / логикой, то попробуйте преобразовать эту логику в куски кода, которые вы включаете в любой код, который требует этого. См. эксперименты Бена с миксинами и комментарии Шона о миксинах .
К сожалению, механизмы для этого в CF слабы, в отличие от модулей Руби.
Если ваши потребности, как вы описываете в своем комментарии, «что-то вроде, логика / бизнес-правила одинаковы, но ввод и данные не совпадают», я бы посоветовал взглянуть на Rails или Django для вдохновение.
В моей ситуации я закончил разработку инфраструктуры, которая позволяла мне при определении модели расширять базовый класс модели и просто заполнять его набором тегов cfproperty с пользовательскими свойствами, которые определяли мою модель и использовались класс базовой модели и набор сервисов, которые обрабатывают большую часть бизнес-логики. Это работало в 95% случаев, и в любой ситуации, когда мне нужно было отклониться от логики фреймворка, я бы либо добавил дополнительные функции в моей модели cfc, либо даже переопределил бы функцию базовой модели.
Мои модели выглядели так:
<cfcomponent output="false" persistentLayer="GAE" persistentClass="asana" extends="com.bespokelogic.framework.BaseModel">
<cfproperty name="id" type="string" persistentDatatype="string" settable="true" gettable="true" required="true">
<cfproperty name="deckSet" type="string" persistentDatatype="string" settable="true" gettable="true" default="basic">
<cfproperty name="englishName" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="traditionalName" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="pronunciation" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="pronunciationNotes" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="description" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="type" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="anatomicalFocus" type="array" persistentDatatype="array" settable="true" gettable="true" default="#arrayNew(1)#">
<cfproperty name="therapeuticFocus" type="array" persistentDatatype="array" settable="true" gettable="true" default="#arrayNew(1)#">
<cfproperty name="benefits" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="variations" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="contraindications" type="array" persistentDatatype="array" settable="true" gettable="true" default="#arrayNew(1)#">
<cfproperty name="skill" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="instructions" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="skill" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="prelimAsana" type="asana" persistentDatatype="Key[]" settable="true" gettable="true" default="#arrayNew(1)#">
<cfproperty name="followupAsana" type="asana" persistentDatatype="Key[]" settable="true" gettable="true" default="#arrayNew(1)#">
<cfproperty name="thumbnailImage" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="primaryImage" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="images" type="array" persistentDatatype="array" settable="true" gettable="true" default="#arrayNew(1)#">
<cfproperty name="primaryVideo" type="string" persistentDatatype="string" settable="true" gettable="true">
<cfproperty name="videos" type="array" persistentDatatype="array" settable="true" gettable="true" default="#arrayNew(1)#">
</cfcomponent>