2015-11-23 63 views
2

我有以下方法:不扔業務異常,但返回值

public void Foo addFoo(String name); 

這種方法增加了Foo一些結構。在同一時間,它檢查Foo給定的name是否已經存在。我可以拋出一些FooNameConflictException,但我不會,因爲我不認爲這是例外情況 - 這可能會發生,並且它是應用程序業務流程的一部分。

相反,如果Foo已經存在,我會返回信息。做這件事的實用方法是什麼?如果名稱已經存在,應該返回什麼?

  1. 返回null - 這是純粹的醜陋null並不意味着什麼,這是不可擴展和......醜。

  2. 返回Foo帶有一些內部狀態,表明Foo是NEW或EXISTING。但是,我們必須仔細設計從NEW - > EXISTING的狀態更改,即我不確定何時會發生這種情況,並且可能會在多線程環境中失敗。

  3. 結交新類FooOperationFooAdding了組成Foo實例和附加的旗(縣),其帶來的添加過程的更多信息。

  4. 我可能會使用#3的通用變體,並且擁有像Either這樣的類,但是這樣就會綁定到兩個值(左側或右側)。

我看到解決方案#3作爲唯一的實用在這種情況下。我錯過了什麼嗎?

+1

乍一看這聽起來像這種方法承擔不止一項責任,並應分解成不同的責任。 – Makoto

+0

爲什麼你需要知道'name'的'Foo'值已被添加,而不是在'addFoo'方法之外重用?你還說衝突是在正常的業務流程中可能發生的事情,你們的業務如何處理這種情況? – Jean

+0

你吞嚥你的例外嗎? –

回答

0

通過經驗,如果nameFoo對象的關鍵你的情況,我想如果發現返回相關的名稱Foo對象。

因此,該方法的用戶將使用返回的Foo對象,而不是關心它是新對象還是已經存在的對象。如果您必須知道Foo對象的狀態,則可以在其中添加state屬性。

+0

這就像#2,但這給了額外的工作正確地做狀態。例如,狀態可能爲NEW,然後附加線程發出實例,並在實際上已被第一個線程使用之前狀態更改。 – igr

0

就我個人而言,我仍然會去尋找例外,但包括檢查它是否存在於您的調用代碼中。

因此,您的正常業務流程包括檢查名稱衝突和適當的反應。儘管存在衝突,調用addFoo將導致引發異常。

如果你願意,你可以在自己的方法中將check + handling + call與addFoo結合起來,甚至可以讓addFoo的可見性有效(使之成爲私有的或者在你的情況下最好的)。

我典型的替代方案是C語言風格:總是返回的結果代碼,讓此基礎上調用代碼分支(成功,nameConflict,...)