这不仅与POLA有关,而且与防止无效状态(可能是错误的来源)有关。
让我们看看如何在不提供具体实现的情况下为您的示例提供一些约束:
第一步:打开文件之前,不允许调用任何内容。
CreateDataFileInterface
+ OpenFile(filename : string) : DataFileInterface
DataFileInterface
+ SetHeaderString(header : string) : void
+ WriteDataLine(data : string) : void
+ SetTrailerString(trailer : string) : void
+ Close() : void
现在很明显,CreateDataFileInterface.OpenFile
必须调用它来检索DataFileInterface
可以写入实际数据实例。
第二步:确保始终设置标题和结尾。
CreateDataFileInterface
+ OpenFile(filename : string, header: string, trailer : string) : DataFileInterface
DataFileInterface
+ WriteDataLine(data : string) : void
+ Close() : void
现在,您必须预先提供所有必需的参数才能获得DataFileInterface
:文件名,标题和结尾。如果在写入所有行之前都无法使用预告片字符串,则也可以将此参数移动到Close()
(可能将方法重命名为WriteTrailerAndClose()
),以便至少在没有预告片字符串的情况下无法完成文件。
回复评论:
我喜欢界面的分离。但是我倾向于认为您关于强制执行的建议(例如WriteTrailerAndClose())正在违反SRP。(这是我在很多情况下一直在努力的事情,但是您的建议似乎是一个可能的例子。)您将如何回应?
真正。我不想把所有的精力都集中在示例上,以说明我的观点,但这是一个好问题。在这种情况下,我想我会称呼它Finalize(trailer)
并且认为它不会做太多。编写预告片和结束语仅是实现细节。但是,如果您不同意或有不同的类似情况,则可以采用以下解决方案:
CreateDataFileInterface
+ OpenFile(filename : string, header : string) : IncompleteDataFileInterface
IncompleteDataFileInterface
+ WriteDataLine(data : string) : void
+ FinalizeWithTrailer(trailer : string) : CompleteDataFileInterface
CompleteDataFileInterface
+ Close()
在这个示例中,我实际上不会这样做,但是它显示了如何进行这项技术。
顺便说一句,我假设实际上必须按此顺序调用方法,例如要顺序写入许多行。如果不需要这样做,那么我总是喜欢Ben Cottrel建议的建造者。