¿OOP cumple la promesa de reutilización de código? ¿Qué alternativas hay para lograr la reutilización del código?


56

Quizás la mayor promesa de usar el paradigma orientado a objetos es la reutilización del código. Algunos discuten que esto se logró. ¿Por qué se logró (no)?

¿El código se reutiliza como lo define OOP y hace que los proyectos sean más productivos?

¿O más manejable? ¿O más fácil de mantener? ¿O con más calidad?

Probablemente todos estamos de acuerdo en que la reutilización de código es algo bueno, pero hay varias formas de lograr este objetivo. La pregunta es sobre el método de reutilización de código ofrecido por OOP. ¿Fue algo bueno? ¿Existen mejores métodos para lograr la reutilización del código que la orientación a objetos, subclases, polimorfismo, etc.? ¿Qué formas son mejores? ¿Por qué ?

Cuéntenos su experiencia con la reutilización de OOP u otra reutilización de paradigmas.



77
Es complementario, no exactamente duplicado. Lo reformulé para comprender mejor la diferencia.
Maniero

Si puede votar y cree que esta es una pregunta útil o tiene respuestas útiles a continuación, vote por favor. Los sitios de StackExchange necesitan votos para construir una buena comunidad. Puedes dar 30 votos por día, no los desperdicies. Especialmente los usuarios con alta reputación y bajo recuento de votos dados, lean esto: meta.programmers.stackexchange.com/questions/393/…
Maniero


2
@j_random_hacker: lee los comentarios.
Maniero

Respuestas:


34

La reutilización de código es una muy buena idea. No es genial .

Tengo una perspectiva extraída de unos 30 años de ingeniería de software, tratando de "reutilizar".

Comencé a investigar la "reutilización de código" como tema de investigación en los años 80, después de descubrir que había reutilizado el diseño de un sistema operativo que construí a principios de los 70, para otro sistema operativo que construí a fines de los 70.

La buena parte de la reutilización del código es la capacidad de reutilizar a veces el código preexistente honesto a dios. Pero el mundo está lleno de código; como puedes encontrar lo que buscas Esto es lo que llamo la maldición de reutilización :

Soy Santa Claus (ok Código abierto), y tengo una bolsa de mil millones de componentes de software. Puedes tener cualquiera de ellos.

Buena suerte eligiendo.

Para resolver bien el problema de reutilización:

  • el usuario debe especificar de alguna manera lo que necesita (funcionalidad, rendimiento, lenguaje de destino, suposiciones del entorno, ...)
  • debe haber una biblioteca de código "reutilizable" que haya sido indexada de varias maneras por estos criterios potenciales
  • Debe existir algún mecanismo para seleccionar los elementos candidatos (en un billón de elementos, no puede verlos todos personalmente)
  • debe haber una manera de caracterizar qué tan lejos de la especificación están los candidatos elegidos
  • debe existir algún proceso regular para permitir que el usuario modifique el código reutilizable elegido (esta es la mayor contribución de OOP: puede editar un componente / objeto existente anulando sus ranuras. OOP no proporciona ninguna otra ayuda).
  • todo esto debe ser claramente más barato que simplemente recodificarlo

En su mayoría, lo que se ha descubierto a lo largo de los años es que para que el código sea reutilizable, debe diseñarse para ese propósito, o contiene demasiados supuestos implícitos. Las bibliotecas de reutilización de código más exitosas en realidad han sido bastante pequeñas. Podría decirse que las bibliotecas y los marcos son código "reutilizable" y son extremadamente exitosos; Java y C # tienen éxito no porque sean muy buenos lenguajes de computadora, sino porque tienen enormes bibliotecas bien diseñadas, implementadas y documentadas disponibles. Pero la gente no mira el código fuente en las bibliotecas; simplemente llaman una API bien documentada (diseñada para ser generalmente utilizable).

Lo que la reutilización de código no ha hecho (OOP tampoco) es proporcionar una mejora de órdenes de magnitud en nuestra capacidad de codificar sistemas.

Creo que la falla clave es que cualquier tipo de reutilización de código es fundamentalmente limitada porque el código tiene demasiados supuestos incorporados . Si hace que el código sea pequeño, minimiza las suposiciones, pero el costo de construir desde cero no es muy grande y las ganancias de reutilización no son efectivas. Si haces que los fragmentos de código sean enormes, son prácticamente inútiles en un nuevo contexto. Al igual que Gulliver, están atados a la playa por un millón de cuerdas pequeñas, y simplemente no puedes permitirte cortarlas todas.

