我对Object Oriented design了解一点,但我不确定如何在我的代码中使用这些原则。这就是我正在做的事情:
public void Query(Agency agency, Citation queryCitation) {
queryCitation.AgencyCode = agency.AgencyCode;
switch (agency.ClientDb.Type) {
case "SQL":
QueryOracle(agency, queryCitation);
break;
case "PIC":
QueryPick(agency, queryCitation);
break;
}
}
(其中大部分是来自NHibernate的对象。我正在使用遗留数据库系统并将其部分重构为代码库。)显然,我可以在这里做一些不同的事情,这样我就不需要重复的功能了对于具有相同输入的不同数据库查询。它应该根据代理对象知道是使用Oracle数据库还是选择数据库连接。 (如果你从未听说过Pick数据库,那么直到我开始在这里工作之前我都没有。我们通过HTTP请求对它进行查询,所以它不是SQL。)
我应该创建一个接口,例如名为“ClientDbConnection”,然后创建两个实现该接口的类,移动代码以查询数据库,然后使用“agency.clientDb.Query(queryCitation)”替换这整个功能?我想我在这里大声思考,但对此的任何意见都将不胜感激。
答案 0 :(得分:12)
代理商是您控制的一个类吗?如果是这样的话:
public abstract class GenericDb
{
public abstract void Query(parms);
}
在您的代理机构类中,您可以
public GenericDb ClientDb {get; set;}
然后有一个SqlDb类,如:
public class SqlDb : GenericDb
{
public void Query(parms);
}
public class PicDb : GenericDb
{
public void Query(parms);
}
然后这段代码:
public void Query(Agency agency, Citation queryCitation) {
queryCitation.AgencyCode = agency.AgencyCode;
switch (agency.ClientDb.Type) {
case "SQL":
QueryOracle(agency, queryCitation);
break;
case "PIC":
QueryPick(agency, queryCitation);
break;
}
}
变为
public void Query(Agency agency, Citation queryCitation) {
queryCitation.AgencyCode = agency.AgencyCode;
agency.ClientDb.Query(queryCitation);
}
由于继承,它将知道ClientDb具有GenericDb的基类。它将通过ClientDb参数的类型知道它是应该运行SqlDb还是PicDb或Oracle等。
答案 1 :(得分:5)
您可能希望在此处实施策略模式。基本上,switch语句中的每个可能的“类型”都将成为它自己的一个实现相同接口的类。
然后,您可以使用以“type”值作为参数的工厂方法。该方法将返回正确的类(其返回类型是上面提到的接口)。
答案 2 :(得分:3)
我会重构利用界面。我可能会这样做:
public interface IQuery
{
void Execute(Agency agency, Citation query);
}
public class OracleQuery : IQuery
{
// Implementation
}
public class PickQuery : IQuery
{
// Implementation
}
然后,您可以更改Agency类以存储IQuery
对象的实例,而不是(或除了)ClientDb
对象之外:
public class Agency
{
public IQuery Query { get; set; }
}
然后在初始化代码中(通常设置ClientDb
属性),可以将实例设置为适当的IQuery
实现:
agency.Query = new PickQuery();
答案 3 :(得分:2)
ADO.NET有一组通用类:DbCommand,DbConnection等......它们还实现了另一组通用接口:IDbCommand,IDbConnection等......
所以你可以使用它们,但它最终可能会变得非常复杂。您的解决方案的优势在于它非常易读。另外,pick数据库可能没有任何ADO.NET提供程序......
PS:我会替换Type属性类型,而是使用枚举。
答案 4 :(得分:2)
要编写更少的代码但提高可读性,可以使用每个数据库的委托切换到字典的声明代码级别。这很容易扩展,并且非常易读。考虑到更多功能性方法,您可以获得类似
的内容void Query(Agency agency, Citation queryCitation)
{
Dictionary<string, Action<Agency, Citation>> QueryMap = new Dictionary<string, Action<Agency, Citation>>
{
{ "SQL", QueryOracle},
{ "PIC", QueryPic}
};
queryCitation.AgencyCode = agency.AgencyCode;
QueryMap[agency.ClientDb.Type](agency, queryCitation);
}
答案 5 :(得分:0)
有两个OOP解决方案polymorphism 和Visitor pattern。