我在下面的 Billing
类中有一个 ApproveCheck
方法。此方法批准从客户那里收到的带有订单号的支票,并将其与订单进行匹配以批准它们。所有这些类都没有任何接口(interface),因为它们没有任何要测试的业务逻辑,而是直接与数据库交互。
这是否遵循 SOLID 原则?我应该考虑 SOLID 吗,因为这些类不是为了测试而缩进的,或者后端数据库永远不会改变?如果我不得不考虑,我该如何重构这段代码以实现 SOLID?
public class Billing : Payment
{
public void ApproveCheck()
{
var checksReceived = GetUnapprovedChecksReceived();
var ordersReceived = GetPendingOrdersReceived();
var unapprovedChecks = ordersReceived.Join(checksReceived,
o => o.CheckNumber,
c => c.CheckNumber,
(o, c) => new { c.checkNumber });
// Approve the unapprovedChecks
}
}
public class Payment : Order
{
public Checks GetUnapprovedChecksReceived();
}
public class Order
{
public Orders GetPendingOrdersReceived();
}
我无法帮助您重写,但我可以将示例与定义进行比较
坚固
单一责任原则 - 维基百科说“......每个模块或类都应该对软件提供的功能的单一部分负责,并且该责任应该完全由类封装”。
没有足够的示例代码来确定。
开放/封闭原则 - SOLID 非常依赖于具有可以通过多种不同方式实现的抽象接口(interface)。为满足这一原则,需要清晰的界面和强大的文档。
Liskov 替换 - 第一种方法是查看继承层次结构并询问“A 是 B 的一种吗”? “账单是一种付款吗?”,“付款是一种订单吗?”如果您可以对这些问题回答是,那么您就走在了正确的轨道上。如果答案是否,那么层次结构需要改变。
接口(interface)隔离。有哪些接口(interface)?我不是会计师,但这个模型似乎不合时宜。从我看到的一点点来看,我会将支票建模为 Payment 或 PaymentMethod。层次结构可能是 Check : NegotiableInstrument : PaymentMethod。我可能会用它来生成收据,这是付款的证据。 Receipt 是将与 AccountsReceivable 模块交互的类。在某些时候,这可能必须与对帐过程相关联,在对帐过程中收据被标记为“已核对”或“已退回”(如果支票退回)。一个真正的会计师可以告诉你更多。
更新:
- 依赖反转——如果类直接进入数据库,就没有反转依赖的机会。相反,想象一个像 Account 或 Repository 这样的抽象类。 Repository 类具有查询会计对象(如支票)的方法。至少会有一个 Repository 的具体实现,但可能会有很多。例如,一个实现可能连接到 SQL 数据库(例如 MySqlRepository 类)。另一种实现可能会从文件中读取检查对象(例如 FileRepository 类)。第三种实现可能会发送 REST 请求以从云提供商那里获取支票(例如 YoyodyneCloudRepository 类)。重要的是需要检查的代码是针对接口(interface)或抽象类编写的。这样,更容易切换不同的数据源。当实际存储库发生变化时,需要使用检查的类不需要更改。
根据我过去所见,SOLID 代码需要一个以定义的方式进行交互的抽象框架。有关使用高级抽象的会计模型的示例,请查看 Martin Fowler 的一些资料。 https://www.martinfowler.com/apsupp/accounting.pdf .这可能比您的情况更笼统,但这是开始阅读的好地方。