设计两个具有略微不同数据的类

时间:2015-11-24 21:56:58

标签: c#

假设我的第一个类有一个公共属性,它返回要导出的文件的标题。例如:

private readonly List<string> fileHeaders = new List<string>
{
    "Last Name", 
    "First Name", 
    "Middle Name", 
    "Suffix", 
    "Degree",           
};

public List<string> FileHeaders
{
    get { return fileHeaders; }
}

现在我有一个class B,它导出的文件头只有区别在于它还有一个要导出的列标题,例如一个地址列。

什么是良好的面向对象设计可以做到这一点?

3 个答案:

答案 0 :(得分:4)

使fileHeaders成为基类的受保护成员。类似的东西:

public class Base
{
    protected List<string> fileHeaders;
    public List<string> FileHeaders
    {
        get
        {
            return fileHeaders;
        }
    }
}

public class A : Base
{
    public A()
    {
        fileHeaders = new List<string>
        {"Last Name", "First Name", "Middle Name", "Suffix", "Degree"};
    }
}

public class B : Base
{
    public B()
    {
        fileHeaders = new List<string>
        {"Last Name", "First Name", "Middle Name", "Suffix", "Degree", "Something Else"};
    }
}

如果它有意义(语义上),你也可以将A作为基类,并且B继承,例如,如果它只是B的情况还有一个专栏。如下所示:

public class A
{
    protected readonly List<string> fileHeaders = new List<string>
    {
        "Last Name", "First Name", "Middle Name", "Suffix", "Degree", 
    };

    public List<string> FileHeaders
    {
        get
        {
            return fileHeaders;
        }
    }
}

public class B : A
{
    public B()
    {
        fileHeaders.Add("Something Else");
    }
}

答案 1 :(得分:2)

由于两个实例仅在数据上有所不同,为什么不创建一个具有列表作为成员和只读属性的类(如上所述)并使用构造函数中的参数初始化它?不需要不同的课程。

答案 2 :(得分:1)

I'd prefer this solution with an interface and abstract base class that enforces the implementation in derived classes.

This covers the SOLID open-closed principle

public interface IFileHeaders
{
    IList<string> GetFileHeaders();
}

public abstract class FileHeaderBase : IFileHeaders
{
    protected abstract IList<string> FileHeaders { get; }

    public IList<string> GetFileHeaders() => FileHeaders;
}

This covers a basic implementation:

public class FileHeaderList1 : FileHeaderBase
{
    private readonly IList<string> _fileHeaders = new List<string>
    {
        "Last Name" ,
        "First Name" ,
        "Middle Name" ,
        "Suffix" ,
        "Degree" ,
    };

    protected override IList<string> FileHeaders => _fileHeaders;        
}

This covers lazy loading:

public class FileHeaderList2 : FileHeaderBase
{
    private IList<string> _fileHeaders;

    protected override IList<string> FileHeaders
    {
        get
        {
            if ( _fileHeaders == null )
            {
                _fileHeaders = new List<string>
                {
                    "Address" ,
                };
            }
            return _fileHeaders;
        }
    }
}

This covers dependency injection:

public class FileHeaderList3 : FileHeaderBase
{
    private readonly IList<string> _fileHeaders;

    public FileHeaderList3( IList<string> fileHeaders )
    {
        _fileHeaders = fileHeaders;
    }

    protected override IList<string> FileHeaders => _fileHeaders;
}