Oop 糟糕的面向对象设计有哪些迹象?
当设计一个新的系统或让你的头脑围绕其他人的代码时,在设计阶段出现了什么问题?在类图和继承层次结构上,甚至是在代码本身中,有没有什么线索需要寻找,特别是在项目的早期,需要进行彻底的设计检查?我不喜欢看到的一件事是基类将自己向下转换为派生类。当你看到这一点,你知道你有问题 其他例子可能是:Oop 糟糕的面向对象设计有哪些迹象?,oop,Oop,当设计一个新的系统或让你的头脑围绕其他人的代码时,在设计阶段出现了什么问题?在类图和继承层次结构上,甚至是在代码本身中,有没有什么线索需要寻找,特别是在项目的早期,需要进行彻底的设计检查?我不喜欢看到的一件事是基类将自己向下转换为派生类。当你看到这一点,你知道你有问题 其他例子可能是: 过度使用switch语句 重写一切的派生类 以下是一些: 循环依赖 您使用的基类属性XYZ未受保护/私有 您希望您的语言支持多重继承 对我来说最突出的东西是“” 大多数情况下,我对违背“良好实践”的事情很敏感
- 过度使用switch语句
- 重写一切的派生类
- 循环依赖
- 您使用的基类属性XYZ未受保护/私有
- 您希望您的语言支持多重继承
- 方法所做的事情与您从名称中所想的不同(例如:FileExists()以静默方式删除零字节文件)
- 一些非常长的方法(过程周围的对象包装符号)
- 在同一枚举成员上重复使用switch/case语句(需要提取的子类的符号)
- 大量用于处理而不是捕获状态的成员变量(可能表示需要提取方法对象)
- 一个有很多责任的类(违反了单一责任原则)
- 成员访问的长链(this.that很好,this.that.theOther很好,但是my.very.Long.chain.of.member.accesss.for.a.result很脆弱)
- 类的命名不当
- 在小空间中使用过多的设计模式
- 工作过度(重写框架中或同一项目中其他地方已经存在的函数)
- 拼写(任何地方)和语法(评论中)不好,或者评论只是误导
- 打破单一规则的类 责任原则(SRP)和 执行太多操作
- 太多的继承而不是 作文,即 从子类型派生纯粹如此 他们免费获得功能。 偏爱组合而非继承
- 抽象反转:不公开用户所需的已实现功能,以便他们使用更高级别的功能重新实现
- 不明确的视点:显示模型(通常为OOAD),但不指定其视点
- 大泥球:一个没有可识别结构的系统
- Blob:面向对象设计中God对象的泛化
- 煤气厂:不必要的复杂设计
- 输入混乱:未能指定和实现对可能无效输入的处理
- 接口膨胀:使接口功能强大到极难实现
- 魔术按钮:直接在接口代码中编码实现逻辑,而不使用抽象
- 种族危险:看不到不同顺序事件的后果
- 铁路解决方案:一种提议的解决方案,虽然很差,但由于在设计的其他领域缺乏远见和灵活性,它是唯一可用的解决方案
- 重耦合:引入不必要的对象依赖
- 火炉
- 以下是一些:
- 对我来说最突出的东西是“”
大多数情况下,我对违背“良好实践”的事情很敏感
例如:
一旦你解决了这个问题,OOP实际上就开始有意义了。问题是很少有团队知道这种设计模式。让所有对象都继承一些基本的实用程序类,这样你就可以调用你的实用程序方法,而不必输入太多的代码。不可能正确地进行单元测试。我要说的是糟糕的OO设计的第一条规则(是的,我已经犯了太多次了!)是:
- 这个问题假设面向对象意味着良好的设计。有些情况下,另一种方法更合适 一种气味是对象对其他对象具有硬依赖/引用,而这些对象不是其自然对象层次结构或域相关组合的一部分
示例:假设您有一个城市模拟。如果Person对象具有最接近邮局的属性,则您可能会遇到麻烦 找一位对代码库有经验的程序员。让他们解释一些东西是如何工作的 如果他们说“这个函数调用那个函数”,他们的代码是过程性的
如果他们说“这个类与那个类交互”,那么他们的代码就是OO。在一个长方法中,部分被#region/#endregion包围——在我所看到的几乎所有情况下,代码都可以很容易地提取到一个新方法中,或者需要以某种方式进行重构 过于复杂的继承树,其中的子类执行非常不同的操作,并且彼此之间只存在切向关联 违反DRY-子类,每个子类几乎以完全相同的方式重写一个基方法,只有一个微小的变化。例如:我最近编写了一些代码,其中每个子类都覆盖了一个基本方法,唯一的区别是类型测试(“x是ThisType”vs“x是ThatType”)。我在基中实现了一个方法,该方法采用了泛型类型T,然后在测试中使用它。然后,每个子级都可以调用基本实现,传递它想要测试的类型。这将从8个不同的子类中的每个类中删除大约30行代码。 软件设计反模式