我有一个可以通过几种方式创建的数据集,其中一种是通过解析一些文本,另一种是来自CSV格式,第三种方式是从数据库导入它。
目前,这是界面:
public interface IMyDataMaker
{
public MyDataSet MakeData();
}
这是文本解析器类:
public class MyDataSetTextParser : IMyDataMaker
{
private readonly string textToParse;
public MyDataSetTextParser(string text)
{
textToParse = text;
}
public MyDataSet MakeDate()
{
// parse the text and return the dataset
}
}
csv解析器离文本解析器更近,这是数据库类:
public class DbMyDataSetMaker : IMyDataMaker
{
private readonly SqlConnection connection;
public DbMyDataSetMaker(SqlConnection sqlConn)
{
connection = sqlConn;
}
public MyDataSet MakeDate()
{
// connect to the db and make the dataset
}
}
这是在这种情况下使用的正确模式吗?
答案 0 :(得分:3)
我认为这非常好。这是经典的Strategy实现。
您现在可以通过dependency injection选择真实的实现,或者创建一个方法来接收您需要的接口的一个实例。
答案 1 :(得分:2)
是的,这绝对是正确的做法。使用构造函数来分离每个子类型的连接信息,最后得到一个通用的“读取”信息。方法,正如你已经完成的那样。
答案 2 :(得分:1)
只是按照您对目标的描述,这看起来是正确的方法。它不是任何特定的设计模式,也不是很好的面向对象设计。这是一个抽象基类/接口,它描述了数据源如何以干净的方式进行第38次交互。消费类可以使用任何给定的IMyDataMaker
,而不关心底层实现或数据源。 "多态性"对它来说是对的。
答案 3 :(得分:1)
是的,正如我们的同事已经提到的那样,你的方法是正确的。不过我想在这里添加一些东西。
您可以使用抽象类来实现相同的目标。
public abstract class MyDataMaker
{
public abstract MyDataSet MakeData();
}
现在您可以继承此抽象类而不是接口。这也应该是一个正确的设计。那么问题是在哪种情况下选择哪种设计?
1如果我们使用接口选项,我们允许来自实现接口的任何地方的任何对象来加入该方。你绝对无法控制这种包含。这是一种普遍的方法。
2如果我们使用抽象选项,我们将对想要加入聚会的对象有一定程度的控制权,因为我们知道它来自哪个来源。那就是它必须继承自MyDataMaker。除此之外,如果您希望这样做,您可以执行一些内部,私有甚至公共实现的一些零碎。
当高度主观性问题需要彻底明确目标时,哪一个更合适。
是的,如果你计划允许结构加入聚会,那么抽象选项就会被淘汰,因为结构不是可继承的,所以接口是唯一的选择。