2009-11-28 59 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