2008-10-20 76 views
8

我有一個流暢的接口問題。C#中的流暢接口

我們有作爲參數對象的SQL接口的一些對象,這裏有一個例子:

using (DatabaseCommand cmd = conn.CreateCommand(
    "SELECT A, B, C FROM tablename WHERE ID = :ID", 
    SqlParameter.Int32(":ID", 1234))) 
{ 
    ... 
} 

對於一些參數,我想使一些專門的選項,而是中加Int32方法的更多屬性(這只是其中的一個),我認爲我會研究流暢的接口。

此處,我已經添加了什麼,我尋找到一個例子:

SqlParameter.Int32(":ID", 1234).With(SqlParameterOption 
    .Substitute 
    .Precision(15) 
) 

我知道這兩個選項就沒有意義了這種類型的參數,但是這並不是問題是什麼。

在上面的例子中,Substitute必須是SqlParameterOption類的靜態屬性(或方法,如果我只是添加一些括號),而Precision將不得不是一個實例方法。

如果我重新排列它們,該怎麼辦?

SqlParameter.Int32(":ID", 1234).With(SqlParameterOption 
    .Precision(15) 
    .Substitute 
) 

然後替代將必須是實例屬性和精度靜態方法。這當然不會編譯,我不能同時使用靜態和非靜態屬性或方法。

我該怎麼做?我完全在錯誤的軌道上嗎?

重讀這個問題時,我有一個想法,下面的這個不同的語法會更有意義嗎?

SqlParameter.Int32(":ID", 1234).With 
    .Precision(15) 
    .Substitute 

在這種情況下,任何方式都將是實例方法隨着返回,這將是一個專門的類或SqlParameter選項這樣的接口。我不確定我想傾倒。與部分,因爲這會暴露對象的所有方法,而不僅僅是流利的

建議和一些好的網址的將是最受歡迎的,我已經沖刷了很多例子,但他們往往會表現出這樣的例子:

order 
    .AddFreeShipping() 
    .IncludeItem(15) 
     .SuppressTax(); 

(從this page解除)


編輯:回覆後的跟進 來自@marxidad

class SqlParameterOption 
{ 
    public SqlParameterOption Precision(int p) {/* ... */; return this;} 
    public SqlParameterOption Substitute() {/* ... */; return this;} 
    /* ... */  
} 

/* ... */ 
SqlParameter.Int32(":ID", 1234).With(new SqlParameterOption() 
              .Precision(15) 
              .Substitute()); 

用這種方法,將不得不採取該對象,並將其應用於參數。我很好。

如果我用我說作爲一個例子語法,這將是這樣的:

SqlParameter.Int32(":ID", 1234).With 
           .Precision(15) 
           .Substitute()); 

在這種情況下,不知道什麼時候結束的鏈條,所以每個選項就必須運用其直接影響。

什麼是首選?這些選項是否會構建一個效果對象,以後再應用,或者每個效果都直接應用其效果?

決定: 作爲@marxidad說,如果改變是不可逆的,可能是受到了逆轉,建立國家和在某些時候有一個例外,就是失敗,我會走的路。

但是,在這種情況下,我將使用一種更簡單的方法直接修改SqlParameter對象。

在這種情況下,我的代碼如下所示:

SqlParameter.Int32(":ID", 1234).With 
           .Precision(15) 
           .Substitute()); 

編輯:爾加,這是怎麼一回事呢,當我專注於一兩件事。

我不能使用的語法,我會用下面去,作爲建議的@marxidad

SqlParameter.Int32(":ID", 1234).With(new SqlParameterOption() 
              .Precision(15) 
              .Substitute()); 

的原因當然是該採取的SqlParameter對象作爲參數的方法是不能的來處理由With返回的對象,因此雖然SqlParameter對象的構造和設置正確,但它與預期用法不兼容。

回答

8

SqlParameterOption's方法都可以實例方法返回相同的對象:

class SqlParameterOption 
{ 
    public SqlParameterOption Precision(int p) {/* ... */; return this;} 
    public SqlParameterOption Substitute() {/* ... */; return this;} 
    /* ... */  
} 

/* ... */ 
SqlParameter.Int32(":ID", 1234).With(new SqlParameterOption() 
              .Precision(15) 
              .Substitute()); 

回覆:建立國家要對直接與每個呼叫應用後應用,如果沒有真正的irreverisible副作用在任何一種情況下都會產生影響,那麼這並不重要,並且取決於您的個人喜好。如果選項是針對每個方法調用進行的,並且有可能需要撤銷該選項,那麼您可能需要先建立狀態並應用它。如果參數對象在您應用它們時爲您進行屬性驗證,那麼使用直接應用程序可能會更好,因此您將獲得正確的驗證反饋。

1

雖然您可以重載方法。例如,如果它是Substitute()。你通常不能同時擁有方法的靜態和實例版本,但是擴展方法可能有些用處......但是如果兩個版本的替代品具有不同的含義,那麼簡單地返回不同的類型會更清晰,所以Substitute()的兩個變體不能衝突。

+0

在這種情況下,關於意義不會有任何衝突,問題更多的是關於如何組織代碼來獲得我想要的,語法上的。新增選項對象的實例解決了這個問題,如marxidad所示。 – 2008-10-20 11:36:41