一、公司沿革

我想告诉您一个故事,展示OOP如何帮助应对大型系统的复杂性。这对于理解OOP的目的是必要的。

曾几何时,有一家提供星际航运服务的小公司……

我们称它为 Galaxy Rush。它雇用了5个人。一个在财务部门工作,第二个在仓库工作,第三个负责送货,第四个负责广告,第五个管理整个企业。

他们工作非常努力,每件事都取得了成功。这家公司名声很好,赚了很多钱。但是年复一年的订单越来越多,老板不得不额外招人。仓库多几个,送货多几个,财务多一个,广告专家多一个,扩大公司的市场份额。

那就是问题开始的时候。人多了,他们开始互相挡路。

营销人员在新的广告活动上耗尽了银行账户,因此没有钱购买急需发货的产品。

仓库有 10 个全新的超级驱动器,每月一次运送给客户。一位快递员飞来为另一位客户拿走了一个超级驱动器,导致 10 个超级驱动器的常规订单延迟了一个月。第一个快递员根本不知道另一个订单是由第二个快递员填写的。

新任副理派快递员坐飞船去采购更多货物。与此同时,其他人都在等待可用的宇宙飞船出现。有大量紧急交货,但这位助理只负责监督采购,并努力做好自己的工作。 员工履行职责越好,他就越会干扰他人的工作。

分析情况,老板意识到飞船、现金和产品等重要资源没有得到最佳利用。相反,他们受制于“你打瞌睡,你就输了”的规则。任何员工都可以占用其他人工作所需的资源,从而危及其他员工和整个公司。

必须做点什么,所以老板决定将这个庞大的公司分成几个部门。他创建了运输部、市场部、采购部、财务部和库存部。任何人都不能简单地乘坐飞船。航运部门的负责人收到了所有关于交货的信息,并把船发给了利润最高的订单的快递员。此外,仓库不允许快递员随便拿走他们想要的任何货物。相反,从仓库中挑选产品变成了一个受控的过程。如果财务部门知道很快就会有采购,就不会为营销活动发放资金。每个部门都有一个公众形象——部门主管。每个部门的内部结构都是它自己的业务。如果快递员要取货,她会去找仓库管理员,而不是去仓库。如果收到新订单,则由运输部门负责人 ( public-facing representative) 而不是快递员 ( someone not authorized to interact with the other departments) 接收。

也就是说,老板将资源和涉及资源的行动统一到组(部门)中同时也禁止他人干涉部门的内部架构。 部门间的互动必须通过特定的人。

从OOP的角度来看,这无非是把程序分成对象。一个由方法和变量组成的整体程序变成了一个由对象组成的程序。对象有变量和方法。

问题在于任何员工都可以使用任何资源并向任何其他员工下达命令,而这一切都没有监督或控制。我们施加了一个小的限制,但获得了更多的秩序。而且我们也能够更好地控制一切。

这是最纯粹形式的分而治之。


2. 程序是如何创建的

我想谈一谈更重要的一点,它揭示了OOP的另一个优势。您是否看到程序更像是动物而不是建筑物?它们不是建造的。他们长大了。发展是不断变化的。在施工中,您可以有一个好的计划并精确地执行它。这不是软件开发的情况。

很多时候在编程中,你不能按照你最初的意图去做一些事情,必须进行大量的返工。客户需求的变化更加频繁。

但是,如果客户提供了非常精确的规格怎么办?这让事情变得更糟。看看随着时间的推移,产品会发生什么。

产品的成功将导致客户想要发布一个新版本,然后一个又一个。当然,您需要做的就是对现有产品添加“小改动”。所以你可以看到产品开发是一系列不断变化的过程。只是时间尺度不同。可以每周、每月或每六个月发布一次新版本。

我们可以从这一切中得出什么结论呢?产品的内部结构需要以一种允许以最少的返工进行重大(和次要)更改的方式进行维护。

对象内聚

但这样做比决定这样做更困难。我们已经说过,程序由相互交互的对象组成。让我们在板上绘制所有程序的对象,用点表示它们。让我们从每个对象(点)到与之交互的所有其他对象(点)绘制箭头。

现在我们将对象(点)组合成组。如果点之间的联系比与其他点的联系更紧密,则点应该被分组。如果一个点的大部分箭头都指向其所在组中的其他点,则组的形成是正确的。我们说一个组内的点具有高内聚性,而不同组内的点具有较低的内聚性。

松耦合原则

有一个“松耦合原则”。一个程序被分成几个部分,这些部分通常是分层的。这些层/部分的逻辑与其内部结构紧密耦合,而与其他层/部分的耦合非常松散。层与层之间的交互通常非常规范。一层可能引用第二层并且仅使用其类的一小部分。这就是我们前面看到的“公司分部门”的原则,但是规模更大。

结果是我们可以根据需要重组一个部门以提高其效率,我们可以为该部门雇用更多的人,只要我们不改变与其他部门互动的协议,那么所做的所有改变都会留在当地。没有人需要重新学习任何东西。您不必重新设计整个系统。如果选择好部门间交互机制,每个部门都可以进行这种内部优化。

选得好。但是,如果他们没有选择好怎么办?然后改变的能力很快就会耗尽,你将不得不重做整个系统。这必须时常进行。你无法预测未来,但你可以将重做的次数保持在最低限度。

抽象原则

选择部门的结构以及它们如何交互是“抽象原则”。在编程中,它用于确定将程序分解为组成部分的最佳方式以及这些部分应该如何交互。我们可以重新应用该原则,将结果部分分成多个部分,直到我们将程序分解为单独的类。

隐藏这些部分的内部结构并严格限制与其他部分的交互就是封装 封装和抽象是OOP的基石。一个好的程序必须遵循这两个原则。将来,我们将研究其余原则并探索它们提供的好处。