En realidad, el código OO es mucho menos reutilizable, y eso es por diseño. La idea detrás de OOP es restringir las operaciones en piezas de datos particulares a cierto código privilegiado que está en la clase o en el lugar apropiado en la jerarquía de herencia. Esto limita los efectos adversos de la mutabilidad. Si una estructura de datos cambia, solo hay algunos lugares en el código que pueden ser responsables.
Con la inmutabilidad, no le importa quién puede operar en una estructura de datos dada, porque nadie puede cambiar su copia de los datos. Esto facilita la creación de nuevas funciones para trabajar en estructuras de datos existentes. Simplemente cree las funciones y agrúpelas en módulos que parezcan apropiados desde el punto de vista del dominio. No tiene que preocuparse por dónde encajarlos en la jerarquía de herencia.
El otro tipo de reutilización de código es crear nuevas estructuras de datos para trabajar en funciones existentes. Esto se maneja en lenguajes funcionales usando características como genéricos y clases de tipos. Por ejemplo, la clase de tipo Ord de Haskell le permite usar la sort
función en cualquier tipo con una Ord
instancia. Las instancias son fáciles de crear si aún no existen.
Tome su Animal
ejemplo y considere implementar una función de alimentación. La implementación directa de OOP es mantener una colección de Animal
objetos y recorrerlos todos, llamando al feed
método en cada uno de ellos.
Sin embargo, las cosas se ponen difíciles cuando te pones a detalles. Un Animal
objeto, naturalmente, sabe qué tipo de comida come y cuánto necesita para sentirse lleno. No No sabe, naturalmente, donde se guarda la comida y la cantidad está disponible, por lo que un FoodStore
objeto ha pasado a ser una dependencia de todo Animal
, ya sea como un campo del Animal
objeto, o en el pasado como un parámetro del feed
método. Alternativamente, para mantener la Animal
clase más cohesionada, puede moverse feed(animal)
al FoodStore
objeto, o puede crear una abominación de una clase llamada uno AnimalFeeder
o algo así.
En FP, no hay inclinación para que los campos de una Animal
permanezcan siempre agrupados, lo que tiene algunas implicaciones interesantes para la reutilización. Digamos que tiene una lista de Animal
registros, con campos como name
, species
, location
, food type
, food amount
, etc También tiene una lista de FoodStore
registros con campos como location
, food type
, y food amount
.
El primer paso en la alimentación podría ser mapear cada una de esas listas de registros a listas de (food amount, food type)
parejas, con números negativos para las cantidades de los animales. Luego puede crear funciones para hacer todo tipo de cosas con estos pares, como sumar las cantidades de cada tipo de alimento. Estas funciones no pertenecen a la perfección ya sea a una Animal
o un FoodStore
módulo, pero son altamente reutilizables por ambos.
Terminas con un montón de funciones que hacen cosas útiles [(Num A, Eq B)]
que son reutilizables y modulares, pero tienes problemas para averiguar dónde colocarlas o cómo llamarlas como grupo. El efecto es que los módulos FP son más difíciles de clasificar, pero la clasificación es mucho menos importante.