2009-03-27 16 views
7

Mantener las clases débilmente acopladas es un aspecto importante de la escritura de código que es fácil de comprender, modificar y depurar; eso lo entiendo. Como novato, sin embargo, casi cada vez que voy más allá de los ejemplos más simples que lucho.Prácticas de acoplamiento flojo y OO para principiantes

Entiendo, más o menos, cómo puedo encapsular cadenas, enteros y tipos de datos simples en clases propias. Sin embargo, cuando empiezo a tratar con información como el formato de texto enriquecido, las cosas se vuelven realmente complicadas, a menos que solo use los diversos métodos ya presentes en un componente. Para continuar con este ejemplo, supongamos que estaba escribiendo algo que incluye un componente de nota RTF en la interfaz de usuario. En Delphi, el componente tiene métodos integrados para hacer cosas como guardar texto formateado. Además, a veces parece que las únicas (o al menos mejores) formas de trabajar con el texto RTF son los métodos integrados en el componente.

¿Cómo (o por qué) haría todo el trabajo de guardar, cargar y formatear texto en otra clase cuando ya tengo un componente que hace todo esto por mí?

Por mi parte, suelo terminar (a) haciendo algo que parece mucho más complicado de lo necesario, reinventando métodos ya presentes, o (b) creando clases mal hechas que todavía están estrechamente acopladas entre sí. Como dicen en informercials, "¡Tiene que haber una mejor manera!"

Me acabo de perder conceptualmente sobre cómo funciona esa 'mejor manera'. ¿Alguna idea?

Respuesta

5

Te creo he echado de menos en algunos conceptos básicos.

La idea detrás de OOP comienza con unidades discretas y reutilizables de la lógica. Con énfasis en la creación de módulos autosuficientes.

En el caso del componente RTF Memo, cumple con los criterios anteriores al manejar un conjunto determinado de datos (la nota) de tal manera que su programa y otros objetos dentro de su programa no se preocupan por cómo funciona. trabajo. Su propósito es mostrar una interfaz, aceptar datos, manipular esos datos específicos y pasar esos datos a otra parte de su programa.

La idea detrás de ser loosely coupled es simplemente que puede reemplazar ese control memo por otro control que cumpla con las mismas especificaciones de interfaz. A saber, que puede instanciarlo, permitir que el usuario interactúe con él, y extraer los datos cuando sea necesario.

Siendo poco pareja va de la mano con la idea de Separation of Concerns (SoC); que es el proceso de dividir un programa en características distintas para reducir la funcionalidad de superposición y facilitar su administración. Pero no son lo mismo. Incidentalmente, este fue también uno de los principales impulsores detrás de alejarse del estilo de programación de procedimiento en OOP. Como OOP obliga a la programación a pensar en términos de funcionalidad relacionada y discreta.

Parece que realmente está preguntando por SoC.

Hay muchas maneras de lograr SoC. Algunas veces implica mantener separadas la UI, la lógica de procesamiento y las capas de persistencia (considere el patrón de diseño de MVC, por ejemplo). Algunas veces es simplemente mantener juntas las funciones relacionadas para reducir la complejidad; que el control RTF ya hace al contener todas las funciones necesarias para manipular los datos para que no tenga más dependencias.

0

Bueno, no estoy del todo claro con la pregunta, pero parece que el patrón de estrategia funcionaría aquí.

Construya un objeto basado en su objeto RTF principal pero establezca los métodos de manejo para el almacenamiento, etc. como objetos definidos con sus propios métodos.

Esto habilita el poder de la composición sin heredar estrictamente todos los métodos principales y no tiene que crear un gran objeto personalizado, solo reemplace los métodos que necesita.

5

Sugeriría dos conceptos, interfaces e inyección de dependencia, como una manera de desacoplar sus clases. Las interfaces le brindan una forma de definir un contrato o conjunto de comportamientos esperados que es independiente de cualquier implementación. Cuando tienes una clase que depende de una interfaz en lugar de una clase, tienes la libertad de sustituir a otras clases que implementan la interfaz sin tener que reescribir la clase que depende de ella.

Cuando utiliza interfaces con inyección de dependencia, es decir, le da a la clase la implementación real en la que debe trabajar en lugar de crear una implementación particular por sí mismo, logrará aún más desacoplamiento en su aplicación. Ahora la clase solo sabe sobre la interfaz y ni siquiera sabe cómo crearla, solo úsala. La inyección de dependencia a menudo se usa con patrones creacionales como Builder o Factory, donde se localiza la construcción de objetos en una sola clase, de modo que solo esa clase necesita cambios cuando se amplía la aplicación con clases adicionales.

Además, recuerde que el acoplamiento (y su gemelo, cohesión) es una medida relativa. No puede eliminar todos los acoplamientos o sus objetos no podrían interactuar. Tener cierto nivel de dependencia es necesario. También debe equilibrarlo con facilidad de uso e implementación.

En cuanto a su ejemplo particular, es difícil decirlo sin el código real. Sospecho que estás sobre-diseñando la solución y violando el principio DRY (no te repitas). Es posible que necesite buscar formas de utilizar interfaces y quizás una envoltura ligera para desacoplar sus clases del componente de marco en lugar de una reimplementación completa.

+0

No, en Delphi usted es mucho más probable que bajo-ingeniero –

0

El ejemplo que escogió es bastante complejo.

usted tiene razón cuando dice que el componente del memorándum rtf se acopla de manera muy informal. Tan vagamente, que prácticamente no se puede extender, y solo se puede usar tal cual, ya que integra la presentación/vista, el controlador y el modelo.

Si desea ver un ejemplo de un sistema de texto enriquecido extensible bien diseñado, eche un vistazo a la documentación del OS X text system (o Gnustep, si desea leer el código). Es complejo, porque hay muchas decisiones de diseño que deben tomarse y deben ocultarse de un módulo a otro. Allí puedes trabajar directamente en una buena estructura.

El componente del memorándum rtf tiene un alcance de uso limitado, que puede que tenga que evitar el uso de clases bien diseñados:

  • La carga y el almacenamiento de los datos de componentes sólo tienen sentido si no lo hace tiene que guardar otros datos en su programa en el mismo archivo/db.
  • Tampoco maneja bien grandes cantidades de datos.
  • Y solo comprende un pequeño subconjunto de rtf.