アプリケーションのモンスターを継承しました。多くのお客様にご利用いただいている注文処理サイトです。古くて時代遅れで、深刻な更新が必要です。最も難しいのは、最初は 1 種類のクライアントを念頭に置いて作成されたものであり、その後、新しいクライアントが追加されると、基本的にクライアントごとに機能をオンまたはオフにする何百もの IF ステートメントでコードが荒廃したことです。次のようなものを想像してください (ColdFusion で記述):
<cfif clientId EQ "MIKE">
<a href="cart1.cfm">Shopping Cart</a>
<cfelseif clientId EQ "JOE">
<a href="cart2.cfm">Shopping Cart</a>
<cfelseif clientId EQ "BILL"
OR clientId EQ "JILL"
OR clientId EQ "RAY">
<a href="cart3.cfm">Shopping Cart</a>
<cfelse>
<a href="cart.cfm">Shopping Cart</a>
</cfif>
上記は、私がウェブサイト全体で扱っているもののきれいなバージョンです。
そのため、クライアント固有の構成を簡単にできるように Web サイトをリファクタリングしようとしています。基本的には、クライアントごとに機能を提供または非表示にします。
私はシンプルでクリーンな解決策だと思っていたものから始めましたが、維持するのが面倒になるのではないかと心配しています。
基本的に、私は各クライアントに、ファイルが保存されている Web ルートから離れたディレクトリを提供します。おそらく、Web サイトで使用されるドキュメントなどです。このディレクトリは、C:\clients\MIKE\
. このディレクトリに、xml ファイルを保存します。これを config.xml と呼びましょう。最初に作成した config.xml ファイルの内容は次のとおりです。
<?xml version="1.0" encoding="UTF-8"?>
<root>
<cart>
<url>cart1.cfm</url>
</cart>
</root>
そのため、すべてのページ リクエストに対して、xml を探します。存在する場合は、各値をClient
クラス インスタンスのプロパティにコピーします。
<cfcomponent
hint="Represents configurable per-Client settings stored in a local Xml file">
<cfscript>
VARIABLES.CartLink = "";
</cfscript>
<cffunction name="init" return="Client" output="false">
<cfargument name="clientId" type="String" required="true" hint="i.e. 'MIKE'"/>
<cfscript>
var _clientXml = XmlNew();
THIS = setClientId(ARGUMENTS.clientId);
_clientXml = read();
if ( StructKeyExists(_clientXml.XmlRoot, "cart")
&& StructKeyExists(_clientXml.XmlRoot["cart"], "url")
)
setCartLink(_clientXml.XmlRoot["cart"]["url"].XmlText);
return THIS;
</cfscript>
</cffunction>
<cffunction name="getCartLink" returntype="String" output="false">
<cfreturn VARIABLES.CartLink />
</cffunction>
<cffunction name="setCartLink" returntype="Void" output="false">
<cfargument name="cartLink" type="String" required="true" />
<cfset VARIABLES.CartLink = Trim(ARGUMENTS.cartLink) />
</cffunction>
<cfscript>
function getXmlFilePath() {
return APPLICATION.ClientFilePath
& "\" & getClientId() & "\config.xml";
}
</cfscript>
<cffunction name="read" access="public" output="false" returntype="xml">
<cfscript>
var _clientXml = XmlNew();
var _fileContents = "";
_clientXml.XmlRoot = XmlElemNew(_clientXml, "root");
if (FileExists(getXmlFilePath()))
_fileContents = FileRead(getXmlFilePath());
if (IsXml(_fileContents))
_clientXml = XmlParse(_fileContents);
return _clientXml;
</cfscript>
</cffunction>
</cfcomponent>
上記のサンプル xml を使用すると、ユーザーが「MIKE」クライアントでログインしている場合、REQUEST スコープの Client インスタンスのプロパティの値は「cart1.cfm」になりますcartLink
。
これで、単純にその値を探して、それを使用してアンカー タグを設定できます。
<a href="#REQUEST.Client.getCartLink()#">Shopping Cart</a>
私の目標は、コードをきれいに保ち、編集が必要な数百の IF ステートメントを回避することです。
しかし、今このデザインを見ると、これがさらにメンテナンスの悪夢になる可能性があることに気付きました。Web サイトには現在、約 30 ~ 40 のクライアントがあります。したがって、現時点では、30 ~ 40 個の xml ファイルを維持する必要があり、構成プロパティごとに任意の数のノードが必要です。さらに、新しい機能が追加されるたびに、新しいプロパティの新しいゲッター/セッター メソッドでクライアント クラスを更新する必要があります。
これを悪化させたくありません。どんな考えでも大歓迎です。