En lo que deberíamos estar trabajando es en la reutilización del conocimiento para construir código . Si podemos hacer esto, entonces podemos aplicar ese conocimiento para construir el código que necesitamos, manejando el conjunto actual de suposiciones.

Para hacer esto, todavía se necesita la misma capacidad de especificación para caracterizar los componentes de software (¡todavía tiene que decir lo que quiere!). Pero luego aplica este conocimiento de "construcción" a las especificaciones para generar el código que desea.

Como comunidad, todavía no somos muy buenos en esto. Pero la gente lo hace todo el tiempo; ¿Por qué no podemos automatizarlo? Hay mucha investigación, y esto demuestra que se puede hacer en muchas circunstancias.

Una pieza clave de la maquinaria necesaria para esto son las herramientas mecánicas para aceptar "descripciones de componentes" (estos son solo documentos formales y se pueden analizar como lenguajes de programación) y aplicarles transformaciones de programa .

Los compiladores ya hacen esto: -} Y son realmente buenos en la clase de problema que abordan.

Los modelos UML con generación de código son un intento de hacer esto. No es un muy buen intento; más o menos lo que uno dice en la mayoría de los modelos UML es "Tengo datos que se ven así". Es bastante difícil generar un programa real si se deja de lado la funcionalidad.

Estoy tratando de construir sistemas prácticos de transformación de programas, una herramienta llamada DMS . Me ha distraído bastante aplicar las transformaciones del programa no tanto a las especificaciones abstractas para generar código, sino al código heredado para limpiarlo. (¡Son el mismo problema en abstracto!). (Construir tales herramientas lleva mucho tiempo; he estado haciendo esto durante 15 años y mientras tanto tienes que comer).

Pero el DMS tiene las dos propiedades clave que describí anteriormente: la capacidad de procesar especificaciones formales arbitrarias y la capacidad de capturar "conocimiento de generación de código" como transformaciones, y aplicarlas bajo demanda. Y notablemente, generamos en algunos casos especiales, algún código bastante interesante de las especificaciones; DMS se construye en gran medida utilizándose para generar su implementación. Eso nos ha permitido al menos parte de la promesa de reutilización (conocimiento): ganancias de productividad extremadamente significativas. Tengo un equipo de aproximadamente 7 personas técnicas; probablemente hemos escrito 1-2 MSLOC de "especificaciones" para DMS, pero tenemos unos 10MSLOC de código generado.

Resumen: la reutilización del conocimiento de generación es la victoria, no la reutilización del código .


44
En mi humilde opinión, la mejor respuesta. Lo importante es la reutilización de conocimiento / idea, no el código.
Kravemir

44
Mostly what has been discovered over the years is that for code to be reusable, it sort of has to be designed for that purpose, or it contains too many implicit assumptions.Llegué a una conclusión similar, pero no pude expresarlo de manera tan sucinta.
biziclop

36

La reutilización del código se logra en OOP pero también se logra en la programación funcional. Cada vez que toma un bloque de código y lo hace invocable por el resto de su código para que pueda usar esta funcionalidad en otro lugar, es la reutilización del código.

Este tipo de reutilización de código también hace que el código sea más manejable porque cambiar este bloque invocable cambia todos los lugares a los que se llama. Yo diría que este resultado también aumentó la calidad y la legibilidad.

No estoy seguro de que OOP simplemente esté allí para proporcionar la reutilización del código. Miro a OOP como una forma más de interactuar con objetos y abstraer los detalles de la estructura de datos.

De Wikpedia:

La programación orientada a objetos tiene raíces que se remontan a la década de 1960. A medida que el hardware y el software se volvieron cada vez más complejos, la capacidad de administración a menudo se convirtió en una preocupación. Los investigadores estudiaron formas de mantener la calidad del software y desarrollaron programación orientada a objetos en parte para abordar problemas comunes al enfatizar fuertemente las unidades discretas y reutilizables de lógica de programación [cita requerida]. La tecnología se centra en los datos en lugar de los procesos, con programas compuestos de módulos autosuficientes ("clases"), cada instancia de los cuales ("objetos") contiene toda la información necesaria para manipular su propia estructura de datos ("miembros"). Esto contrasta con la programación modular existente que había sido dominante durante muchos años y que se centraba en la función de un módulo, en lugar de específicamente en los datos, pero que también se proporcionaba para la reutilización del código, y unidades de lógica de programación reutilizables autosuficientes, que permiten la colaboración mediante el uso de módulos vinculados (subrutinas). Este enfoque más convencional, que aún persiste, tiende a considerar los datos y el comportamiento por separado.


