これは、POLAだけでなく、バグの原因となる可能性のある無効な状態を防ぐことでもあります。
具体的な実装を提供せずに、例にいくつかの制約を提供する方法を見てみましょう。
最初のステップ:ファイルを開く前に、何も呼び出さないでください。
CreateDataFileInterface
+ OpenFile(filename : string) : DataFileInterface
DataFileInterface
+ SetHeaderString(header : string) : void
+ WriteDataLine(data : string) : void
+ SetTrailerString(trailer : string) : void
+ Close() : void
これで、実際のデータを書き込むことができるインスタンスCreateDataFileInterface.OpenFile
を取得するために呼び出す必要があることは明らかDataFileInterface
です。
2番目のステップ:ヘッダーとトレーラーが常に設定されていることを確認してください。
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が示唆するように、常にビルダーを好むでしょう。