Guillermo、例外処理は、ここでいくつかの悪いアイデアをシームレスに置き換えることができます。
- thisContextを使用する(これはほとんど必要ではなく、通常は悪い考えです)
- たとえば「1|」の周りに文字列を渡す、UserInterfaceinvalidCartIdErrorMessage
- returnの使用:これらの文字列を使用してエラーを渡します
また、retrieveCart:onErrorReturnFrom:の実行が多すぎます。すべてのエラーハンドラーを使用すると、実際のロジックが失われます。
したがって、最初に行うことは、ドメインの概念を表すErrorサブクラスを作成することです(例:AddBookError、CartExpiredError、InvalidCartError)。
次に、次のようにエラーメッセージを設定します。
CartExpiredError>>initialize
super initialize.
self messageText: '1|', UserInterface cartHasExpiredErrorMessage.
次のこと(実際には2つのステップ)は、生のディクショナリメソッドをプライベートアクセサに置き換えることです。プライベートアクセサは、次のように新しいErrorクラスを使用できます。
timestampFor: aCartId
^ cartCreationDateAndTime at: aCartId ifAbsent: [ InvalidCartError signal ].
と
cartNumber: aCartId
^ carts at: aCartId ifAbsent: [ InvalidCartError signal ].
Cart>>add: aQuantity booksWithISBN: aBookISBN
fail ifTrue: [ AddBookError signal ].
これで、retrieveCart:onErrorReturnFrom:は次のようになります。
retrieveCart: aCartId
| aCartCreationDateAndTime |
aCartCreationDateAndTime := self timestampFor: aCartId.
Time now > (aCartCreationDateAndTime + 30 minutes) ifTrue: [ CartExpiredError signal ].
^ self cartNumber: aCartId.
そして最後に、大幅に簡略化されたAは次のようになります。
add: aQuantity booksWithISBN: aBookISBN toCart: aCartId
| aCart |
[aCart := self retrieveCart: aCartId.
aCart add: aQuantity booksWithISBN: aBookISBN]
on: Error
do: [ :e | ^ e messageText ].
^ '0|OK'.
これはまだクリーンアップでき(たとえば、messageTextの前に「1 |」を付けるすべてのErrorクラスのスーパークラスを作成する)、明らかにこの簡略化されたバージョンを実際のプロジェクトに組み込む必要がありますが、例外がどのようにできるかを確認し始めることができますあなたの人生を楽にしますか?
これは、 githubでのテストに合格した、コードの動作するモックアップです。
nb私が気付いたもう1つのことは、aCartCreationDateAndTimeでした。これがカートのプロパティである方が自然に思えますが、実際のアプリケーションでは意味がないかもしれません...