99
La programación funcional +1 puede ser el camino a seguir para la reutilización de código.
Jonas

1
@Matthieu M .: Bueno, ¿qué tan reutilizable es double sqrt (double x)? Las funciones puras son el arquetipo de la reutilización.
Joonas Pulakka

3
@Joonas: double sqrt(double x), float sqrt(float x), int sqrt(int x)es posible definir un montón de ellos, mientras que con un lenguaje de programación genérica que tendría Number sqrt(Number x)y hacer con ella.
Matthieu M.

1
@Matthieu M .: De hecho, los genéricos reducen la replicación de código, por lo que es "más reutilizable", sí. Sin embargo, creo que la clave real para la reutilización es definir funciones simples, pequeñas, sanas y puras (esta es la dirección de "programación funcional"), y pasarlas, lo cual es posible en C. Se trata más del estilo de programación general que sobre las capacidades del lenguaje en sí.
Joonas Pulakka

1
@ Joonas: Ah, me había perdido la palabra pura , tienes razón, componer pequeñas funciones puras es simplemente genial, e incluso C presenta punteros a las funciones para eso.
Matthieu M.

15

Si y no

La reutilización de código es un término general para muchas actividades diferentes.

  1. Reutilización de código dentro de un solo proyecto. OO es perfectamente adecuado para esto, una aplicación bien diseñada habrá mapeado de cerca las relaciones del mundo modelado, eliminando así el código duplicado tanto como sea posible y aconsejable. Sin embargo, puede argumentar que las tecnologías pre-OO podrían lograr lo mismo, lo cual es cierto, pero OO es en muchos aspectos más conveniente.
  2. Bibliotecas de terceros Esto parece funcionar igualmente bien con o sin OO.
  3. Reutilización de código multipropósito La mayor promesa de reutilización de código de OO fue que el código, una vez escrito para una aplicación, puede reutilizarse para otra, para lo cual no había sido diseñado específicamente. Esto causó furor cuando la noción de OO se filtró a través de las puertas de las oficinas de alta gerencia, y OO no pudo lograrlo por completo. Resultó que el propósito era un aspecto crucial del diseño OO (y posiblemente todo el código de procedimiento, pero esa es solo mi teoría) y los intentos de reutilizar el código terminaron en desastres de mantenimiento. (Los conocidos antipatrones de un antiguo marco que nadie se atreve a modificar y su amigo, los marcos ligeramente diferentes para cada aplicación, generalmente se derivan de aquí).

13

Publicaría una respuesta larga pero ¿por qué? Udi Dahan lo explica mucho mejor que yo.

http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/

Aquí está el comienzo de la publicación:

Esta industria está ocupada con la reutilización.

Existe la creencia de que si solo reutilizáramos más código, todo sería mejor.

Algunos incluso van tan lejos como para decir que todo el punto de orientación a los objetos era reutilizar; no lo era, la encapsulación era lo más importante. Después de que la orientación de los componentes era lo que se suponía que debía hacer la reutilización. Aparentemente, eso tampoco funcionó tan bien porque aquí estamos fijando nuestras esperanzas reutilizables en la orientación al servicio.

Se han escrito libros completos de patrones sobre cómo lograr la reutilización con la orientación del día. Los servicios se han clasificado de todas las maneras posibles para tratar de lograr esto, desde servicios de entidad y servicios de actividad, hasta servicios de proceso y servicios de orquestación. La composición de servicios se ha promocionado como la clave para reutilizar y crear servicios reutilizables.

También podría contarte el pequeño secreto sucio:

Reutilizar es una falacia


44
-1. El Sr. Dahan está preocupado por los hombres de paja; nadie reutiliza seriamente el código no genérico como lo implica, y si elimina ese argumento de su artículo, de hecho está a favor o reutilizando el código adecuadamente .
Steven A. Lowe

