繁体   English   中英

如何重构这个C#代码?

[英]How to refactor this C# code?

我正在研究遗留代码,我看到了很多像这样的代码:

public class Person
{
    public Person(PersonData data)
    {
        this.Name = data.Name;
        this.Gender = data.Gender ;
    }

    public String Name { get; private set;}
    public String Gender { get; private set;}
}

public class PersonData
{
    public String Name;
    public String Gender;
}

public static Person ReadPerson(Reader reader)
{
    PersonData data = new PersonData;
    data.Name = reader.ReadString();
    data.Gender = reader.ReadString();

    Person p = new Person(data);
    return p;
}

PersonData类用于在其构造函数中设置Person类中的私有字段。 除此之外,PersonData类引入了冗余代码,正如您所看到的,现在您在Person和PersonData类中都有Name和Sex。

在我的观点中,这种设计不能扩展:现在我有一个新的字段“Age”来阅读,我必须在两个不同的地方添加“Age”属性。

这是一个有效的设计选择(鉴于我在遗留代码中看到了很多这样的代码)?
我怎么能重构这个?

编辑:

这两个类是真实代码的简化版。 所以请原谅使用字符串而不是枚举性别。

在实际代码中,PersonData有超过10个字段,所以Person类。

在使用构造函数注入时,使用参数对象是一种有效的方法,并且您在构造函数中开始获取大量参数 - 但是当您拥有的参数较少时,这是不必要的。

这是一个建议:

public class Person
{
    public Person(string name, string sex)
    {
        _name = name;
        _sex = sex;
    }

    public string Name { get {return _name; }}
    public string Sex { get {return _sex; }}

    private readonly string _name, _sex;
}

这使得该类不可变

如果它是某种面向外部的对象(与您的情况似乎不同的数据传输对象),您可以考虑使用流畅的接口来构建它们,它不会减少类的数量,但会让您更加花哨地构造对象寻找方式以及更好地控制所需要的和可选的。

如果感兴趣,请参阅使用fluent-interface标记的帖子。 条件生成器方法链接流畅的界面

var person = PersonBuilder
  .CreatePerson()
    .Named(reader.ReadString())
    .Sex(reader.ReadString())
    .Build()

一种方法是代替

public String Name { get; private set;}
public String Sex { get; private set;}

公开PersonData类型的属性

public class Person
{
    public PersonData PersonData { get; }
}

您还可以查看从PersonData派生Person

摆脱PersonData并将Reader给构造函数:

public sealed class Person
{
    public Person(Reader reader)
    {
        this.Name = reader.ReadString();
        this.Sex = reader.ReadString();
    }

    public string Name { get; private set; }

    public string Sex { get; private set; }
}

一般来说,我会回到你正在建模的真实世界(或商业:)系统。 如果班级匹配那个世界中的某些东西,那就没关系了。 如果这个类纯粹是编程系统的一个工件而且看起来没必要,那我就把它扔掉。 使用“data”类还可以隐藏使用显式参数捕获的各种问题。 例如,当您添加“年龄”时,您将如何检测到所有案例都被发现? 如果将其添加为构造函数参数,则每个丢失的大小写都会出错。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM