实际上,OO代码的可重用性要少得多,这是设计使然。OOP背后的想法是将对特定数据段的操作限制为类中或继承层次结构中适当位置的某些特权代码。这限制了可变性的不利影响。如果数据结构发生变化,则代码中只有太多地方可以负责。
有了不变性,您不必在乎谁可以对任何给定的数据结构进行操作,因为没有人可以更改您的数据副本。这使得创建新功能来处理现有数据结构变得更加容易。您只需创建功能并将它们分组为从域角度看似乎合适的模块。您不必担心将它们放入继承层次结构的位置。
另一类代码重用是创建新的数据结构以使用现有功能。这是使用泛型和类型类之类的功能以功能语言处理的。例如,Haskell的Ord类型类允许您对sort
具有Ord
实例的任何类型使用该函数。如果实例不存在,则很容易创建它们。
以您的Animal
示例为例,并考虑实现供稿功能。直接的OOP实现是维护Animal
对象的集合,并遍历所有对象,并feed
在每个对象上调用方法。
但是,当您深入细节时,事情会变得棘手。一个Animal
对象自然知道什么样的食物它吃,它以需要多大的感觉十足。它自然不知道食物存放在哪里以及有多少可用,因此FoodStore
对象只是成为了Every的依赖项Animal
,要么作为Animal
对象的字段,要么作为feed
方法的参数传入。或者,为使Animal
类保持更高的凝聚力,您可以移至feed(animal)
该FoodStore
对象,也可以创建一个称为an AnimalFeeder
或此类的类的可憎对象。
在FP中,不倾向于Animal
始终将字段组合在一起,这对于可重用性具有一些有趣的含义。假设你有一个清单Animal
记录,与领域,如name
,species
,location
,food type
,food amount
,等你也有一个列表FoodStore
记录中包含的字段location
,food type
以及food amount
。
喂养的第一步可能是将每个记录列表映射到(food amount, food type)
成对列表,其中动物数量为负数。然后,您可以创建函数来使用这些对进行各种操作,例如将每种食物的数量相加。这些功能并不是Animal
一个FoodStore
模块或模块的完美结合,但是两者都可以高度复用。
最后,您会得到一堆函数,这些函数可做有用的事情,[(Num A, Eq B)]
这些函数是可重用的和模块化的,但是您很难确定将它们放置在何处或将它们称为什么。结果是FP模块更难以分类,但分类的重要性要低得多。