2009-02-01 56 views
2

这可能是显示通过我的幼稚,但无论如何...通用接口作为方法参数,看到领域

我有一个通用的接口,它定义了一组不同实现标准方法(不同的方式实现)。

我将接口作为参数传递给方法,该方法负责持久化数据库。例如。我有一些实现称为bug,事件等,从通用接口(称为IEntry)定义。这些concerete实现也使用IEnumerable

因为错误是不同的事件,有不同的领域。当我将接口作为参数传递给方法时,有什么方法可以推断这种类型吗?所以如果我传入Bug对象,我可以使用它的字段,这些字段与事件中的字段不同。这些字段对于数据库的持久性很有用。我假设没有,因为没有办法知道通过什么类型(显然),但我知道这里的人有更多的智慧。在那种情况下,是否有更好的做事方式?由于相似性,我想坚持接口。

编辑:我想另一种方法是利用一些流量控制来生成在运行中的SQL语句,然后作为参数传递它。

感谢

回答

3

约四周传递对象和接口的事情是,你真的不应该与实际类型而言,只要它继承/实现了特定的基类/接口你有兴趣

因此,将逻辑构建到该方法中以发现它是一个错误,然后访问仅存在于错误中的东西,这基本上不是OOP方式,尽管它可能是您的特例中的“最佳”方式。但是,我会,但是,建议反对它,而是尝试建立一个适当的OOP与多态性的方式来处理差异,而不是作为特殊情况构建到方法。

你提到持久性,这种方法负责存储数据的地方?也许你可以将收集信息的部分从存储信息的部分中分离出来,这样你可以要求对象本身为你提供所有相关的信息,这些信息可能因类而异。

0

持久性事件只是一个方法在一个类中上传细节到数据库。

我想我可以写一个抽象类与持久性要求的功能,并可能基于它的参数工作。我可以在我的每个接口实现中使用它。因为更新数据库的方式将会发生(几乎相同,但sql查询中的几个字改变),所以我可以根据方法参数生成它。

3

糟糕的设计(我认为在这个问题被描述):

public interface IEntry 
{ 
    string Description { get; set; } 
} 
public class Bug : IEntry 
{ 
    public int ID { get; set; } 
    public string Description { get; set; } 
    public string UserName { get; set; } 
} 
public class Incident : IEntry 
{ 
    public Guid ID { get; set; } 
    public string Description { get; set; } 
} 

public class Persister 
{ 
    public void Save(IEnumerable<IEntry> values) 
    { 
     foreach (IEntry value in values) { Save(value); } 
    } 

    public void Save(IEntry value) 
    { 
     if (value is Bug) { /* Bug save logic */ } 
     else if (value is Incident) { /* Incident save logic */ } 
    } 
} 

改进设计(智能实体法):

public interface IEntry 
{ 
    string Description { get; set; } 
    void Save(IPersister gateway); 
} 

public class Bug : IEntry 
{ 
    public int ID { get; set; } 
    public string Description { get; set; } 
    public string UserName { get; set; } 

    public void Save(IPersister gateway) 
    { 
     gateway.SaveBug(this); 
    } 
} 

public class Incident : IEntry 
{ 
    public Guid ID { get; set; } 
    public string Description { get; set; } 

    public void Save(IPersister gateway) 
    { 
     gateway.SaveIncident(this); 
    } 
} 

public interface IPersister 
{ 
    void SaveBug(Bug value); 
    void SaveIncident(Incident value); 
} 

public class Persister : IPersister 
{ 
    public void Save(IEnumerable<IEntry> values) 
    { 
     foreach (IEntry value in values) { Save(value); } 
    } 

    public void Save(IEntry value) 
    { 
     value.Save(this); 
    } 

    public void SaveBug(Bug value) 
    { 
     // Bug save logic 
    } 

    public void SaveIncident(Incident value) 
    { 
     // Incident save logic 
    } 
} 

改进的设计只为迎合需要转移需要更改Persister.Save(IEntry)。我只是想演示让代码更脆弱的第一步。在现实和生产代码中,您希望拥有BugPersister和IncidentPersister类,以符合Single Responsibility principle

希望这个更以代码为中心的例子是一个帮助。