首页 文章

关于新功能的开放式原则

提问于
浏览
1

关于开闭原则我有些不明白 . 假设您已完成此代码:

public abstract class Player
{
    public string Name { get; set; }
    public int Level { get; set; }
}

public sealed class Fighter : Player { /* ... */ }
public sealed class Warrior : Player { /* ... */ }

这段代码完美无缺,你已经完成了第一次发布,输入就行了 .
现在你要添加一些功能,比如玩家可以装备戒指 . 开放原则表示开放延伸,接近修改 . 如果我不修改这些课程,我怎么能实现我的球员可以有戒指的事实呢?

2 回答

  • 2

    您可以通过添加新方法和字段来修改类 Player . 它是开放的延伸 . 但是,如果您已经有一些方法,如 JumpFight ,并且您想修改它们 - 那就违反了原则 .

    想象一下,你的 class Fighter 有方法 Fight() 并且它只使用裸手:

    public Fighter() : Player
    {
      ...
      public virtual void Fight()
      {
        //use bare hands
      }
    }
    

    如果你想 Fighter 用棍子打架(例如)你不应该修改初始方法 Fight() 但是添加另一个类如 FighterWithStick : Fighter 并覆盖方法 Fight() 那里:

    public FighterWithStick() : Fighter
    {
      ...
      public override void Fight()
      {
        //use stick
      }
    }
    
  • 2

    首先想一想为什么这种规则可能有用 . 关闭修改,开放扩展 . 这对于必须向后兼容的库或代码是有意义的 . 想想这个例子:

    我写了“BestLibrary”库,它公开了界面:

    namespace BestLibrary
    {
        public interface GoodStuff
        {
             Goodies GiveMeGoodStuff();
        }
    }
    

    但在下一个版本中,我想根据参数决定 Goodies 给出什么,所以我将界面更改为:

    namespace BestLibrary
    {
        public interface GoodStuff
        {
             Goodies GiveMeGoodStuff(GoodiesType type);
        }
    }
    public enum GoodiesType { All, Type1, Type2 }
    

    现在,使用我的库的每个人都必须修复他们的代码,因为他们的项目将停止构建 . 这制动开/关原理 . 相反,我应该制作另一种方法,如下所示:

    namespace BestLibrary
    {
        public interface GoodStuff
        {
             Goodies GiveMeGoodStuff();
             Goodies GiveMeGoodStuff(GoodiesType type);
        }
    }
    

    在这里,我没有修改任何东西 . 旧代码仍然有效 . 有人想随机 Goodies ?他们仍然可以得到它 . 我用其他方法扩展了 GoodStuff 接口 . 这样一切都可以编译,人们可以使用新功能 .

    如果您处理的项目不是库或api,那么我认为没有理由遵循这一原则 . 需求变更和代码应遵循 .

相关问题