Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这是否违反了打开/关闭原则?_C#_Oop_Solid Principles_Open Closed Principle - Fatal编程技术网

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。