2009-11-28 55 views
1

和感謝的任何援助C#設計模式:通用方法?

爲:

public abstract class EntityBase 
{  
protected void Create(EntityBase c)  
{   
    Log.Audit(c); 
} 
} 

public class Customer : EntityBase 
{  
public void CreateCustomer(Customer c)  
{   
    Create(c);  
}  
} 
} 

public class Car : EntityBase 
{  
public void CreateCar(Car c)  
{   
    Create(c);  
}  
} 
} 

對於上面的例子 1)你將如何實現對方法簽名: Log.Audit(C);

2)在審計(c)方法中,我們需要將c轉換爲適當的類型,並遍歷整個對象的屬性以進行審計。這將如何完成。我正在考慮類似......

public Audit(T t) 
{ 
switch (t.GetType()) 
{ 
case Customer: 
    //Audit Customer 
    Audit(<Customer> t); 
    break; 
case Car: 
    //Audit Car 
    Audit(<Car> t); 
} 
} 

只是一個猜測,任何幫助將是偉大的。

注意:如果您可以想到更好的架構此方法的方法,請告訴我。

再次感謝。 Steven

回答

3

我在做審計時幾乎總是使用反射。如果您有屬性具有可區分它們的屬性(如ColumnAttribute),則可以使用這些屬性來查找要審覈的屬性。您可以隨時創建要使用的屬性並應用它。然而,最簡單的事情就是審覈班級的公共財產。

public void Audit(T t) 
{ 
    foreach (var property in t.GetType().GetProperties()) 
    { 
     var value = property.GetValue(t,null); 
     ...do something with property.Name and value... 
    } 
} 

您可以瞭解我如何使用LINQ to SQL在http://farm-fresh-code.blogspot.com/2009/05/auditing-inserts-and-updates-using-linq.html

5

在一個方法中,當你有開關或if/else結構來決定如何分配方法時,這是一個你沒有使用多態性的跡象。

一種解決方案是使審計()EntityBase的虛方法,並有審覈調用它的實例(所以你覆蓋客戶或租車審計)

可以作爲獎金提供使用默認的實現反射,通過繼承類的每個屬性來轉儲它。

public abstract class EntityBase 
{  
    protected void Create(EntityBase c)  
    {   
     Audit(c); 
    } 

    public virtual void Audit() 
    { 
    //Default audit code here, using reflection for instance 
    }  
} 

public class Car : EntityBase 
{ 
    //Does not override, uses default Audit Code 
} 

public class Hamster : EntityBase 
{ 
    public override void Audit() 
    { 
     //Specific code here.. 
    } 
} 

如果你不希望有實體類或其繼承人的一個內部審計責任,你必須去思考的方式。

0

我會建議基類應該永遠不會知道有關耙類的任何內容。在這種情況下:如果添加另一個耙類,則還需要每次更改基類。因此,Yann Schwartz的建議比您的方法更好。

問題可能是客戶/汽車/ ...邏輯與autdit功能的緊密結合(請參閱single responsiblity principle)。這可能是對反思的一種補充(正如上面已經提到的那樣,即使它可能會更慢),但如果你想爲所有目的實施一個共同的方法,這可能變得非常複雜。將問題委託給您可以使用的單獨部分(例如可插入的插件aspect oriented programming)是一種更好的做法。幾個框架已經支持這個問題。

如果你想「外包」你的開關盒問題,你可以使用strategy pattern。 你可以找到我經常在c#中使用的例子,沒有特殊的框架here