我正在学习D.I. 我的架构存在一些问题,也许我遗漏了一些要点。
假设我有这个非DI代码(我从文件中读取了“人员”列表)
static void Main()
{
PersonReaderFromFile personReader = new PersonReaderFromFile("path-to-file");
Person p = personReader.GetNext(); //return a Person parsed from file line or NULL at EOF
}
class Person
{
//stuffs here
}
class PersonReaderFromFile
{
public Person GetNext()
{
Person person = new Person();
//some logic
return person;
}
}
首先,用于实施D.I.模式,我需要接口,所以我要做
static void Main()
{
iPersonReader personReader = new PersonReaderFromFile("path-to-file");
iPerson p = personReader.GetNext();
}
interface iPerson
{
}
class Person : iPerson
{
}
interface iPersonReader
{
iPerson GetNext();
}
class PersonReaderFromFile : iPersonReader
{
public iPerson GetNext()
{
Person person = new Person();
//some logic
return person;
}
}
现在我的问题是:PersonReaderFromFile取决于Person的实现。 没关系? 还是我需要一个额外的类,例如PersonFactory?
static void Main()
{
iPersonFactory factory = new PersonFactory();
iPersonReader personReader = new PersonReaderFromFile("path-to-file", factory);
iPerson person = personReader.GetNext();
}
interface iPerson
{
}
class Person : iPerson
{
}
interface iPersonReader
{
iPerson GetNext();
}
class PersonReaderFromFile : iPersonReader
{
iPersonFactory _factory;
public PersonReaderFromFile(iPersonFactory factory)
{
_factory = factory;
}
public iPerson GetNext()
{
Person person = _factory.CreateNewPerson();
//some logic
return person;
}
}
interface iPersonFactory
{
iPerson CreateNewPerson();
}
class PersonFactory : iPersonFactory
{
iPerson CreateNewPerson()
{
Person person = new Person();
return person;
}
}
现在PersonFactory取决于Person实现,但是应该正确。 有什么建议吗? 向所有人发送Tnx。
编辑: 我展示了一个示例PersonReaderFromFile实现
class PersonReaderFromFile
{
StreamReader _fileReader;
public PersonReaderFromFile(string path)
{
_fileReader = new StreamReader(file);
}
public Person GetNext()
{
string line = _fileReader.ReadLine();
if (line == null)
{
_fileReader.Close();
return null;
}
string name, lastName, email;
ParseInformationFromLine(line, out name, out lastName, out email);
Person p = new Person { Name = name, LastName = lastName, Email = email };
return p;
}
private ParseInformationFromLine(string line, out string name, out string lastName, out string email)
{
//I don't think that matters
}
}
答案 0 :(得分:1)
PersonReaderFromFile
不依赖于Person
。该类似乎只是表示运行时数据的POCO。
PersonReaderFromFile
依赖于StreamReader
和ParseInformationFromLine
函数
首先将这些实现细节抽象为他们自己关心的问题。
public interface IReadLines {
string ReadLine();
}
public interface IParsePersonInformationFromLine {
void ParseInformationFromLine(string line, out string name, out string lastName, out string email);
}
目标类将明确依赖抽象
public class PersonReaderFromFile {
private readonly IReadLines reader;
private readonly IParsePersonInformationFromLine parser;
public PersonReaderFromFile(IReadLines reader, IParsePersonInformationFromLine parser) {
this.reader = reader;
this.parser = parser;
}
public Person GetNext() {
string line = reader.ReadLine();
if (line == null) {
return null;
}
string name, lastName, email;
parser.ParseInformationFromLine(line, out name, out lastName, out email);
Person p = new Person { Name = name, LastName = lastName, Email = email };
return p;
}
}
各个抽象将具有自己的实现,以满足在运行时使用的所需功能。例如,读者在内部仍将使用StreamReader
来获取行。 PersonReaderFromFile
不需要了解有关如何检索行的任何信息。只是它在被调用时需要一条线。
Main
现在可以重构为例如使用Pure DI
static void Main() {
IReadLines reader = new ReadLinesImplementation("path-to-file");
IParsePersonInformationFromLine parser = new ParsePersonInformationFromLine();
PersonReaderFromFile personReader = new PersonReaderFromFile(reader, parser);
Person p = personReader.GetNext(); //return a Person parsed from file line or NULL at EOF
}
还有其他可应用的重构,但这仅是标识实现细节的简化示例,应从与实现问题紧密相关的代码中抽象出这些细节。