gpt4 book ai didi

database-design - 我如何创建一个架构,允许许多客户使用一个网站,每个网站都有不同的功能?

转载 作者:行者123 更新时间:2023-12-04 07:01:47 25 4
gpt4 key购买 nike

我继承了一个应用程序的怪物。这是一个被许多客户用来处理订单的网站。它很旧,过时,需要一些认真的更新。最难的部分是它最初是为一种类型的客户端创建的,然后,随着新客户端的添加,代码被数百条 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>

以上是我在整个网站上处理的内容的一个很好的 CLEAN 版本。

因此,我正在尝试重构网站以允许更轻松的特定于客户端的配置 - 基本上是为每个客户端提供或隐藏功能。

我从我认为是一个简单、干净的解决方案开始,但我担心它可能会变得难以维护。

基本上,我将给每个客户端一个从 web-root 中存储他们的文件的目录——可能是网站上使用的文档等。这个目录类似于 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 实例将具有属性 cartLink 的“cart1.cfm”值。 .

现在我可以简单地查找该值并使用它来填充 anchor 标记:
<a href="#REQUEST.Client.getCartLink()#">Shopping Cart</a>

我的目标是保持代码干净,避免在需要编辑的地方出现数百条 IF 语句。

但是,当我现在看到这个设计时,我意识到这可能会变得更像是一个维护噩梦。该网站目前有大约 30-40 个客户。所以,现在,我需要维护 30-40 个 xml 文件,每个配置属性都有任意数量的节点。此外,每当添加新功能时,我都必须使用新属性的新 getter/setter 方法更新客户端类。

我不想让事情变得更糟。任何想法将不胜感激。

最佳答案

首先,我不知道ColdFusion,所以我不能给你代码。

但是,您所描述的问题通常被称为“ Multi-Tenancy ”架构。应用程序通过您描述的过程,回顾性地破解这些功能并不罕见;很少有好的结局!不过,在谷歌上搜索这个词可能会带来一些乐趣。

根据我的经验,你必须选择你希望复杂性存在的地方——目前,它存在于代码中,这是它存在的最糟糕的地方。复杂的代码更难维护,包含更多的错误,更难改变/扩展,让开发人员生气。

管理作为数据/配置的复杂性是一种更好的方法 - 它显着降低了代码库的复杂性,并且通常更易于管理。你已经在这条路上迈出了第一步,但我会稍微改进一下。

首先介绍一下“convention over configuration”的概念。因此,在您使用的购物车示例中,我会考虑使用客户端 ID 命名解决方案中的所有变量元素。所以不是“cart3.cfm”,而是“cartMike.cfm”。这应该会显着减少 XML 修改量。

其次,您可能想介绍默认值的概念。在大多数情况下,80% 的设置在客户端之间是通用的,只有 20% 需要特定于客户端的设置。不必管理所有这些设置,而是引入默认值;如果没有特定于客户端的默认值,请使用默认文件中的默认值。

第三,您可能想介绍客户类型——黄金/白银/青铜、免费/中小企业/企业等等。这将需要为每种客户端类型创建默认配置,但可能会增加默认配置文件的命中率。

最后,您需要考虑应用程序生命周期——新客户端的配置过程应该是怎样的?它主要是一项技术任务吗?在那种情况下,我会继续使用 XML 文件,因为它们可以在版本控制中轻松管理。如果它更像是一项“业务”任务,您希望将其包装成一个对用户更友好的流程,但随后您需要能够验证配置。例如,如果“cart”的配置设置为“/Mike/cart.cfm”,则需要确保该文件确实存在。您可能还需要版本控制和从开发人员到测试再到生产环境的机制。

关于database-design - 我如何创建一个架构,允许许多客户使用一个网站,每个网站都有不同的功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12975039/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com