9

そのため、私が働いている会社は、私たちのサイトに関しては、非常に組織化されていないアプローチをとっています. すべてのスクリプトは手続き型で、cfincludes がスローされます。私はこれを、他の Web 開発者が何かを行うために使用する内部 API に編成したいと考えていました (変更を行うと、変更を更新する必要がある他のすべてのインスタンスを見つけて見つける必要があるため)。

私はついに実例を手に入れ、上司に見せました。それは私が通常の方法であると仮定したことに従います(私のグーグルから)。サービス層 > ゲートウェイ & DAO > Beans。オブジェクトの作成を支援するいくつかのファクトリがあります。それはうまく機能し、私が達成したかったことを正確に実行します. 彼はそれに感銘を受け、コードを整理してよりよく整理する必要があることに同意しますが、同じことを達成するために cfincludes の大きなリストに対するオブジェクト指向 API 呼び出しのこの方法を使用する利点を理解していません。本質的に、彼が cfincludes を説明した方法から、それはメソッド呼び出しと同じように機能します。

彼は、私のアプローチとこの cfinclude の利点について尋ねられました。私の人生では、同様のデータをすべて 1 つのオブジェクト内にグループ化する以外に明らかな利点を見つけることができません。他に何かありますか、それとも cfinclude アプローチを使用する方が有利でしょうか?

4

3 に答える 3

25

可読性、メンテナンス、実証済みのオブジェクト指向パラダイムへの準拠は、多くの cfincludes ではなく、CFC/オブジェクトの真のサービス レイヤーを使用して ColdFusion アプリケーションを構築する上で最も重要な側面です。最悪のコレクションの悪夢。

可読性

アプリケーションのすべての呼び出しを含む _queries.cfm という cfinclude があるとします。次に、従業員ページの上部で、すべての従業員を出力する直前に、次のようにします。

<cfinclude template="_queries.cfm" />

<cfoutput query="employeeQry">

employeeQry はどこから来たのですか? そのテンプレートのクエリの 1 つですか? それは何をするためのものか?従業員だけが必要な場合、そのテンプレートを含める必要がありますか? サイト内のすべてのクエリがある場合はどうなりますか...それらすべてを毎回含める必要がありますか?

次のように、もう少し読みやすいものにしないでください。

<cfset employeeQry = request.model.queries.getEmployees() />

<cfoutput query="employeeQry">

ああ、それでは行きます。システムのニュアンスについて何も知らなくても、一目で次のことがわかります。

  • employeeQry 変数の由来
  • どのキャッシュ CFC からクエリを呼び出しているか
  • 私が呼び出しているのは 1 つだけのクエリであり、クエリの配列を含む大量のクエリではなく、ページに必要なクエリはありません。

ビジネス ロジックをサービス レイヤー (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>

...だから、これを見て考えてください... employeesByDept クエリを変更する必要があるので、そのテンプレートを開いて見つけます:

<!--- 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>

これで、従業員データベースにクエリを実行するときに生成するすべての情報を参照する単一のポイントが得られ、すべてを一度にパラメーター化/調整できるようになりました。面倒で、まっすぐに保つのが難しい (適切なソース管理があっても)。

1行をエレガントに書くことができます:

<cfset empQry = request.model.queries.getEmployees() />

また

<cfset empQry = request.model.queries.getEmployeesByDept(14,'DESC') />

これにより、コードの保守がはるかに容易になります。

実証済みのオブジェクト指向パラダイムへの準拠

あなたの上司は、Java のロックスターがチームに加わったことを発表しました。あなたはここ数年、主に CF で立ち往生していたので、彼と一緒に座ることに非常に熱心で興奮しており、彼にあなたの作品のいくつかを見せて、おそらく彼からも学ぶ機会を望んでいます.

「では、アプリケーションはどのようにしてデータにアクセスするのでしょうか?」彼はあなたに尋ねます。

「ああ、さまざまなページで呼び出す一連のクエリがあり、パラメーターに基づいて、さまざまな種類の情報を取得します。」

「いいですね」と彼は言います。

そうではない、とあなたは思います。インクルード内にインクルードするだけです...しかし、彼は続けます、

「これは素晴らしいことです。追加する新しいものの 1 つは、基本的には Employee のサブセットである Contractor オブジェクトです。彼はいくつかの異なる機能を持ちますが、全体的には Employee と非常によく似た動作をします。先に進んで Employee をサブクラス化し、それらのクエリのいくつかをオーバーライドします...」

...そして今、あなたは迷っています。インクルードのサブクラス化がないためです。インクルードには継承はありません。インクルードには、ドメインやビジネス オブジェクト、または他のオブジェクトとの対話方法に関する情報がありません。

cfinclude は、ヘッダーやフッターなどの共通要素を再利用するのに便利です。ビジネス オブジェクトの複雑さを反映するメカニズムではありません。

アプリケーションのエンティティを反映するオブジェクトとして CFC を設計/構築/実装するときは、共通言語である OO を話していることになります。これは、実証済みの構造に基づいてシステムを設計する能力を提供するのではなく、その「オブジェクト指向性」の言語を他のテクノロジーのプログラマーに拡張することを意味します。Java プログラマー、C++/C# プログラマーなど、オブジェクト指向開発についてある程度の知識を持っている人なら誰でも、自動的にあなたの言語を話し、あなたとあなたのシステムを操作できるようになります。

最後に、すべてのアプリケーションがオブジェクト指向である必要はありません。上司が従業員テーブルの簡単な XML ダンプを作成し、それを Web サイトに平手打ちするように求めている場合、おそらく oo モデル全体を放棄することができます。しかし、アプリケーションをゼロから構築していて、従業員、ユーザー、部門、クエリ、ロール、ルール、チケットなどを特徴とする場合、つまりドメイン内のエンティティを扱う場合は、cfincludes を脇に置く時が来ます。コードを再利用するための主要なツールとして。

追伸: ガベージ コレクションについて冒頭に残したちょっとしたメモは、冗談ではありません。Application.cfc自体が cfincludes を呼び出すように、CF アプリケーションが正しくビルドされていないのを見たことがあります。また、GC 内のオブジェクトのリアルタイムの作成/破棄を監視できる JVMに CF を接続した後、メモリが EKG モニターのように見えるのを見てきました。 .

良くない。

于 2012-01-20T02:21:46.933 に答える
1

Shawn の回答は、要点を確実にカバーしています。これらすべてを上司が理解できる重要なポイントに要約すると.. CFC アプローチは、メンテナンスの面で彼に多くのお金を節約し、開発者の仕事が非常に簡単になるため、開発者をより幸せに保ちます。熟練した/やる気のある開発者の定着率は、標準としてスパゲッティ コードにとどまる場合よりもはるかに高くなります。

于 2012-01-20T02:49:45.033 に答える
1

私はショーンの回答に完全に同意します...そして、コードをさらに高いレベルに引き上げたい場合は、フレームワークを使用してください! そうすれば、誰もが独自の基準を順守するため、あなたや他の開発者の時間を大幅に節約できます。

私の個人的な好みは Coldbox ですが、一般的な MVC/OO フレームワーク (Coldbox、Mach-II、Model-Glue、FW/1) のどれでも構いません。CFWheels についても良いことを聞いたことがありますが、使用したことはありません。

于 2012-01-20T16:59:36.213 に答える