2011-06-19 279 views
0

我正在使用類似SOA的應用程序的依賴注入。你如何使用依賴性服務和依賴注入?

例如,我有一個VoteService,用於爲投票和評論投票。

我已經有4個依賴關係,文章,評論,數據庫抽象層和需要投票的用戶。

所以我的構造函數有4個參數來填充我的對象。

我總是聽說超過2/3的參數是錯誤代碼設計的警告,我可能會同意這一點。

也許我的VoteService沒有很好的設計。

我可能必須在第&評論服務中移動投票投票嗎?

您認爲如何?


class ArticleService { 
    public function createArticle(); // and other crud methods 
} 

class VoteService { 

    public function __construct($entityManager, $articleService, $commentService, $configurationService); 

    // here is the constructor with much arguments 

    public function addArticleVote() 
    { 
    $vote = new ArticleVote(); 
    $vote->setType(ArticleVote::TYPE_UP) 
    $vote->setArticle($article); 
    $this->entityManager->persist($vote); 
    $this->entityManager->flush(); 
    } 

    // the same method applies for comment 
} 
+0

3是教條小數目。就我個人而言,我開始認爲,也許這應該在6-7左右之後完成。但無論如何,因爲你不會編寫調用這個構造函數的代碼,所以這個論點是沒有意義的。 – Jon

+0

爲了解決這個問題,並幫助關閉我腦海中尖叫的聲音,我通過在數組中放置15個參數來作弊。然後,我只通過一個變量right:D –

回答

0

總是聽說,超過2/3的論點是錯誤的代碼設計

完全地錯誤的警告。特別是在這種情況下。
你正在做正確的方式(DI)。這裏不需要改變。

我可能必須在第&評論服務中移動投票投票嗎?

這可能是另一種解決方案。但你可以隨意留在這個imo。
如果您想要實現此解決方案,您可以使用方法addVote創建一個接口IVotable

在這一點上,你可以在你的Articles/Comments類實現這個接口,所以你可以這樣做:

$a = new Article; 
$b = new Comment; 
$a->addVote($currentLoggedUser,10); //> Inject only loggedUser (and maybe your DAL) 
$b->addVote($currentLoggedUser,10); 
4

我總是聽說,超過2/3的論點是錯誤的代碼設計警告

這本身並不是一個問題。這只是潛在問題的一個指標。

而這條規則通常適用於公共成員函數,而不適用於構造函數。

像這樣的經驗法則如果盲目應用,會很危險。你可能有一個問題,你可能沒有任何問題。

可能(或可能不)在你的架構中存在的問題的一些示例:

  • 您的投票服務做得太多,而應該被分拆
  • 你「投票服務」 ISN實際上它自己的邏輯概念,只是系統中其他概念的一個方面
  • 您錯過了概念的抽象概念(在這種情況下,投票包含文章,評論和用戶)

但是我真的不得不看到更多的代碼來告訴你它們是否適用。從你的簡短描述來看,這聽起來像你的服務很簡單,並且你在過度思考問題。

我正在使用類似SOA的應用程序的依賴注入。

在SOA應用程序中,您將擁有用戶不應該知道的依賴關係。不要將它們暴露給用戶。在這種情況下,用戶不應該知道DAL。

解決此問題的一種方法是將您的應用程序的頂層(注入頂層依賴關係的那個層),在頂層添加墊片,並僅將墊片展示給用戶。

查看Facade Pattern

編輯:

例如,我有這是用來投票兩種文章和評論一個VoteService。 ...所以我的構造函數有4個參數來填充我的對象。

依賴注入不是只有構造函數注入。您還可以通過屬性(或setter函數)和每個方法調用期間注入依賴項。您應該對每個依賴使用任何有意義的內容。

您是否總是同時對文章和評論投票?你是否總是對同一篇文章和/或同一評論進行投票?我的猜測是否定的,所以不要在構造函數中傳遞它們。

只傳遞那些在構造函數中的用法之間不會改變的依賴關係。傳遞函數中參數列表中每次使用更改的依賴關係。通過屬性/設置器傳遞可選的依賴關係。

你的具體情況,你應該採取$entityManager在構造函數中,採取$configurationService無論是在構造函數或在二傳手(取決於它是否能夠生活在沒有依賴),取$articleServiceaddArticleVote方法,並採取中的addCommentVote方法。

class VoteService { 

    public function __construct($entityManager); 

    // Adding this in case you have sensible logic if it isn't present. 
    // If it isn't optional (you don't have defaults that make sense to put in this class), 
    // then put it back in the ctor 
    public function setConfigurationService($configurationService) 
    { 
    // ... 
    } 

    public function addArticleVote($articleService) // or $article 
    { 
    // ... 
    } 

    public function addCommentVote($commentService) // or $comment 
    { 
    // ... 
    } 
} 

也許我VoteService然後沒有精心設計的。

我會評估你是否應該有一個VoteService。例如,在ArticleServiceCommentService類中添加vote方法,或者甚至在ArticleComment類中添加vote方法可能是有意義的,這些類尚未描述。

如果你有興趣在這類型的反饋(看到你應當如何重構你的整套類),那麼你應該張貼另一個問題上http://codereview.stackexchange.com

+0

+1,以便深入地識別缺少抽象/概念(投票對象)。尼斯。 –

+0

我可能並不清楚,當我的意思是DAL我是指Doctrine 2實體管理器不是DAL本身。我將編輯我的問題,向您展示更多我當前的代碼。 – JohnT

+0

編輯我的問題 – JohnT