3
@ Steven A. Lowe Bueno, desearía que fuera cierto. Desearía tener tu suerte porque he visto la reutilización del código en forma no genérica. No fue lindo.
Tony

1
Estoy seguro de que no fue así, pero ¿hablaban en serio ? dilbert.com/strips/comic/1996-01-31
Steven A. Lowe

1
De acuerdo, el costo de hacer que el código sea reutilizable es realmente alto, por lo que no vale la pena a menos que esté hablando en la escala de las clases base Java o .NET. Ver youtube.com/watch?v=aAb7hSCtvGw
Andomar el

13

Estoy de acuerdo con Chris, la programación funcional es una buena manera de reutilizar el código.

Muchos programas tienen estructuras de código que son recurrentes. Para esto , se utilizan algunos patrones de diseño en el mundo OOP, pero esto se puede lograr mediante funciones recursivas y coincidencia de patrones en lenguajes de programación funcionales. Para obtener más información al respecto, consulte el primer capítulo de Programación funcional del mundo real .

Creo que la herencia profunda en OOP puede ser engañosa en muchos casos. Tiene una clase y muchos de los métodos estrechamente relacionados se implementan en diferentes archivos. Como Joe Armstrong dijo sobre OOP:

El problema con los lenguajes orientados a objetos es que tienen todo este entorno implícito que llevan consigo. Querías un plátano pero lo que obtuviste fue un gorila sosteniendo el plátano y toda la jungla.

Las funciones de alto orden también son muy útiles cuando se trata de la reutilización de código, por ejemplo, mapy foldresa es la base de MapReduce de Google .

El paso de mensajes asincrónicos también es una buena manera de organizar un software complejo, y algunos científicos informáticos afirman que se suponía que los objetos se comunicaban entre sí de manera asincrónica como en el principio Tell, no pregunte a OOP. Vea más sobre esto en Programación Orientada a Objetos: ¿El camino equivocado? donde se cita a Joe Armstrong :

Comencé a preguntarme qué era la programación orientada a objetos y pensé que Erlang no estaba orientado a objetos, era un lenguaje de programación funcional. Entonces, mi supervisor de tesis dijo "Pero te equivocas, Erlang está extremadamente orientado a objetos". Dijo que los lenguajes orientados a objetos no están orientados a objetos. Podría pensar, aunque no estoy muy seguro de si creo esto o no, pero Erlang podría ser el único lenguaje orientado a objetos porque los 3 principios de la programación orientada a objetos son que se basa en el paso de mensajes , que tienes aislamiento entre objetos y tener polimorfismo .

La transmisión de mensajes asincrónicos como en sistemas controlados por eventos y en Erlang también es una muy buena manera de desacoplar sistemas y el acoplamiento flexible es importante en sistemas complejos. Con un sistema suficientemente desacoplado, puede evolucionar el sistema mientras se está ejecutando, tal vez en diferentes nodos. Unibet hizo una gran presentación sobre esto: Arquitectura dirigida por eventos de dominio

Sin embargo, creo que la mayor parte de la reutilización del código se realiza mediante bibliotecas y marcos.


2
Me encanta esa cita de gorila. ^^
gablin

Pensé que la pregunta era sobre la reutilización del código, no una buena semántica ...
Daniel Lubarov

6

La humilde tubería de Unix ha hecho más por la reutilización de código que cualquier otra cosa que haya aparecido y desaparecido. Los objetos resultaron ser una forma intuitiva de estructurar el código cuando aparecieron y luego la gente comenzó a agregarle cualquier cosa y todo. En general, los objetos son para encapsulación y no para reutilización de código, la reutilización de código requiere algo más y la jerarquía de herencia de clase es un sustituto pobre de lo que realmente debería ser un mecanismo de reutilización de código.


4

OOP no es especial; puede hacer código reutilizable con o sin OOP. Las funciones puras son particularmente reutilizables : por ejemplo, java.lang.math.sqrt(double)toma un número y da un número. Sin POO, pero definitivamente más reutilizable que la mayoría de los códigos existentes.


4

Desde una vista de programación funcional, OOP se trata principalmente de administrar el estado.

En la programación funcional, puede tener fácilmente cientos de funciones útiles para las listas: http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Data-List.html .

¿Tendría cientos de métodos en una clase de lista? Los métodos públicos se consideran una interfaz con el estado interno que desea mantener pequeño.

