如何管理跨多个站点共享的 CFC(子系统)?

发布于 2024-11-01 16:07:02 字数 242 浏览 6 评论 0原文

你怎么能处理这样的事情呢?我尽最大努力将子系统设计为可重用,但只有某些站点特有的东西必须进行自定义(例如 Account 实体中的字段,或 orm 注释中的 cfc="" )。

我想过使用 SVN 并分支定制,但我们发现它非常麻烦,因为提交人员每次都必须决定属于卡车或分支的增强/错误修复,一旦错过某些内容,就不容易撤消。

那么...处理这种情况的最佳方法是什么?只需将代码集克隆到新的源代码控制中,然后修复两个/所有源代码控制上的错误?

How can you manage something like that? I tried my best to design the subsystem to be reusable, but there are just certain things that are unique to the site that have to be customized (e.g. fields in Account entity, or cfc="" in orm annotation).

I thought of using SVN and branch out the customization, but we found it very cumbersome quick as the commit person has to decide an enhancement / bug fix belongs to the Truck or Branch every time and once something is missed, is not easy to undo.

So... What's the best way to handle this situation? Just clone the set of code into a new source control, and fix bugs on both/all source controls?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吃兔兔 2024-11-08 16:07:02

假设您没有使用某种 MVC 框架...但是...

我使用了几种不同的方法来处理此类情况。

根据 CFC 之间看似不同和相同的内容,您可以:

1) 使用继承

如果绝大多数代码是相同的,但每个项目只有一些差异,则将公共代码重构为基本 CFC,您为每个项目进行扩展。这允许您为大多数功能维护一组测试,然后只需为每个项目不同的代码添加进一步的测试。

这样做的缺点是,在修改基类时需要一些规划和规则来保持向前兼容性。从本质上讲,您正在定义一个 API,而做好这件事并不是一件容易的事。

2) 使用 mix-ins

如果您似乎每次重复的是功能/逻辑,那么请尝试将该逻辑重构为代码块,然后将其包含到任何需要它的 cfc 中。请参阅 Ben 的 mixins 实验Sean 对 mixins 的评论

遗憾的是,与 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>

Assuming you're not using some sort of MVC framework... yet...

I've used a couple of different methods for handling these sorts of situations.

Depending on what seems to be different and the same between CFC's, you can:

1) use inheritance

If the vast majority of your code is the same, but each project has just a few differences, then refactor the common code into a base CFC which you extend for each project. This allows you to maintain a single set of tests for most of the functionality, then just add further tests for code that deviates for each project.

The drawback to this is that it requires some planning and discipline to maintain forward compatibility when modifying the base classes. You are, in essence, defining an API, and doing that well is not an easy task.

2) use mix-ins

If what you seem to be duplicating each time is functionality/logic, then try refactoring that logic into chunks of code which you cfinclude into any cfc's that require it. See Ben's experiments with mixins and Sean's comments on mixins.

Sadly, the mechanisms for doing this well in CF are weak, unlike Ruby's modules.

If your needs are as you describe in your comment, "something like, the logic/business rules are the same, but the input and data collected are not the same", I would suggest taking a look at Rails or Django for inspiration.

In my situation, I ended up developing a framework that allowed me, when defining a model, to extend a base model class, and simply fill it with a bunch of cfproperty tags with custom properties that defined my model and were used by the base model class and a set of services which handled most of the business logic. This worked for 95% of the cases and in any situation where I needed to deviate from the framework logic, I would either add additional functions in my model cfc or even override the base model's function.

My models ended up looking like:

    <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>
瞄了个咪的 2024-11-08 16:07:02

在我看来,您正在尝试在两个站点之间重用代码,但代码存在细微差别。我知道这听起来说起来容易做起来难,但我认为你必须区分差异。因此,如果仅需要更改Accounts CFC,则维护该版本的两个版本,每个站点一个版本。

然后你可以设置一些CF映射。然后,您可以在 com.common.model 下为两个站点创建一组 CFC,在 com.mysite.model 下为另一个站点创建一组 CFC,在 com.myothersite.model 下为另一个站点创建一组 CFC

这样您就可以避免模型层中特定于站点的条件逻辑 - 这很快就会变得一团糟。

希望有帮助。

I seems to me that you are trying to reuse code between two sites but there are subtle differences to the code. I know this is going to sound easier said than done, but I think you'll have to separate out the differences. So if it's only the Accounts CFC that needs to change, then maintain two version of that, one for each site.

Then you can setup some CF mappings. You can then have a set of CFCs for both sites under com.common.model and another under com.mysite.model and another under com.myothersite.model.

That way you avoid site specific conditional logic in your model layer - which would turn into a big mess very quick.

Hope that helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文