关于面向对象的编程

面向对象的编程被认为是基于三个支柱的,这三个支柱为程序员提供了优于过程方法的优势。它们是封装,继承和多态性。当使用面向对象的方法时,继承使您可以大大摆脱代码重复。但是使用它,您应该始终牢记SOLID的一项原则,称为Liskov替代,除非您详细介绍,否则该原则指出继承应仅用作“ is”关系的实现。也就是说,后代的类别必须“是”父系的一个亚种。例如,您可能具有Bird类及其子类Sparrow(sparrow)和Raven(raven),例如,它们继承(并且可以扩展或修改)fly方法。但是,如果创建名为Penguin(企鹅)的Bird的后代,并且其fly方法会抛出异常(因为企鹅不会飞行),这将违反Liskov替换原理。说到继承,还值得一提的是“四人帮”(Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides)在其《设计模式:可重用的面向对象软件的元素》(1994)一书中坚持的一项重要原则,其中指出您应该尝试使用组合(当一个对象“包含”另一个对象时),而不是尽可能地继承。实际上,“四人帮”发明的许多设计模式都正是基于这一原理。实际上,“四人帮”发明的许多设计模式都正是基于这一原理。实际上,“四人帮”发明的许多设计模式都正是基于这一原理。

通常,在实践中,即使在大多数情况下,优秀的程序员都用组合代替了继承,但并不经常使用继承。一个接口有多种实现,在客户端类中被指定为依赖项。反过来,您又可以使用OOP的第二个支柱-多态性。这允许您将不同的依赖实现传递给客户端代码。由于所传输的依赖项具有相同的接口,客户端(取决于接口)并不关心传入的对象,因此程序员可以在程序执行过程中以何种方式(接口的哪种实现)更改最终任务。说到OOP,人们不能不提到封装。这是OOP的基本要素,它提供了创建抽象的功能,以隐藏底层实现细节,同时降低了开发复杂性。实现细节被访问修饰符(例如private和protected)隐藏。创建类时,您需要创建它们,以便它们的接口(可访问的公共方法)提供一致的抽象,否则不再是OOP(!)例如,假设我们正在开发一个控制核反应堆冷却系统的程序。然后,接口的约定抽象如下。

CoolingSystem::getTemperature()
CoolingSystem::SetCirculationRate($rate)
CoolingSystem::OpenValve($valveNumber)
CoolingSystem::CloseValve($valveNumber)

由于短的表达接口形成了一个连贯的抽象,因此我们可以使用反应堆冷却系统,而不必对所选技术特有的底层实现细节有丝毫的了解。使用抽象可以大大降低开发系统的复杂性。与复杂性作斗争是发展的主要技术要求。这里有一些更多的一致抽象的例子:

速度控制系统:

  • 设定速度
  • 获取当前设置
  • 恢复以前的速度值
  • 禁用系统

咖啡研磨机:

  • 启用
  • 关掉
  • 设定速度
  • 开始磨咖啡
  • 停止研磨咖啡

油箱:

  • 加油
  • 排空燃油
  • 获得油箱容量
  • 获取油箱状态

灯:

  • 启用
  • 关掉

在设计对象的接口时,仅将客户端需要管理的那些方法声明为公共,隐藏其他所有内容。结果,您应该得到黑匣子,在添加了类代码之后,您可能会忘记该黑匣子的设备。这种方法可以大大降低开发系统的复杂性。

All Articles