我在库中有一个抽象类.我正在尝试尽可能简单地正确实现此类的派生.问题是我需要在三个步骤中初始化对象:获取文件,执行一些中间步骤,然后使用该文件.第一步和最后一步特别适用于派生类.这是一个精简的例子.
abstract class Base
{
// grabs a resource file specified by the implementing class
protected abstract void InitilaizationStep1();
// performs some simple-but-subtle boilerplate stuff
private void InitilaizationStep2() { return; }
// works with the resource file
protected abstract void InitilaizationStep3();
protected Base()
{
InitilaizationStep1();
InitilaizationStep2();
InitilaizationStep3();
}
}
Run Code Online (Sandbox Code Playgroud)
当然,麻烦在于构造函数中的虚方法调用.如果他们不能指望派生类完全初始化,我担心库的使用者在使用类时会发现自己受到限制.
我可以将构造函数中的逻辑拉出到受保护的Initialize()方法中,但是实现者可以直接调用Step1()而Step3()不是调用Initialize().问题的关键在于如果Step2()被跳过则不会有明显的错误; 在某些情况下表现糟糕.
我觉得无论哪种方式都存在严重且不明显的"问题",未来的图书馆用户将不得不解决这些问题.我应该使用其他一些设计来实现这种初始化吗?
如有必要,我可以提供更多细节; 我只是想提供表达问题的最简单的例子.
我有一个特别困难的业务约束,我想在数据库级别强制执行.这些数据本质上属于财务数据,因此必须保护其不存在与第n度的不一致 - 不要信任业务层.我稍微松散地使用"时间"这个词,这意味着我打算控制一个实体如何能够随着时间而改变.
对细节进行着色,这是设计:
这是一个精简的数据定义:
CREATE TABLE Invoices
(
InvoiceID INT IDENTITY(1,1) PRIMARY KEY,
)
CREATE TABLE Fees
(
FeeID INT IDENTITY(1,1) PRIMARY KEY,
InvoiceID INT REFERENCES Invoices(InvoiceID),
Amount MONEY
)
Run Code Online (Sandbox Code Playgroud)
您会注意到发票的"可锁定"性质未在此处表示; 如何表达它 - 以及它是否需要直接表示 - 仍然是一个悬而未决的问题.
我开始相信这是那些无法转换为域密钥正常形式的安排之一,尽管我可能错了.(毕竟,真的没有办法说出来.)尽管如此,我仍然对高度规范化的解决方案抱有希望.
我碰巧在SQL Server 2008上实现了这个(语法可能是一个暗示),但我是一个好奇的人,所以如果有其他DBMS的解决方案,我也很想听到这些.