我也处于你的位置,我同意这是一个困难的位置。就我而言,我正在为客户构建定制的单一产品网站。虽然每个站点都遵循类似的布局和工作流程,但每个站点都必须有足够的灵活性才能拥有完全定制的设计、围绕运输和优惠券的定制规则以及不同的商家网关和配置。
几年后,我们确实得到了一些可维护的东西。首先,我们创建了库来存放我们所有的公共代码,并将这些库放入一个简单称为 Common 的 TFS 项目中。然后,我们为每个站点(不是客户,因为许多客户有多个产品/站点)创建了一个新的 TFS 项目,并将适用的项目从 Common 分支到它们中。接下来,我们创建了一个包含站点骨架的 VS 模板项目,包括“无设计”视图、控制器及其操作方法(请记住,每个站点都有相同的基本流程)。此外,每个站点都在自己的数据库上运行,该数据库是从一个其他未使用且大部分为空的模板数据库中克隆的。
由于每个站点都在自己的分支和数据库上运行,因此可以对模板安装的原始流程和设计进行修改(无需重新合并),而不会影响任何其他站点。对于自定义业务方法,例如运输计算,我们可以创建公共类的子类并在需要时覆盖。实现这一点的部分原因是将我们所有的代码转换为使用依赖注入。具体来说,每个 Controller 都注入了 Services,每个 Service 都注入了 Repositories。商户处理也被编码到一个接口并注入。另外值得一提的是,这允许我们对每个站点的所有加售逻辑进行硬编码(您购买了产品 X,所以我们推荐 Y),与在我们旧的追加销售规则引擎中定义复杂的配置规则相比,这更容易创建和维护。不知道你有没有这样的...
有时我们希望对公共代码本身进行更改,这通常是由对特定站点的特定需求引起的。在这种情况下,我们将在该分支上进行更改,将其合并到 Common,然后在方便时将其合并到其他站点(非常适合“破坏”更改或还需要更改数据库的更改)。同样对于数据库更改,我们将更新模板数据库,然后编写一个小脚本来更新具有相同架构更改的其他站点数据库(仍然必须聪明并小心)。
另一个好处是我们还创建了 Mock 存储库,这些存储库将在“设计”构建配置中使用/注入,这使设计人员能够在应用程序中跳转并在屏幕上工作,而无需将自己真正提交给工作流。它还允许他们在后端完成任何操作之前开始在站点上工作,这对于那些需要“看到一些东西”的焦虑客户来说非常重要。
10+ 客户绝对不是你所说的小数目。三对我来说已经足够痛苦了。我们同时运行了 30 多个站点,由三位开发人员和两位设计师维护。
Finally, I know it's outside the scope of your question and a bit presumptuous, but getting "final" client sign-off on design before the designers actually went about implementing it (and before devs did their thing) also saved us a lot of costly rework. I know no design is final, but increasing efficiency on the implementation end gave the clients less time to change their minds about the design they approved.
I hope that at least gives you some approaches to think about.