【问题标题】:Open-Close principle about new features关于新功能的开闭原则
【发布时间】:2018-10-15 09:45:06
【问题描述】:

关于开闭原则,我有些不明白。假设你已经完成了这段代码:

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

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

这段代码运行良好,您已经完成了第一个版本,一切正常。
现在您想添加一些功能,例如玩家可以装备戒指。开闭原则说对扩展开放,对修改开放。如果我不应该修改这些类,我如何实现我的玩家可以拥有戒指这一事实?

【问题讨论】:

  • 你可以考虑阅读this nice answer
  • 这是一个扩展而不是修改,您正在扩展播放器类以拥有一个默认情况下将由每个孩子继承的环。例如,修改是添加一个抽象方法,该方法应由每个子实现,这是一个修改。

标签: c# solid-principles open-closed-principle


【解决方案1】:

可以通过添加新方法和字段来修改类Player。它对扩展开放。但是如果你已经有了JumpFight 之类的方法,并且你想修改它们——那就违反了原则。

想象一下,你的班级 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,那么我认为没有任何理由遵循这一原则。需求变化和代码应该遵循。

    【讨论】:

      猜你喜欢
      • 2018-04-09
      • 2021-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 1970-01-01
      • 2010-09-13
      • 1970-01-01
      相关资源
      最近更新 更多