2011-12-20 17 views
0

首先我的要求是當需求以這種方式演變時,如何區分責任?

「我們可以在其上創建一個帳戶投入資金,當我們購買項目,我們降低了賬戶」

所以我的AccountController看起來像

class AccountController 
{ 
    private IAccountDataSource _accountDataSource; 

    Create(Account anAccount) 
    { 
     _accountDataSource.Insert(anAccount); 
     Render(anAccount.Id); 
    } 
} 

但隨後有一個新的要求 「有些人可以有一個免費帳戶(所有項目將是免費的),但如果我們創建一個真正的帳戶,然後我們刪除了免費帳戶」

所以我的控制器.Create成爲

Create(Account anAccount) 
{ 
    _accountDataSource.Insert(anAccount); 
    RemoveFreeAccount(anAccount.Customer); 
    Render(anAccount.Id); 
} 

RemoveFreeAccount(Customer aCustomer) 
{ 
    _accountDataSource.Remove(new AccountFilter() { Type='Free', CustomerId=aCustomer.Id }); 
} 

但對我來說,感覺就像我應該把這個RemoveFreeAccount別的地方,但我不知道在哪裏,因爲IAccountDataSource只是假設來處理數據存儲。

回答

1

問題顯示您正在破壞SRP。你的控制器不應該包含業務邏輯。直接在控制器中使用存儲庫會迫使您將所有邏輯放入其中,並因此承擔兩項責任(作爲處理業務邏輯的MVC +中的M之間的橋樑)。

第一重構部分應該是業務邏輯移動到模型(MVC不與實體模型或視圖模型混淆)

這給你的原始代碼的結構如下:

public class AccountService 
{ 
    void CreateAccount(string accountName) 
    { 
     var account = new Account(accountName); 
     _dataSource.Create(account); 
     DomainEvents.Publish(new AccountCreated(account)); 
    } 
} 

public class AccountController 
{ 
    private AccountService _service; 

    Create(AccountViewModel model) 
    { 
     var account = _accountDataSource.Create(model.Name); 
     Render(account.Id); 
    } 
} 

的改變可能看起來不起眼,但是很重要:

  1. 控制器現在都只有一個理由去改變(在視圖和模型之間的映射)
  2. 業務需求的任何更改都不會強制更改UI層。因爲它需要在其他帳戶的服務沒有變化

    public class FreeAccountService : ISubscriberOf<UserCreated>, ISubscriberOf<AccountCreated> 
    { 
        public FreeAccountService(AccountService) 
        { 
        } 
    
        public void HandleEvent(UserCreated domainEvent) 
        { 
         accountService.Create(new FreeAccount()); 
        } 
    
        public void HandleEvent(AccountCreated domainEvent) 
        { 
         var freeAccount = dbSource.GetFreeAccount(); 
         if (freeAccount != null) 
          accountService.Delete(freeAccount) 
        } 
    } 
    

  3. 變化的要求只在一個地方

了添加的,我會用一個事件驅動模型免費帳戶支持。

+0

這是一個很好的解決方案,但是您不覺得CRUD系統有太多抽象嗎? –

+0

我的經驗是沒有系統保持簡單的CRUD系統。你的問題就是一個很好的例子。免費帳戶功能是業務規則,而不僅僅是CRUD。從一開始就做,或者稍後再做一次維護噩夢。 – jgauffin

+0

您使用哪個API /框架來處理事件?有沒有像這樣的內置工具? –