C# 这是否违反了打开/关闭原则?
我下午大部分时间都在阅读开放/封闭原则,但我似乎无法完全理解它。 这里有一些我已经读过的参考文章,似乎我错过了一些东西 假设我有一个基本的通用存储库,它公开了一些最通用的方法,以满足存储库中的任何需求 存储库C# 这是否违反了打开/关闭原则?,c#,oop,solid-principles,open-closed-principle,C#,Oop,Solid Principles,Open Closed Principle,我下午大部分时间都在阅读开放/封闭原则,但我似乎无法完全理解它。 这里有一些我已经读过的参考文章,似乎我错过了一些东西 假设我有一个基本的通用存储库,它公开了一些最通用的方法,以满足存储库中的任何需求 存储库 public abstract class Repository<TModel> where TModel : class { protected Repository() { } public abstract IList<TModel> F
public abstract class Repository<TModel> where TModel : class {
protected Repository() { }
public abstract IList<TModel> FilterBy(
Expression<Func<TModel, bool>> filterExpression);
public abstract IList<TModel> GetAll();
public abstract TModel GetById(int id);
public abstract Save(TModel instance);
}
public abstract class ProductRepository : Repository<Product> {
protected ProductRepository() : base() { }
}
public abstract class AlertLevelConfigurationRepository
: Repository<AlertLevelConfiguration> {
protected AlertLevelConfigurationRepository() : base() { }
public abstract AlertLevelConfiguration GetCurrent();
}
公共抽象类存储库,其中TModel:class{
受保护的存储库(){}
公共过滤器(
表达式过滤器表达式);
公共抽象IList GetAll();
公共抽象tModelGetById(intID);
公共抽象保存(TModel实例);
}
然后,我希望专门研究ProductRepository
ProductRepository
public abstract class Repository<TModel> where TModel : class {
protected Repository() { }
public abstract IList<TModel> FilterBy(
Expression<Func<TModel, bool>> filterExpression);
public abstract IList<TModel> GetAll();
public abstract TModel GetById(int id);
public abstract Save(TModel instance);
}
public abstract class ProductRepository : Repository<Product> {
protected ProductRepository() : base() { }
}
public abstract class AlertLevelConfigurationRepository
: Repository<AlertLevelConfiguration> {
protected AlertLevelConfigurationRepository() : base() { }
public abstract AlertLevelConfiguration GetCurrent();
}
公共抽象类ProductRepository:Repository{
受保护的ProductRepository():base(){}
}
假设我已经从这里的基本存储库中获得了所需的所有信息。如果是这样,那么我觉得我没有打破开放/封闭原则,因为我没有定义任何新成员或类似的东西
但是,如果我需要一种特殊的存储库,比如说AlertLevelConfigurationRepository,那么业务需求说明我一次只能有一个AlertLevelConfiguration。因此,存储库需要始终获取当前配置
AlertLevelConfigurationRepository
public abstract class Repository<TModel> where TModel : class {
protected Repository() { }
public abstract IList<TModel> FilterBy(
Expression<Func<TModel, bool>> filterExpression);
public abstract IList<TModel> GetAll();
public abstract TModel GetById(int id);
public abstract Save(TModel instance);
}
public abstract class ProductRepository : Repository<Product> {
protected ProductRepository() : base() { }
}
public abstract class AlertLevelConfigurationRepository
: Repository<AlertLevelConfiguration> {
protected AlertLevelConfigurationRepository() : base() { }
public abstract AlertLevelConfiguration GetCurrent();
}
公共抽象类AlertLevelConfigurationRepository
:存储库{
受保护的AlertLevelConfigurationRepository():base(){}
公共抽象AlertLevelConfiguration GetCurrent();
}
现在,我觉得我打破了开/闭原则,因为这个新方法,因为这个类是从它的祖先修改的派生类型。它被修改为存储库的基本定义不提供此GetCurrent
方法。此外,我很确定我永远不会使用任何基本方法,因为alter-level配置可以很好地进行配置,除了Save
方法之外
最后,我想知道我是否理解开/闭原则,不知何故我怀疑我是否理解
我想知道这是否是一个原则被破坏的例子,如果不是,那么我想得到一些关于原则本身的解释。这里的内容看起来像是“打开/关闭原则”的定义-
存储库
类可以扩展,但不能修改。您可以通过扩展新功能(以新子类的形式)来添加新功能,而无需修改Repository类。将GetCurrent()
调用添加到Alert
子类是原则的“opentoextension”部分的一部分
打开/关闭是关于打开/关闭的特定类,而不是整个继承层次结构。您只想编写一次类,并且只出于一个原因(单一责任原则)对其进行更改
你提出了一个单独的问题:
“此外,我确信我永远不会使用任何基本方法,因为alter level配置可以很好地配置,所以Save方法除外!”
这表明继承层次结构设计不当,或者选择从错误的类继承。如果您继承了很多不需要或不想使用的功能,那么它不是正确的基类,或者该类做得太多(违反了单一责任原则)
您可能希望将此功能中的某些功能(如警报类不需要的
GetAll()
和GetById()
调用)封装到单独的类中,只有需要该功能的派生类才能作为依赖项(假设您使用的是DI)。或者可能将该功能放入一个从存储库派生的类中,并使需要它的类从该类派生(不过我更喜欢组合解决方案而不是继承解决方案)。在这种情况下,您是否会为IAlertLevelConfig创建一个接口,并让AlertLevelConfigurationRepo继承存储库并实现IAlertLevelConfig?IAlertLevelConfig将为GetCurrent方法提供抽象。其他不需要此功能的repo将不会实现此IAlertLevelConfig。