Lamentablemente, en lugar de (re) usar muchas funciones pequeñas, algunas personas duplican la funcionalidad. Para mí eso se debe a que OOP no fomenta la reutilización del código tanto como lo hace la programación funcional.


1
Tus conclusiones están todas equivocadas, @ Lenny222. No hay nada acerca de OOP que requiera clases para mantener el estado. Esa es una cuestión de su arquitectura si almacena el estado internamente o, como las clases Integer de Smalltalk, crea instancias de nuevos objetos con un nuevo estado.
Huperniketes

1
Lamento no haberme expresado de una manera que haya evitado este malentendido: lo que quise decir es que la diferencia entre OOP y FP no es que OOP eclipse el código reutilice más de lo que lo hace FP (lo que implica el titular). He experimentado una reutilización de código mucho mejor con FP. Si solo tienes clases inmutables, estás emulando FP, ¿por qué hacer POO en primer lugar? En mi POV se trata de una gestión estatal imperativa.
LennyProgrammers

3

Para mí, sí, pero no todo el tiempo, y podría haberse hecho de otras maneras.

La mayoría de las veces creando una clase base abstracta y creando implementaciones concretas de esa clase.

También muchos marcos hacen uso de la herencia para proporcionar la reutilización del código (Delphi, Java, .Net son solo algunos que se me ocurren al instante).

Eso no quiere decir que muchas bibliotecas de utilidades y fragmentos de código no podrían haber hecho el trabajo también, pero hay algo agradable en una jerarquía de objetos bien diseñada.


3

En mi experiencia, he tenido más éxito aprovechando el código "reutilizable" a través de recursos de programación genéricos (como plantillas de C ++) que el que he tenido usando principios de OOP como jerarquías de herencia.


2

OOP está demasiado abierto para una reutilización efectiva.

Hay demasiadas formas de reutilizar. Cada clase pública pregunta: "¡crea una nueva instancia de mí!" , cada método público dice: "¡llámame!" , cada método protegido produce: "¡anularme!" - y todas estas formas de reutilización son diferentes , tienen diferentes parámetros, aparecen en diferentes contextos, todos tienen sus diferentes reglas, cómo llamarlo / extenderlo / anularlo.

La API es mejor, es un subconjunto estricto de puntos OOP (o no-oop), pero en la vida real, las API están sobrevaloradas y crecen para siempre, todavía hay demasiados puntos de conexión. Además, una buena API puede facilitar la vida, es la mejor manera de proporcionar una interfaz para OOP.


El paradigma Datadlow proporciona una interfaz estricta para los componentes, tienen puertos de los siguientes tipos:

  • consumidores (insumos), y
  • productores (productos).

Dependiendo del dominio, hay algunos tipos de paquetes, por lo que los consumidores y productores pueden conectarse si tienen los mismos puertos (o compatibles). La parte más hermosa de esto, que puede hacerse visualmente, porque no hay parámetros ni ajustes adicionales en las conexiones, realmente solo conectan a un consumidor y un productor.

No estaba claro, puede echar un vistazo a la etiqueta "flujo de datos" en StackOverflow , o "programación de flujo de datos" de Wikipedia o "programación basada en flujo" de Wikipedia .

(Además, he escrito un sistema de flujo de datos, en C ++. Entonces, OOP y DF no son enemigos, DF es una forma de organización de nivel superior).


2

En CommonLisp hay muchos medios para lograr la reutilización:

  • escritura dinámica, haciendo que su código sea genérico por defecto

  • abstracciones imperativas, es decir, subrutinas

  • orientación a objetos, con herencia múltiple y despacho múltiple

  • abstracción de sintaxis, la capacidad de definir nuevas construcciones sintácticas o abreviar código de placa de caldera

  • abstracciones funcionales, cierres y funciones de alto orden

Si intenta comparar la experiencia de CommonLisp con otros lenguajes, verá que la característica principal que facilita la reutilización del código es la presencia de abstracciones tanto orientadas a objetos como funcionales. Son más complementarios que alternativos: sin uno de ellos, se ve obligado a volver a implementar las características que faltan de una manera torpe. Vea, por ejemplo, las clases de functor utilizadas como cierres y coincidencia de patrones para obtener el envío de métodos no extensibles.


1

