在这个使用 C# 的应用程序中应用开闭原则的最合适方法是什么?
场景
每天晚上,我们都会对大约一百万个客户合约执行一系列计算。每个合同都与一组大约十个产品中的一个相关,每个产品都可以采用要执行的计算集的变化(尽管总体流程大致相同)。给定产品的所有合约将在任何给定夜晚使用相同的计算集;分布不均匀,从最小的产品几千到最大的几十万不等。
随着时间的推移,我们将添加新的类似(但不太可能相同)的产品,并且可以通过引入所采用的算法的变化来调整现有产品。 (顺便说一句,我希望算法能够在不修改代码的情况下进行参数变化)。
我们用来支持这一点的核心“引擎”应该适用于产品开发和生产。后者由我们的运营人员管理,他们对自己接受的内容以及一般如何管理变革非常谨慎。
在考虑架构时,我强烈倾向于开闭原则:
软件实体应该开放 延长,但关闭 修改。
由于我们计划在 C# 中实现,我正在考虑规定函数在核心外部定义、以文本形式加载并在产品运行开始时在产品定义的当前版本的控制下进行编译。这些组件中的每一个都将编译为一个类,该类实现应用程序的已编译元素中定义的接口(或等效接口)。我乐观地认为,从运营的角度来看,这将被认为是一个优点,因为回归测试的范围大大缩小了。
问题
这有意义吗?任何人都可以针对潜在的陷阱提供任何明智的建议吗?
我是否要重新发明依赖注入?是否最好通过每次提供新的 DLL 来提供定期更改?如果是这样,这会让我们的日常产品开发流程变得多么糟糕?
或者我应该采取更敏捷的方法,端到端构建一个产品,然后依次添加其他产品,看看重构时会出现什么架构?
如果你还在我身边,谢谢你的耐心...
Scenario
Each night we perform a series of calculations on about a million customer contracts. Each contract is related to one fo a group of about ten products, each of which may employ variations on the set of calculation for be performed (although the overall flow is largely the same). All the contracts for a given product will use the same set of calculations on any given night; the distribution is uneven though ranging from a few thousand for the smallest product to a few hundred thousand for the largest.
Over time we will add new similar (but unlikely to be identical) products and existing products may be adjusted by introducing variations to the algorithms employed. (I expect algorithms to be able to be varied parametrically without code modification, by the way).
The core "engine" we use to support this should be applicable both in product development and production. The latter is managed by our Operations people who are very cautious about what they accept and how change is managed generally.
In considering an architecture I'm strongly drawn to the Open-Closed Principle:
Software entities should be open for
extension, but closed for
modification.
Since we're planning to implement in C#, I'm considering stipulating that functions be defined externally to the core, loaded in text form and compiled at the start of the run for a product under the control of the current version of the product definition. Each of these components would compile to a class that implements an interface (or equivalent) as defined in the compiled element of the application. I'm optimistic that this would be considered a plus from the Operations point-of-view since the scope of regression tests is dramatically reduced.
The Question(s)
Does this make sense? Can anyone offer any sage advice as to potential pitfalls?
Am I re-inventing dependency injection and would I be better-advised to deliver the regular changes by, say, providing a new DLL each time? If so, how much worse does that make our daily product development process?
Or should I take a more Agile approach, build one product end-to-end and add the others in turn, seeing what architecture emerges as I refactor?
If you're still with me, thanks for your patience...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用依赖项注入创建一个具有采用 IProcess 参数的进程方法的类。为实现此接口的每个产品类型创建一个不同的类,每个类应该位于它自己的 DLL 中。创建一个配置文件以将产品类型映射到进程 dll 和类。然后,您可以使用反射读取配置文件并加载相关 dll,并将它们传递到 DI 类上的处理函数中。这样,您只需创建一个新的 DLL 并更新配置文件即可添加新进程。更改现有进程只需更新相关类并重新部署 dll 即可。
Use dependency injection to create a class with a process method that takes an IProcess parameter. Create a different class for each product type that implements this interface, each class should be in it's own DLL. Create a config file to map product type to process dll and class. You can then use reflection read the config file and load the relevent dlls and them pass them into the process function on the DI class. THat way you can add a new process by simply creating a new DLL and updating the config file. Changing existing processes is simply a nmatter of updating the relevent class and redeploying the dll.