¿Tener muchos métodos duplicados y jerarquías de herencia profunda en las API de GUI (Java Swing, SDK de Android) viola los principios de diseño SOLID?

Pregunta:

Para aquellos que no están familiarizados con los principios SOLID, pueden comenzar a leer aquí: Artículo de Wikipedia . Sin embargo, la mayor parte de mi comprensión proviene de: http://www.objectmentor.com/resources/publishedArticles.html

De todos modos, parece que cada interfaz GUI con la que me encuentro en Java (incluso la de Adobe Flex, sinceramente) está llena de docenas de métodos que se duplican en muchas clases. Las jerarquías de herencia profundas son la norma y la composición definitivamente no se prefiere a la herencia . Esto parece ser una clara violación de SRP e ISP .

Lo que me gustaría saber es si tengo razón al pensar que estos marcos están violando los principios de diseño SOLID. Si es así, ¿por qué?

Respuesta a Muñeco de nieve

No estoy de acuerdo con que SWING sea un ejemplo de SÓLIDO. Usemos el ejemplo de JButton:

1) SRP: el método isDoubleBuffered va más allá de la responsabilidad de JButton para representar un botón de interfaz de usuario. Ese método representa un detalle de implementación que no tiene nada que ver con el concepto abstracto de un botón de interfaz de usuario.

2) OCP: si quiero cambiar la forma en que JButton maneja los eventos, tengo que reemplazar la clase JButton por completo.

3) LSP: la implementación de JButton no se puede sustituir fácilmente con otras implementaciones. JButton hereda la mayoría de sus detalles de implementación directamente. Si quiero cambiar la forma en que un JButton crea información sobre herramientas, asigna detectores de acciones o accede al contexto de gráficos, tengo que desechar todo SWING. No puedo simplemente agregar una nueva clase que maneje esas cosas ya que JButton hereda directamente de JComponent.

4) ISP: la interfaz pública de JButton está plagada de docenas de métodos de cada clase de la que hereda. Literalmente, es un grupo de volcado de métodos públicos de JComponent, Container, Compound, etc. Si la interfaz de JButton se adhiriera al ISP, solo habría unos 10 métodos expuestos públicamente.

5) DIP: JButton expone públicamente los métodos de sus detalles de implementación concretos. Si aplicara una verdadera inversión de dependencia, cosas como íconos, diseño, manejo de eventos, etc. se delegarían en clases separadas que el usuario podría cambiar fácilmente para lograr una nueva funcionalidad.

Respuesta:

En general, no estoy de acuerdo con que los marcos de GUI violen SOLID . Puede haber excepciones, pero esto resume mi experiencia con múltiples marcos:

  • SRP: una clase de GUI normalmente tiene una responsabilidad. Tal vez esté respondiendo a un evento, representando un objeto o tal vez "representando este elemento de la interfaz de usuario". Este último puede parecer que no es una responsabilidad "única" porque esa responsabilidad es unir todo (por ejemplo, JButton o JPanel ). La clave a buscar es esos objetos "grandes" que a menudo se delegan a otros objetos que están especializados y manejan un aspecto del objeto en detalle (manejo de eventos, representación, etc.).

  • Abierto/Cerrado: su ejemplo muestra cómo las clases de interfaz de usuario están definitivamente abiertas para la extensión: hay mucha herencia en curso. Se podría argumentar que las clases de interfaz de usuario violan el aspecto de "cerrado para modificación", ya que normalmente son muy configurables y se pueden modificar para hacer muchas cosas de manera diferente, pero para empezar, ese es uno de los propósitos de estas clases.

  • Sustitución de Liskov: en casi todos los marcos que he visto, las subclases agregan más funcionalidad y aún permiten el comportamiento de la clase principal. No siempre tiene sentido, pero es compatible. Por ejemplo, podría anidar elementos de la interfaz de usuario dentro de un botón si extiende un marco (quizás se podría agregar un ícono a un botón de esta manera, un elemento de imagen anidado dentro de un botón a pesar de que el "botón" no se considera comúnmente como un elemento principal ). Este principio es clave para la naturaleza anidada de los marcos de interfaz de usuario.

  • Segregación de interfaz: mi principal experiencia aquí es con Java, donde hay muchas pequeñas interfaces para varios oyentes y controladores. Parece un buen ajuste.

  • Inversión de dependencia: junto con el argumento de Liskov, muchos marcos se basan en abstracciones. Por ejemplo, puede haber una interfaz de alto nivel o una clase abstracta para representar todos los componentes de la interfaz de usuario. Los componentes principales pueden aceptar cualquier componente de alto nivel como un elemento secundario, lo que permite diseños arbitrariamente complejos a través del anidamiento.

En general, creo que hay un fuerte argumento para que los marcos de GUI se adhieran a SOLID.

Leave a Comment

Your email address will not be published.

Scroll to Top

istanbul avukat

-

web tasarım