Realmente no existe tal cosa como "reutilizar" la forma en que la gente lo describe. La reutilización es una propiedad accidental de cualquier cosa. Es difícil planearlo. Lo que la mayoría de la gente quiere decir cuando habla de "reutilizar" es "usar". Es un término mucho menos atractivo y emocionante. Cuando usa una biblioteca, la está usando para lo que estaba destinada, normalmente. Usted está no volver a usarlo a menos que estés haciendo algo realmente loco con ella.

En ese sentido, la reutilización en el mundo real se trata de reutilizar las cosas. Puedo reutilizar estos asientos aquí y reorganizarlos para formar ... ¡una cama! No es una cama muy cómoda, pero puedo hacer eso. Ese no es su uso principal. Los estoy reutilizando fuera de su dominio original de aplicabilidad. [...] Mañana, volaré de regreso al Reino Unido. Yo no volver a utilizar el avión. Solo lo usaré para el propósito para el que fue diseñado, no hay nada lujoso o emocionante al respecto.

- Kevlin Henney


3
La gente creerá todo lo que vea impreso. Kevlin Henney es incorrecto y basó su razonamiento en una falta de contexto histórico y una pobre interpretación semántica. La reutilización del código fue un principio de programación fundamental desde los días de las computadoras de tubo de vacío UNIVAC e IBM. Reutilizar el código no se trataba de volver a utilizarlo para alguna funcionalidad distinta de la prevista . Escribiste y ensamblaste (luego se compiló) tus subrutinas para producir código objeto que luego se vinculó a tu programa. Reutilizar realmente significa lo que comúnmente se entiende en la industria actual.
Huperniketes

Si escribe dos funciones que hacen exactamente lo mismo, NO ha reutilizado el código, independientemente de cuántas veces las haya usado.
JeffO

La analogía de la silla es agradable y todo eso, pero solo una palabra: Lego.
biziclop

1

Voy a arriesgarme a ridiculizar y confesar, solo he estado usando OOP muy recientemente. No viene a mí automáticamente. La mayor parte de mi experiencia involucra bases de datos relacionales, así que pienso en tablas y combinaciones. Hay afirmaciones de que es mejor aprenderlo desde el principio, lo que evita tener que reconectar su pensamiento a la hora de programar. No tengo ese lujo y me niego a desechar mi carrera por alguna teoría de la torre de marfil. Como todo lo demás, lo resolveré.

Al principio pensé que todo el concepto no tenía sentido. Simplemente parecía innecesario y demasiados problemas. Lo sé, esto es una locura. Obviamente, se necesita un cierto nivel de comprensión antes de poder apreciar los beneficios de algo o descartarlo por mejores métodos.

La reutilización del código requiere la voluntad de no repetir el código, la comprensión de cómo lograrlo, la planificación inicial. ¿Debería evitar reutilizar el código cuando haya decidido que tiene un caso en el que simplemente no vale la pena? Y ningún lenguaje es tan estrictamente OO que arroje un error cuando piense que debería haber heredado el código de otra clase. En el mejor de los casos, proporcionan un entorno propicio para implementarlo.

Creo que el mayor beneficio de OOP es la aceptación general de cómo se debe organizar el código. Todo lo demás es salsa. Un equipo de programadores puede no estar totalmente de acuerdo sobre cómo deberían estructurarse todas las clases, pero deberían poder encontrar el código.

He visto suficiente código de procedimiento para saber que podría estar en cualquier lugar, y a veces está en todas partes.


"Y ningún lenguaje es tan estrictamente OO que arrojará un error cuando piense que debería haber heredado el código de otra clase", ¡todavía no!
Steven A. Lowe

1

OOP le ofrece más formas de reutilizar el código. Eso es todo.


OOP también promueve la reutilización de la interfaz y la reutilización del diseño.
rwong

Me da muchas menos formas de escribir un código genérico, reutilizable y altamente abstracto que los otros paradigmas, como la programación funcional (currículum, bibliotecas combinadas, etc.) y la metaprogramación. En realidad, OOP parece tener un nivel de copa de abstracción, cuando las alternativas no están limitadas en absoluto.
SK-logic

@ SK-logic: ortogonal.
Steven A. Lowe

1

Reutilización horizontal: aspectos, rasgos, injertos.

Classic OO a veces se queda corto en la reutilización de código, especialmente cuando te vuelves loco por la falta de una mejor manera de compartir la funcionalidad real entre las clases. Para este problema, se han creado mecanismos de reutilización horizontal, como AOP, rasgos e injertos.

