Lew*_*rin 26 c# dependency-management solid-principles
我正在研究SOLID原则,并且有关于接口的依赖关系管理的问题.
我正在阅读的书中的一个例子(Gary McLean Hall的C#自适应代码)显示了一个TradeProcessor类,它将获取交易数据,处理它并将其存储在数据库中.交易数据由一个名为的类建模TradeRecord.甲TradeParser类将处理转换所接收到的交易数据TradeRecord例如(一个或多个).本TradeProcessor类只引用了ITradeParser这样它不依赖于接口TradeParser的实现.
作者使用该Parse方法(在ITradeParser界面中)返回一个IEnumerable<TradeRecord>包含已处理交易数据的集合.这ITradeParser是不是意味着现在依赖于TradeRecord班级?
作者不应该做一些像创建ITradeRecord接口并Parse返回ITradeRecord实例集合的东西吗?还是我错过了重要的事情?
这是代码(执行TradeRecord是无关紧要的,因此省略):
TradeProcessor.cs
public class TradeProcessor
{
private readonly ITradeParser tradeParser;
public TradeProcessor(ITradeParser tradeParser)
{
this.tradeParser = tradeParser;
}
public void ProcessTrades()
{
IEnumerable<string> tradeData = "Simulated trade data..."
var trades = tradeParser.Parse(tradeData);
// Do something with the parsed data...
}
}
Run Code Online (Sandbox Code Playgroud)
ITradeParser.cs
public interface ITradeParser
{
IEnumerable<TradeRecord> Parse(IEnumerable<string> tradeData);
}
Run Code Online (Sandbox Code Playgroud)
Avn*_*tan 43
这是一个很好的问题,涉及纯度和实用性之间的权衡.
是的,通过纯委托,你可以说ITradeParser.Parse应该返回一个ITraceRecord接口集合.毕竟,为什么要将自己与特定的实现联系起来?
但是,你可以进一步.你应该接受IEnumerable<string>吗?或者你应该有某种ITextContainer?I32bitNumeric而不是int?当然,这是简单的荒谬,但它表明我们总是在某个时刻达到我们正在处理某个事物的点,一个具体的对象(数字,字符串,TraceRecord,等等),而不是抽象.
这也提出了我们首先使用接口的原因,即定义逻辑和功能的契约.An ITradeProcessor是可以替换或更新的未知实现的合同.一个TradeRecord不执行合同,这是落实.如果它是一个DTO对象,它似乎是,接口和实现之间没有区别,这意味着定义这个合同没有真正的目的 - 它隐含在具体的类中.
Jon*_*lis 10
作者使用Parse方法(在ITradeParser接口中)返回一个IEnumerable集合,该集合保存已处理的贸易数据.
这是不是意味着ITradeParser现在依赖于TradeRecord类?
是的,ITradeParser现在紧紧联系在一起TradeRecord.鉴于这个问题的学术方法越来越多,我可以看到你来自哪里.但是什么TradeRecord呢?根据定义,记录通常是简单的,非智能的数据(有时称为POCO,DTO或模型).
在某些时候,抽象的潜在收益比其引起的复杂性更有价值.这种方法在实践中非常普遍 - 模型(我称之为模型)是流经应用程序层的密封类型.作用于模型的图层被抽象为接口,因此可以单独模拟和测试每个图层.
例如,客户端应用程序可能具有View,ViewModel和Repository层.每个层都知道如何使用具体记录类型.但ViewModel可以连接到一个模拟的IRepository,它使用硬编码的模拟数据构建具体类型.此时抽象的IModel没有任何好处 - 它只有简单的数据.