Los idiomas OO se pueden usar en lugar de idiomas de bajo nivel a veces para interactuar directamente con una máquina. C ++ Seguro, pero incluso para C # hay adaptadores y demás. Aunque escribir código para controlar las partes mecánicas y tener un control minucioso sobre la memoria se mantiene lo más cerca posible del nivel más bajo posible. Pero si esta pregunta está relacionada con el software actual orientado a objetos como Line Of Business, aplicaciones web, IOT, servicios web y la mayoría de las aplicaciones de uso masivo, entonces ...
Respuesta, si corresponde
Los lectores pueden intentar trabajar con una arquitectura orientada a servicios (SOA). Es decir, DDD, N-Layered, N-Tiered, Hexagonal, lo que sea. No he visto que una aplicación para grandes empresas utilice eficientemente OO "tradicional" (Active-Record o Rich-Models) como se describió en los años 70 y 80 en la última década. (Ver nota 1)
La falla no es con el OP, pero hay un par de problemas con la pregunta.
El ejemplo que proporciona es simplemente para demostrar Polimorfismo, no es un código de producción. A veces, ejemplos exactamente así se toman literalmente.
En FP y SOA, los datos se separan de la lógica de negocios. Es decir, los datos y la lógica no van juntos. La lógica entra en Servicios, y los Datos (Modelos de dominio) no tienen comportamiento Polimórfico (Ver Nota 2).
Los servicios y funciones pueden ser polimórficos. En FP, con frecuencia pasa funciones como parámetros a otras funciones en lugar de valores. Puede hacer lo mismo en OO Languages con tipos como Callable o Func, pero no se ejecuta desenfrenada (Ver Nota 3). En FP y SOA, sus modelos no son polimórficos, solo sus servicios / funciones. (Ver nota 4)
Hay un mal caso de hardcoding en ese ejemplo. No solo estoy hablando de la cadena de color rojo "perro ladra". También estoy hablando de CatModel y DogModel. ¿Qué sucede cuando quieres agregar una oveja? ¿Tienes que ingresar tu código y crear un nuevo código? ¿Por qué? En el código de producción, preferiría ver solo un AnimalModel con sus propiedades. En el peor de los casos, un modelo de anfibio y un modelo de ave si sus propiedades y manejo son tan diferentes.
Esto es lo que esperaría ver en un lenguaje "OO" actual:
public class Animal
{
public int AnimalID { get; set; }
public int LegCount { get; set; }
public string Name { get; set; }
public string WhatISay { get; set; }
}
public class AnimalService : IManageAnimals
{
private IPersistAnimals _animalRepo;
public AnimalService(IPersistAnimals animalRepo) { _animalRepo = animalRepo; }
public List<Animal> GetAnimals() => _animalRepo.GetAnimals();
public string WhatDoISay(Animal animal)
{
if (!string.IsNullOrWhiteSpace(animal.WhatISay))
return animal.WhatISay;
return _animalRepo.GetAnimalNoise(animal.AnimalID);
}
}
¿Cómo pasar de las clases en OO a la programación funcional? Como otros han dicho; Puedes, pero en realidad no. El objetivo de lo anterior es demostrar que ni siquiera debería usar Clases (en el sentido tradicional del mundo) al hacer Java y C #. Una vez que llegue a escribir código en una Arquitectura Orientada a Servicios (DDD, Capas, Niveles, Hexagonal, lo que sea), estará un paso más cerca de Funcional porque separa sus Datos (Modelos de Dominio) de sus Funciones Lógicas (Servicios).
OO Language un paso más cerca de FP
Incluso podría llevarlo un poco más lejos y dividir sus Servicios SOA en dos tipos.
Clase opcional Tipo 1 : Servicios comunes de implementación de interfaz para puntos de entrada. Estos serían puntos de entrada "impuros" que pueden llamar a otras funciones "puras" o "impuras". Estos podrían ser sus puntos de entrada de una API RESTful.
Clase opcional tipo 2 : Servicios de lógica empresarial pura. Estas son clases estáticas que tienen funcionalidad "pura". En FP, "Puro" significa que no hay efectos secundarios. No establece explícitamente el estado o la persistencia en ninguna parte. (Ver nota 5)
Entonces, cuando piensa en las Clases en Lenguajes Orientados a Objetos, que se usan en una Arquitectura Orientada a Servicios, no solo beneficia su Código OO, sino que comienza a hacer que la Programación Funcional parezca muy fácil de entender.
Notas
Nota 1 : El diseño orientado a objetos "Rich" o "Active-Record" original todavía existe. Hay MUCHO código heredado como ese cuando la gente "lo hacía bien" hace una década o más. La última vez que vi ese tipo de código (hecho correctamente) era de un video juego Codebase en C ++ donde controlaban la memoria con precisión y tenían un espacio muy limitado. No quiere decir que FP y las arquitecturas orientadas a servicios sean bestias y no deberían considerar el hardware. Pero colocan la capacidad de cambiar constantemente, mantenerse, tener tamaños de datos variables y otros aspectos como prioridad. En los videojuegos y la IA de la máquina, controlas las señales y los datos con mucha precisión.
Nota 2 : Los modelos de dominio no tienen comportamiento polimórfico, ni tienen dependencias externas. Están "aislados". Eso no significa que tengan que ser 100% anémicos. Pueden tener mucha lógica relacionada con su construcción y alteración de propiedades mutables, si corresponde. Ver DDD "Objetos de valor" y entidades de Eric Evans y Mark Seemann.
Nota 3 : Linq y Lambda son muy comunes. Pero cuando un usuario crea una nueva función, rara vez usa Func o Callable como parámetros, mientras que en FP sería extraño ver una aplicación sin funciones que sigan ese patrón.
Nota 4 : No confundir el polimorfismo con la herencia. Un CatModel podría heredar AnimalBase para determinar qué propiedades tiene típicamente un animal. Pero como muestro, Modelos como este son un código de olor . Si ve este patrón, podría considerar desglosarlo y convertirlo en datos.
Nota 5 : Las funciones puras pueden (y lo hacen) aceptar funciones como parámetros. La función entrante puede ser impura, pero puede ser pura. Para fines de prueba, siempre sería puro. Pero en la producción, aunque se trata como puro, puede contener efectos secundarios. Eso no cambia el hecho de que la función pura es pura. Aunque la función del parámetro puede ser impura. No es confuso! :RE