2013-02-07 39 views
0

我目前的服務和業務層實現如下圖所示。將行爲添加到現有實現 - C#/設計模式

public class MyEntity { } 

// Business layer 
public interface IBusiness { IList<MyEntity> GetEntities(); } 
public class MyBusinessOne : IBusiness 
{ 
    public IList<MyEntity> GetEntities() 
    { 
     return new List<MyEntity>(); 
    } 
} 

//factory 
public static class Factory 
{ 
    public static T Create<T>() where T : class 
    { 
     return new MyBusinessOne() as T; // returns instance based on T 
    } 
} 

//Service layer 
public class MyService 
{ 
    public IList<MyEntity> GetEntities() 
    { 
     return Factory.Create<IBusiness>().GetEntities(); 
    } 
} 

我們需要對當前實施進行一些更改。原因是數據增長在時間和服務&客戶端無法處理的數據量。我們需要爲當前的服務實施分頁。我們也期待更多的功能(如返回故障時的數據更是門檻,應用過濾器等),這樣的設計需要更新。

以下是我的新建議。

public interface IBusiness 
{ 
    IList<MyEntity> GetEntities(); 
} 

public interface IBehavior 
{ 
    IEnumerable<T> Apply<T>(IEnumerable<T> data); 
} 

public abstract class MyBusiness 
{ 
    protected List<IBehavior> Behaviors = new List<IBehavior>(); 
    public void AddBehavior(IBehavior behavior) 
    { 
     Behaviors.Add(behavior); 
    } 
} 

public class PaginationBehavior : IBehavior 
{ 
    public int PageSize = 10; 
    public int PageNumber = 2; 
    public IEnumerable<T> Apply<T>(IEnumerable<T> data) 
    { 
     //apply behavior here 
     return data 
      .Skip(PageNumber * PageSize) 
      .Take(PageSize); 
    } 
} 

public class MyEntity { } 

public class MyBusinessOne : MyBusiness, IBusiness 
{ 
    public IList<MyEntity> GetEntities() 
    { 
     IEnumerable<MyEntity> result = new List<MyEntity>(); 
     this.Behaviors.ForEach(rs => 
     { 
      result = rs.Apply<MyEntity>(result); 
     }); 
     return result.ToList(); 
    } 
} 

public static class Factory 
{ 
    public static T Create<T>(List<IBehavior> behaviors) where T : class 
    { 
     // returns instance based on T 
     var instance = new MyBusinessOne(); 
     behaviors.ForEach(rs => instance.AddBehavior(rs)); 
     return instance as T; 
    } 
} 

public class MyService 
{ 
    public IList<MyEntity> GetEntities(int currentPage) 
    { 
     List<IBehavior> behaviors = new List<IBehavior>() { 
      new PaginationBehavior() { PageNumber = currentPage, } 
     }; 
     return Factory.Create<IBusiness>(behaviors).GetEntities(); 
    } 
} 

如果我的實施是正確的,或者我已經過度殺死它,請專家給我建議。如果它更正了它的設計模式 - 裝飾者或訪問者。

另外我的服務返回JSON字符串。如何使用此行爲集合來序列化僅選定的屬性而不是整個實體。屬性列表來自用戶請求。 (種類選擇器)

+0

可能更好的問http://codereview.stackexchange.com/ ... –

回答

1

看起來我沒有足夠的觀點來評論你的問題。所以,我會做一些假設,因爲我不是C#專家。

假設1:看起來您首先獲取數據,然後使用行爲對象應用分頁。如果是這樣,這是一個錯誤的方法。假設有500條記錄,並且您每次抓取顯示50條記錄。而不是簡單地從數據庫獲取50條記錄,你獲取500條記錄爲10次,在它上面添加的是昂貴的過濾器。 DB更適合做C#或Java這個工作。

我不會認爲分頁是關於服務的行爲。它是表示層的行爲。您的服務應該只關心「數據粒度」。看起來你的一位客戶想要一次性提供所有數據,而其他人可能需要這些數據的一部分。

選項1:在DAO層,有兩種方法:一種用於分頁,另一種用於常規提取。根據傳入的參數決定調用哪種方法。

選項2:在服務級別創建兩個方法。一個用於一小部分數據,另一個用於整組數據。既然你說過JSON,這應該是Restful服務。然後根據傳入的URL,正確調用正確的方法。如果你使用澤西島,這應該很容易。

在服務中,可以通過簡單地公開新方法或向現有方法/功能添加新參數(僅確保這些更改向後兼容)來添加新行爲。我們真的不需要裝飾者或訪客模式。唯一的擔憂是現有的用戶不應該受到影響。