c# - 关于新功能的开闭原则
问题描述
关于开闭原则,我有一些不明白的地方。假设您已经完成了以下代码:
public abstract class Player
{
public string Name { get; set; }
public int Level { get; set; }
}
public sealed class Fighter : Player { /* ... */ }
public sealed class Warrior : Player { /* ... */ }
这段代码运行良好,你已经完成了第一个版本,一切都很好。
现在您想添加一些功能,例如玩家可以装备戒指。开闭原则说对扩展开放,对修改开放。如果我不应该修改这些类,我怎么能实现我的玩家可以拥有戒指的事实?
解决方案
首先想想为什么这种规则可能有用。对修改关闭,对扩展开放。这对于必须向后兼容的库或代码是有意义的。想想这个例子:
我编写了公开接口的“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,那么我认为没有任何理由遵循这一原则。需求变化和代码应该遵循。
推荐阅读
- matplotlib - 基于值的Python散点图颜色
- c# - C# 在异步 ForEach 循环中写入数据库
- python - bot.wait_for_reaction () 使用自定义表情符号进行多重反应
- pixi.js - Pixi.js。如何在不改变其本地位置的情况下将孩子添加到父母
- bash - 使用 bash 打开套接字以查看输出
- matlab - 如何通过精确移动一行和一列从大型矩阵创建所有可能的子矩阵
- javascript - 使用 OBJ 文件旋转的 JavaScript 360
- python - 如何合并每个都是字符串列表的行..不包括重复项
- string - FSharp F# 中的字符串编辑问题
- jenkins - 如何将 Jenkins DSL 管道命令设置为 groovy 中的变量?