ある種のMVCフレームワークを使用していないと仮定すると...まだ...
私はこの種の状況を処理するためにいくつかの異なる方法を使用しました。
CFC間で何が異なり、同じように見えるかに応じて、次のことができます。
1)継承を使用する
コードの大部分が同じであるが、各プロジェクトにわずかな違いがある場合は、共通コードをリファクタリングして、プロジェクトごとに拡張するベースCFCにします。これにより、ほとんどの機能に対して単一のテストセットを維持し、プロジェクトごとに逸脱するコードに対してさらにテストを追加することができます。
これの欠点は、基本クラスを変更するときに上位互換性を維持するために、ある程度の計画と規律が必要になることです。本質的に、あなたはAPIを定義しているので、それをうまく行うのは簡単な作業ではありません。
2)ミックスインを使用する
毎回複製しているように見えるものが機能/ロジックである場合は、そのロジックをコードのチャンクにリファクタリングしてみてください。これを必要とするcfcにcfincludeします。ベンのミックスインの実験とショーンのミックスインに関するコメントを参照してください。
悲しいことに、Rubyのモジュールとは異なり、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>