我必须创建一个基于数据库中数百个不同表的报告系统(这意味着大量的报告),我想知道最佳实践和/或您对此的疯狂想法。
以下是详细信息:
最简单的解决方案是为每个品牌分别实现每一份报告,但这将是一项耗时的工作,而且几乎是重复的工作,所以我想避免这种方法。
我正在考虑一种“流水线”风格的体系结构(见附件图像),在这里,我只是为每个片段定义了一些规则,而且无论输入参数如何,相同的算法都可以计算结果。这样,如果我必须为劳斯莱斯显示一个新的报告,我只是定义一些规则,我得到的结果。关于规则,我在考虑每个品牌的表定义、字段映射等等。

这个解决方案的问题是,我必须为每一步实现某种解释器,分析和执行规则集,这些规则集是危险的,不可维护的,而且我不确定它是否具有可伸缩性。是否有其他避免重复工作的方法或最佳做法?
发布于 2021-08-09 09:53:46
基于所提供的信息,一个简单的接口将满足您的可重用需求。
注意:人们可能会争论使用基类(抽象与否)而不是接口。我建议错误地使用不支持多重继承的语言的接口,或者当所需的契约不需要基本实现时。
例如:宝马有一个台式机,其字段名为cc(用于发动机排量),但福特在一个名为“cu”的表中存储了相同的内容。
您在这里已经确定,虽然数据的存储方式不同,但您希望处理相同的数据(一旦检索到)。检索到的数据并不是特定于给定制造商的,因此您可以创建一个数据实体来表示它:
public class Car
{
public string Make { get; set; }
public string Model { get; set; }
public int CC { get; set; }
}这只是一个基本的例子。
但是,每个制造商对数据的获取是不同的,因此您的存储库将有明显的不同。尽管如此,他们有着相同的可重用期望:检索汽车。这就是我们定义接口的原因:
public interface ICarRepository
{
IEnumerable<Car> GetAll();
}当然,您可以扩展这个接口,例如GetByEngineCC(int minCC)。这取决于你需要什么。
然后,这可以由特定于制造商的存储库实现,它们各自具有不同的私有逻辑来获取所需的数据。
public class FordCarRepository : ICarRepository
{
public IEnumerable<Car> GetAll()
{
// fetch from the Ford tables
}
}
public class BmwCarRepository : ICarRepository
{
public IEnumerable<Car> GetAll()
{
// fetch from the BMW tables
}
}这确保您可以编写适用于所有可能的制造商的报表生成器逻辑。例如:
public void PrintReport(ICarRepository repo)
{
var cars = repo.GetAll();
foreach(var car in cars)
{
Console.WriteLine($"{car.Make} - {car.Model} - {car.CC}cc");
}
}请注意,如果这些制造商的存储库实现了所需的接口,那么这个报告逻辑是如何为所有制造商工作的。
这是如何处理内部不同实现(即唯一的数据获取)的核心原则,但使用外部通用处理(即通用报告)。现在,您可以通过创建额外的具体存储库将新的制造商添加到混合产品中,但是不需要更改其他代码,这是理想的目标。
另一方面,价格和销售储存在一个表中,丰田的情况下,在5个表(外键链接)的情况下,马自达。
这里也有同样的故事:
SalesFigure DTOISalesRepository )定义一个GetSalesForYear(int year)接口ISalesRepository的特定于制造商的销售存储库ISalesRepository对象,而不是特定于制造商的存储库类型。这样,如果我必须为劳斯莱斯显示一个新的报告,我只是定义一些规则,我得到的结果。
这不是“规则”。这是一个不同的实现。你的基本想法是正确的,但我建议不要把它称为规则,因为人们会误解你的意图。
本质上,您所要做的就是添加一个特定于Rolls的存储库,它实现了相同的接口(cfr步骤3)。
注意:由于您谈到了数据库表,因此这个示例使用了使用相同接口的不同的具体存储库。在其他情况下,在BLL而不是DAL上实现这个接口可能更有意义。但是,无论您在哪个层实现它,它都是相同的原则。
https://softwareengineering.stackexchange.com/questions/430913
复制相似问题