关于新功能的开闭原则

时间:2018-10-15 09:45:06

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

关于开闭原理,我有些不了解。假设您已完成以下代码:

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 个答案:

答案 0 :(得分: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,那么我认为没有任何理由遵循该原则。需求变更和代码应遵循。

答案 1 :(得分:2)

可以通过添加新的方法和字段来修改类TypeError: data type "datetime" not understood 。它是扩展扩展名。但是,如果您已经有了PlayerJump之类的方法,并且想要对其进行修改,那将违反原理。

想象一下,您的类Fight的方法为Fighter,并且只用裸手:

Fight()

例如,如果您想让public Fighter() : Player { ... public virtual void Fight() { //use bare hands } } 用棍子打架,则不应修改初始方法Fighter,而应添加另一个类似Fight()的类并在其中覆盖方法FighterWithStick : Fighter

Fight()