2011-05-15 25 views
11

我正在使用一個服務層,直到現在我使用了一個ServiceObject(它實現了ArrayAccess,Iterator,Countable),但我想知道它是否是一個好主意。我的服務方法簽名應該如何?

你能幫:

ArticleService::createArticle($articleData, $userId); 

ArticleService::createArticle(ServiceObject $data); 

其中$data是:

array(
    'title' => 'Lorem ipsum', 
    'body' => 'Dolor sid amet', 
    'userId' => 55, 
); 

的ServiceObject必須爲每一個方法的共同簽名的好處,但是有時它看起來效率不高,並且沒有被廣泛使用,因此失去了它的利益。

有沒有反饋意見?

回答

0

我爲對象投票,因爲在複雜系統中的代碼完成是非常好的事情,也有一些自動驗證,因爲當你知道對象類型時你可以以某種方式驗證它。但是如果你在createSomething中沒有複雜的邏輯,那麼數組也可以適用。

0

第二種方式更好,你將永遠不會有問題的人調用你的方法是錯誤的!閱讀並查看所需內容也更容易。對於我作爲開發人員來說,很顯然我必須傳遞一個ServiceObject類型的對象,然後我開始搜索該類的文檔或示例或界面。但在第一個例子中,我必須閱讀createArticle的代碼來弄清楚如何處理這兩個參數。

第二種方法還可以幫助您保持API /簽名的清潔。當在createArticle內需要一些額外的數據時,您只需通過ServiceObject即可通過它們,而且您不需要更改簽名!

用於第一實施例A好一點簽名將是:

ArticleService::createArticle(array $articleData, $userId); 

在這種情況下$articleData必須是一個數組。這可以防止錯誤。在PHP函數參數中,只有數組和類名可用於投射。

+1

嗨,謝謝你的回答。這是我的一些想法。我首先使用了一個ServiceObject,因爲它有一些可選的參數,假設客戶端沒有提供一個可以自動生成的slug(後面的想法),我不想在每個參數上使用isset(),所以在它沒有被定義,它返回null,實體會正確處理這個,我的ServiceObject不過是一個ArrayAccess,Iterator和Count的實現,它只是一個普通的php對象,帶有toArray()輔助方法,但是我在我定義該對象的方式中可能是錯誤的。 – JohnT 2011-06-11 13:32:07

+1

關於你的「學習曲線」有趣的另一點是,如果我使用ServiceObject,我需要記錄提供的選項,如'userId','body'等。而對於一個經典的「簽名」,我可以看到方法($ userId,$ body,$ title),它是顯式的(但在進化爲bc原因時更難)。我目前認爲我應該添加PHPDoc來解釋哪些選項可用。當創建一個ServiceObject時,新的ServiceObject(array('userId'=> 1,'body'=>'lorem ipsum')); – JohnT 2011-06-11 13:33:09

+0

(很多評論對不起)另一點是當我只需要一個參數,如'getArticleById($ id)'這是常見的在這裏提供一個整數,所以是值得使用一個ServiceObject太像getArticleById(新的ServiceObject(數組('articleId'=> 1'));因爲它尊重一致性,但是輸入的時間更長,而且大多不是真正有用的,或者我可以只使用整數還是使用整數? – JohnT 2011-06-11 13:37:30

5

將其更改爲:

ArticleService::createArticle($title, $body, $user_id); 

這使得它非常清楚你需要創建一個「文章」是什麼。

'選項'數組就像你的$articleData$data是不可能明智地intellisense,我會建議反對它。

垃圾你的想法爲一個通用的ServiceObject這實際上是一個非常糟糕的主意。你的動機是高尚的,但這是錯誤的解決方案。

如果您需要更有說服力,隨時捅。

+0

謝謝你的回答,我理解你的論點,但你能解釋一下它爲什麼如此可怕嗎? – JohnT 2011-06-14 15:56:58

+3

這很「可怕」,因爲簽名並不是一個非常有用的簽名,它只是說_「這個函數有輸入」_,沒有狗屎Sherlock:p你想知道你應該放在那裏,你想有一個非常簡單的方法來找到出來了,爲什麼不明確說明呢? – Halcyon 2011-06-14 20:45:20

+0

好吧,文章是一個簡單的例子,但如果它是用UserService,用戶可以有很多參數,我總是認爲超過2/3的參數是函數設計的警告。順便說一句,用戶是非常靈活的實體,可能會有很大的變化,所以簽名由於向後兼容性原因變得難以維護。 – JohnT 2011-06-14 21:01:53

0

沒有正確的方法,但我會在這個特定的情況下使用ArticleService::createArticle($articleData, $userId);

我假設文章有一個必需的非空屬性userId(您從上下文獲得)和一個可選的(不是非常重要的)可能爲空的內容數據。

這種方式文章和用戶對象之間的連接是顯而易見的。可讀性略有提高。否則,您需要完全熟悉所需的數據和createArticle方法。

作爲證據:當我看到ArticleService::createArticle($articleData, $userId)時,我明白了方法在做什麼以及對輸入數據有什麼期望,而第二個問題讓我感到困惑。

此外,如果userId丟失,您將在此刻收到錯誤,而不是在您將其插入到數據庫的位置,您可能會遇到很難跟蹤的SQL錯誤。

另一方面,在ZF中,使用數組作爲參數非常常見,因此您的代碼可能會以不同的樣式顯示。

但它主要取決於您的偏好。

2

我覺得這裏最好的辦法是有一些像

$article = new Article; 
$article->title = "Lorem ipsum" 
$article->body = "Dolor sit amet" 
$article->creator = $userID 
ArticleService::createArticle($article) 

雖然想必「createArticle」不會對任何功能更加最好的名字,作爲第二十對象已經創建看到。你可能會喜歡ArticleService::publishArticle($article),雖然我不知道你在做什麼。

你想要的是將你的數據的構造(Article)與它的使用(ArticleService)分開。

我真的想說的是不要讓createArticle的參數成爲一個泛型數組或「ServiceObject」,它們都是無用的參數列表抽象,使它成爲一個真正代表相關實體的類。

0

我認爲更好的方法是注入一個對象。但爲什麼ServiceObject呢? 你有一個方法createArticle,那麼傳遞一個文章對象是合乎邏輯的,不是嗎? 以這種方式組織驗證過程更簡單,您可以標記要在註釋中驗證的字段。

此外,這是一個你正在使用的方法的問題。如果您在服務層使用數據映射器模式,那麼您顯然應該將一個對象傳遞給它。

使用一個對象,您可以在對象之間有透明且清晰的通信接口。 使用數組不清楚傳輸的數據類型,數據類型等。

相關問題