设计接口/基类:无需强制转换访问基类列表的SOLID方案
问题与解决方案
初始测试代码
using System.Text; namespace Lib1; public class WriteOnlySqlFile : BaseFile, IWriteOnlySqlFile { public string SaveText() { Console.WriteLine("{0}, {1}, save text sql file", FilePath, FileText); return ""; } } public class ReadOnlySqlFile : BaseFile, IReadOnlySqlFile { public string LoadText() { Console.WriteLine("{0} {1}, readonly sql file loading text here!", FilePath, FileText); return ""; } } public interface IReadOnlySqlFile { public string LoadText(); } public interface IWriteOnlySqlFile { public string SaveText(); } public abstract class BaseFile { public string FilePath { get; init; } = string.Empty; public string FileText { get; init; } = string.Empty; } public static class SqlFileManager { public static string GetTextFromFiles(List<IReadOnlySqlFile> readOnlySqlFiles) { StringBuilder objStrBuilder = new StringBuilder(); foreach (var objFile in readOnlySqlFiles) { objStrBuilder.Append(objFile.LoadText()); } return objStrBuilder.ToString(); } public static void SaveTextIntoFiles(List<IWriteOnlySqlFile> writeOnlySqlFiles) { foreach (var objFile in writeOnlySqlFiles) { objFile.SaveText(); } } }
需求与问题
需要将SqlFileManager改为非静态类,使其持有BaseFile类型的实例集合,遍历集合时避免强制类型转换,以符合SOLID原则的方式调用对应读写方法。当前尝试的代码依赖具体类的类型转换,不符合面向抽象的设计原则。
符合SOLID的解决方案
利用面向接口编程和LINQ的OfType<T>方法,筛选出实现对应接口的实例,直接调用接口方法,无需转换具体类:
using System.Text; using System.Linq; namespace Lib1; // WriteOnlySqlFile、ReadOnlySqlFile、相关接口、BaseFile 保持原有代码不变 public class SqlFileManager { private readonly List<BaseFile> _sqlFiles; public SqlFileManager(List<BaseFile> files) { _sqlFiles = files ?? throw new ArgumentNullException(nameof(files)); } public string GetTextFromFiles() { StringBuilder strBuilder = new StringBuilder(); // 筛选实现IReadOnlySqlFile的实例,直接调用接口方法 foreach (var readOnlyFile in _sqlFiles.OfType<IReadOnlySqlFile>()) { strBuilder.Append(readOnlyFile.LoadText()); } return strBuilder.ToString(); } public void SaveTextIntoFiles() { // 同理筛选实现IWriteOnlySqlFile的实例 foreach (var writeOnlyFile in _sqlFiles.OfType<IWriteOnlySqlFile>()) { writeOnlyFile.SaveText(); } } }
方案优势
- 依赖倒置原则:依赖抽象接口而非具体实现类,后续新增如
ReadWriteSqlFile这类同时实现两个接口的类时,无需修改SqlFileManager的代码 - 无强制转换:通过
OfType<T>安全筛选符合条件的实例,避免类型转换带来的空引用或类型转换异常 - 单一职责原则:
SqlFileManager只负责协调文件的读写调度,具体读写逻辑由各自的文件类实现,职责清晰
内容的提问来源于stack exchange,提问作者razlani
相关产品推荐
相关产品推荐