Programación Orientada a Aspectos

Considero AOP como la mitad naranja que falta de OOP. AOP no es realmente tan conocido, pero ha llegado al código de producción.

Trataré de explicarlo en términos simples: imagine que puede inyectar y filtrar la funcionalidad con una estructura especial llamada aspecto, estos aspectos tienen "métodos" que definen qué y cómo se verá afectado a través de la reflexión , pero en el momento de la compilación Este proceso se llama tejido .

Un ejemplo sería un aspecto que dice "para todos los métodos de ciertas clases que comienzan con get, su programa escribirá en un archivo de registro los datos que se obtuvieron y el momento en que se obtuvieron".

Mire estas dos charlas si quiere entender mejor el AOP:

Rasgos e injertos

Los rasgos son otro constructo para definir el código reutilizable que complementa a OOP, son similares a los mixins , pero más limpios.

En lugar de explicarlos, hay un gran PHP RFC que explica ambos . Los rasgos están llegando a PHP por cierto, ya están comprometidos con el tronco.

En resumen

OOP es clave en la modularidad, aún, en mi opinión y como lo conocemos hoy en día, OOP todavía está incompleto .


0

OOP Proporciona un conjunto de herramientas útiles que le permiten escribir código que puede usarse en más lugares de los que podría tener sin esas herramientas. Si escribe una PrintItfunción que toma cualquier objeto antiguo y lo llama .toString(), habrá reutilizado ese código tan pronto como lo llame con más de un tipo de objeto. Con estas herramientas, cada línea de código hace más.

La programación funcional es muy popular en este momento entre los hipsters. Le proporciona un conjunto de herramientas completamente separado para que cada línea de código haga más. Probablemente no sea mejor o no funcione, pero proporciona otra herramienta en la caja de herramientas.

(Había una idea loca para un nivel adicional de reutilización orientada a objetos: la idea era que pudiéramos definir una sola Customerclase y usarla en cada aplicación que escribimos. Entonces las aplicaciones serían un poco de pegamento aquí y allá. Esto no funcionó. Pero eso no significa que el OO falló, o incluso que la reutilización falló. Los tipos básicos de reutilización de código dentro de las aplicaciones hicieron posible escribir aplicaciones que hicieron más y escribirlas más rápido).


0

Leyendo las publicaciones anteriores, algunas observaciones:

  • Muchos piensan que la reutilización de código en OOP implica herencia. No estoy de acuerdo. Las interfaces y los contratos son el núcleo para la reutilización de código en los sistemas OOP. OOP es un intento de caja gris en la creación de una tecnología de componentes.
  • La diferencia entre "marcos" específicos de dominio y genéricos como tema de reutilización me parece demasiado abstracta. En mi opinión sobre las cosas, un componente (un contrato de interfaz conciso, mínimo y reutilizable y la implementación detrás) solo se puede hacer, si el problema que aborda se entiende bien. Un componente específico del dominio, que permite a los expertos que no pertenecen al dominio hacer su trabajo con menos conocimiento sobre el dominio, es un componente (re) útil. Los usuarios necesitan comprender la interfaz, menos las complejidades del dominio del problema.
  • Niveles de reutilización a menudo olvidados: reutilización de ideas, reutilización de especificaciones, reutilización de arquitectura / diseño, reutilización de interfaz, reutilización de casos de prueba. La reutilización del código no siempre es favorable. Pero a menudo es un gran ahorro de tiempo atenerse a una arquitectura específica para abordar un producto nuevo y similar.
  • Los patrones de diseño de OOP (Gamma et al.) En mis ojos elaboraron técnicas de implementación tácticas en lugar de ser significativas en el contexto de la reutilización del código a mayor escala. Ayudan a escribir una aplicación con elementos OOP, pero no los vería como una solución a la pregunta de "reutilización de código" más allá de una sola aplicación.
  • Tal vez no sea justo: 20 años de experiencia en C / C ++ / C # y 6 meses de programación funcional (F #). Un elemento importante para habilitar la reutilización es: las personas necesitan encontrar fácilmente "la interfaz", estudiarla, comprenderla y luego usarla. La programación funcional pura no me facilita ver la estructura, los candidatos para la reutilización o dónde comienza y dónde termina todo. El tan elogiado "azúcar sintáctico" a menudo es sal en mis ojos, lo que me impide ver fácilmente lo que sucede. Por lo tanto, es menos probable que intente reutilizar un funcional (¿qué es, un montón de funciones?), Que puede tener efectos secundarios ocultos que ni siquiera puedo ver (evaluación perezosa, mónadas, ...). No me malinterpreten, la programación funcional tiene aspectos muy interesantes, pero todas las fortalezas proclamadas las veo con bastante duda.
  • Las especificaciones, el diseño y la implementación están acoplados, pero no son vistas fácilmente transitables sobre la "misma cosa". Mucho más vital para una mayor productividad futura que un nuevo paradigma de programación es, para cerrar la brecha, aumentar (razonamiento automatizado, trazabilidad) los beneficios mutuos entre esas opiniones. Los lenguajes de especificación formalizados, las anotaciones de prueba estandarizadas (p. Ej., Ttcn3) y los lenguajes de programación que admiten la verificación de interfaces y contratos en contra de las especificaciones sin tirar comentarios pueden ser lo que más necesitamos con urgencia.

