我有一个使用策略模式的抽象类。
public interface IReader
{
HashSet<DataSheet> Read(string fullFilePath, HashSet<string> sheetNames, ref string errors);
}
public abstract class AbstractReader : IReader
{
public virtual HashSet<DataSheet> Read(string fullFilePath, Hashset<string> sheetNames, ref string errors)
protected virtual void InitializeRowColInfo(string filePath, string sheetName)
//And some other methods
}
该方法读取,读取excel文件并通过其参数获取所需的信息,并输出要进一步处理的信息。
要实现Abstract Reader,我创建了一个新类来覆盖它。例如,
对于遵循我的抽象类格式逻辑的文件,
public class ConcreteReader1 : AbstractStandardReader
{
}
对于不遵循抽象类格式逻辑的文件,
public class ConcreteReader2 : AbstractStandardReader
{
protected override void InitializeRowColInfo(string filePath, string sheetName)
}
在这里,我将根据文件的格式需求重写该方法,而从抽象类中重用常见的方法。对象的创建方法如下:
public IReader GetReader(string reader){
if (reader.toUpper().trim().Equals("CONCRETEREADER1"){
return new ConcreteReader1();
}
//Continue else ifs for the other readers
}
但是,由于我为所有方法都包括的参数的严格性质,每当需要一种需要其他参数的文件格式时,我都无法重用我的代码。
要解决此问题,我可以创建一个要传递的对象,例如documentInfo对象:
public class DocumentInfo
{
public string FullReadFilePath { get; set; }
public HashSet<string> SheetNames { get; set; }
public string Errors { get; set; }
}
public interface IReader
{
HashSet<DataSheet> Read(DocumentInfo documentInfo);
}
这样,可以将所需的任何其他参数添加到该对象中,而不会影响现有的具体阅读器,并且我可以摆脱引用字符串。
但是,
存在一个冗余问题,因为对DocumentInfo对象的任何新添加的属性将始终未初始化,并且对于不使用它们的读者(也使代码混乱)毫无用处。
此外,我所有其他方法都将依赖于此对象,因为它包含有关读取的所有信息(fullFilePath,sheetNames等)
是否有更好的方法来解决此问题?
答案 0 :(得分:1)
我的理解是,您正在尝试进行技术重构,而无需重新考虑对象责任(SOLID原则https://stackify.com/solid-design-principles/的S)。这导致尝试将所有内容合并为一个类。 我看到您可以通过以下方式重组类:
总而言之,我想使用以下结构
public class DocumentInfo
{
public HashSet<string> SheetNames { get; set; }
// potentially RowColInfo if it's part of your configuration
}
public interface IReader
{
HashSet<DataSheet> Read(DocumentInfo docuInfo, ref string errors);
}
public class ConcreteReader: IReader
{
public ConcreteReader(string filePath) {...};
public HashSet<DataSheet> Read(DocumentInfo docuInfo, ref string errors) {...};
}
实际上就是这样。