我正在开发一个数值模拟库,它以不同计算算法操作的单个数据集合为中心。算法很复杂,它们具有涉及多个参数的不同状态,并且是可互换的(在一些语义限制下)。
为了避免集合的膨胀界面并启用不同的实现等,我正在考虑使用基于策略的设计。这为集合提供了存储结构,算法,参数,内部资源之间广泛的选择组合。
如果我想象我重新设计了我的通用/面向对象的现有设计使用策略,我该如何选择最佳算法和数据结构?从概念上讲,我需要定义一组策略和一组验证测试用例,并执行参数研究。
当使用面向对象编程时这很容易,因为我可以在运行时使用例如确定所有必要类型及其参数。基于字符串的抽象工厂,其类型名称存储在输入文件中,然后由在一系列测试用例上执行客户端应用程序的外部脚本更改。
如何在策略中实现这一点,其中N个策略的组合最终成为N个不同的客户端应用程序?
如何以专业的方式与基于策略的设计一起完成自动化测试?
答案 0 :(得分:1)
如果您将算法表示为策略,则您/应该/已经考虑过一个非常统一的接口。你可以想象一个“AlgorithmPolicy”处理你的数据存储中的一些数据并返回一些结果表示。
“如果我想象我重新设计了我的通用/面向对象的现有设计使用策略,我该如何选择最佳算法和数据结构?”
如果您的面向对象设计目前使用策略模式(另请参阅:Gang of Four一书),您的策略将简单地替换您使用策略的每个地方。为您设计的不同策略选择“最佳算法”只需要为这些策略确定正确的概念结构/接口。 (例如,如果您要使用许多不同的数据存储,请确保用于添加/删除/获取数据的界面是统一的。在这里,考虑三个示例并找到共性可能会有所帮助......然后考虑另一个例子并确保它符合模式。迭代直到事情感觉正确。)
你仍然会有足够的类型检查,它会感觉有点不同(你可能偶尔遇到一些讨厌的编译错误。;)
测试只是为您想要涵盖的每个配置/策略组合编写一些单元测试。你可能应该已经在编写这些测试了;主要区别在于您希望尝试触及您指定的接口,而不是针对具体细节。
您可以根据算法策略的验证来验证不同的存储方法。 (所以,如果我有一些可以以不同方式存储的算法,我可以在一些测试数据上运行算法以获得ecah存储机制并期望得到相同的结果。)假设你已经指出了接口的相关性,那么你应该只需要为您添加的每个附加存储机制编写一个测试。
再次:有关程序结构的更多详细信息,有什么不同的参数以及您需要传递的信息,这样会很好。(这些代码是开源的还是开源的?)
根据您的说法,在我看来,复杂的政策流程可能会有这样的界面:
FancyDataStore.Process()
为了测试它,我写道: MockAlgorithmPolicy - 一种非常简单的算法,无需验证。 MockInternalStuffPolicy - 一个非常简单的内部填充策略,不会导致任何新的集成/报告。 MockStoragePolicy - 一个非常简单的存储策略,可以满足您的存储界面/不会导致很多问题。
编写一个测试,验证放在一起的模拟... 对于您创建的每个StoragePolicy,编写一个自动化测试来验证它:
testSomeStoragePolicy{
// has a call to:
FancyDataStore.Process<MockAlgorithmPolicy, SomeStoragePolicy, MockInternalStuff>()
// validate...
}
这应该证明SomeStoragePolicy按预期工作。
然后,对于您的算法,您可以写:
testSomeAlgorithmPolicy{
FancyDataStore.process<SomeAlgorithmPolicy, MockStoragePolicy, MockInternalStuff>();
///Validate.
}
等。 通过这种方式,您最终编写的每个策略基本上都会编写1个测试(这似乎是可行且不太荒谬)此外,您始终可以添加其他单元测试以涵盖可能随时间推移的其他细微集成。
如果你正在寻找关于这个主题的好书,我建议阅读“现代C ++编程”;它为C ++中的策略驱动设计提供了很好的入门。