0

El problema es más sutil en mi humilde opinión:

  1. OOP es un gran método para estructurar código con estado mutable . Al encapsular el estado en objetos, el código de estado imperativo se vuelve más comprensible porque, por ejemplo, si una parte del estado se expresa como campos privados de una clase, usted sabe que al menos esta parte del estado en particular solo puede modificarse mediante métodos de este tipo. clase. (Y puede romper fácilmente este beneficio al abusar de la herencia, por cierto). Esto ahora es suficiente, pero mucho mejor que no tener ni siquiera esto.
  2. El código con estado mutable es intrínsecamente difícil de reutilizar . Mucho más difícil que el código utilizando estructuras de datos inmutables.

Por lo tanto, OOP en sí mismo no es malo desde el punto de vista de hacer código reutilizable , pero los tipos de código que se escriben usando OOP son intrínsecamente difíciles de reutilizar .

Además, la programación funcional puede dar como resultado un código más reutilizable . Pero obtener las abstracciones correctas para escribir un código funcional sensato mientras se cumple un plazo puede no ser factible. Y las abstracciones de "mitad derecha" serán más fáciles de expresar al estilo OOP. Y no tenderá a resultar en un código más fácil de reutilizar : un mayor nivel de abstracciones significa que la comprensión del código requerirá una mayor inversión inicial de la capacidad cognitiva limitada de los programadores.

Como ejemplo práctico: el código del juego implica mucho estado mutable, porque esta es la forma natural de pensar en la codificación de un juego, a menos que sea un rompecabezas / algoritmo, por lo que obviamente termina siendo estructurado usando OO. Y, por supuesto, es difícil de reutilizar. Pero el mismo código, que contiene el mismo conocimiento, sería aún más difícil de reutilizar sin OOP . Y reescribirlo para que sea un estilo funcional podría necesitar cambiar totalmente la forma en que piensas sobre ese código, el conocimiento detrás de él. Sí, el conocimiento resultante detrás del código sería mucho más claro después de la reescritura de OO a FP tal vez ... pero el costo podría ser enorme y podría serel tipo de costo que también tendrían que pagar las personas que deseen reutilizar el código increíblemente inteligente y bien abstraído con el que terminan , por lo que, paradójicamente, las personas terminarían sin reutilizar el código, incluso si técnicamente es más reutilizable.

... lo que lleva a la última sutileza: la reutilización del código se trata de la interfaz People | Code , no solo del código. OOP hace un trabajo decente al servir esta interfaz porque se correlaciona bien con cuántas personas piensan acerca de muchos tipos de código escritos hoy en día. FP podría ser mejor para la reutilización de código, pero en mi opinión, no para reutilizar fácilmente el tipo de código que la gente realmente necesita escribir hoy en día. Esto cambiará a medida que cambie el tipo de código que necesitamos para escribir.

PD Y si alguien quiere decir que "OO no se trata de estado mutable, también puede tener OO con estado inmutable" ... Yo llamo a eso "FP usando clases como espacios de nombres". Es excelente cuando funciona para usted y evita algunas deficiencias de los sistemas de módulos de algunos idiomas y puede dar como resultado un código más reutilizable. Pero eso no es OO;)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.