c# - 将包含数据的大对象传递到接口中
问题描述
语境
我有一个使用策略模式的抽象类。
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文件并通过其参数获取所需信息并输出信息以进行进一步处理。
战略
为了实现抽象阅读器,我创建了一个覆盖它的新类。例如,
对于遵循我的抽象类的格式化逻辑的文件,
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);
}
这样,任何需要的额外参数都可以添加到这个对象中,而不会影响现有的具体阅读器,我可以摆脱 ref 字符串。
然而,
存在冗余问题,因为任何新添加到 DocumentInfo 对象的属性将始终未初始化并且对于不使用它们的阅读器无用(并且还会使代码混乱)。
此外,我所有的其他方法都将依赖于这个对象,因为它包含有关读取的所有信息(fullFilePath、sheetNames 等)
有没有更好的方法来解决这个问题?
解决方案
我的理解是,您正在尝试在不重新考虑对象责任的情况下进行技术重构(S of SOLID 原则https://stackify.com/solid-design-principles/)。这导致试图将所有内容组合到一个类中。我看到您可以通过以下方式重组类:
- DocumentInfo - 描述文档结构的数据对象(如果它是策略的一部分,则可能包括 RowColInfo)
- IReader - 阅读界面
- 错误 - 错误类(可以保留数组或创建单独的类)
- InitializeRowColInfo - 不确定你是否需要它,这看起来像是特定阅读器实现的一部分
- AbstractReader - 你真的需要它吗?重新考虑将技术方法保留在不同的地方/班级
- 获取特定的阅读器实现超出了阅读器范围(如果您愿意,请保持相同)
总结一下,我想使用下面的结构
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) {...};
}
实际上,就是这样。
推荐阅读
- wpf - 排序插入符号不显示
- flutter - 如何在颤振中模拟数据库
- javascript - Google App Script - 无法使用 API 中的数据设置值
- beanshell - 如何在 beanshell 中捕获异常?
- bazel - bazel build - 如何获取临时目录的名称
- pyspark - INVALID_ARGUMENT:请求失败:不支持通配符表
- javascript - 如何获取具有 [] 等奇怪字符的嵌套对象的属性?
- excel - 日期相同时从列表中组合名称缩写
- selenium - 使用 javascript selenium webdriver,我如何在测试期间获取 DOM 的 HTML?
- python - 在python中输入错误字符后我想返回“输入”