2

我正在研究 DI 我在架构上有一些问题,也许我遗漏了一些要点。

假设我有这个非 DI 代码(我从文件中读取了“Person”列表)

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;
    }
}

首先,为了实现 DI 模式,我需要接口,所以我这样做了

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
   }
}
4

1 回答 1

1

PersonReaderFromFile不依赖于Person。该类似乎只是一个代表运行时数据的 POCO。

PersonReaderFromFile依赖StreamReaderParseInformationFromLine函数

首先将这些实现细节抽象为他们自己的关注点。

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;
    }
}

各个抽象将有自己的实现来满足在运行时使用的所需功能。例如,阅读器内部仍会使用 aStreamReader来获取行。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
}

可以应用进一步的重构,但这只是识别实现细节的简化示例,应该从与实现关注点紧密耦合的代码中抽象出来。

于 2020-03-30T15:46:04.623 回答