En nuestra aplicación Rails, estamos agregando notificaciones. Algunos de estos son blocking
: detienen el progreso de cualquier recurso en el que se agreguen, porque falta información sobre ese recurso.
Otras notificaciones son notificaciones simples y solo proporcionan información.
Hoy tuve una discusión con otro programador de nuestro equipo. He creado la estructura de herencia de esta manera:
Sin embargo, prefiere que solo agregue blocking
como un método de retorno booleano en cada Notificación y especifique una lista de subclases que están bloqueando dentro de la clase principal de Notificación.
La diferencia entre estos enfoques no es muy grande; En mi enfoque, uno no tiene que especificar esta lista, manteniendo limpia la clase raíz. Por otro lado, la lógica especial que ocurre en Notification::Blocking
este momento tampoco es muy grande.
¿Qué tipo de abstracción es más adecuada para este problema?
Respuestas:
Desea evitar que las clases base conozcan las clases derivadas. Presenta un acoplamiento estrecho y es un dolor de cabeza de mantenimiento porque debe recordar agregar a la lista cada vez que cree una nueva clase derivada.
También evitará que pueda colocar la clase de Notificación en un paquete / ensamblaje reutilizable si desea utilizar esta clase en múltiples proyectos.
Si realmente desea utilizar una sola clase base, otra forma de resolver esto es agregar una propiedad virtual o método IsBlocking en la clase de notificación base. Las clases derivadas podrían anular eso para devolver verdadero o falso. Tendría una solución de clase única sin que la clase base conozca las clases derivadas.
fuente
Eso se ve muy peculiar y es un código de olor particular.
Proporcionaría subclases si tiene diferencias de comportamiento entre las clases y desea tratar todas estas notificaciones de la misma manera (es decir, utilizando polimorfismo ).
fuente
Como respuesta a las respuestas existentes, sugeriría que la propiedad booleana es la mejor opción si se requiere cambiar dinámicamente el modo que se utilizará (por ejemplo, a través de un archivo de configuración que proporciona una lista de los tipos que se van a bloquear y que no lo son).
Dicho esto, un mejor diseño incluso en esta situación podría ser usar un objeto Decorador.
fuente
Diría que depende de cuánto más sea especial acerca de una notificación de bloqueo, aunque mi primer pensamiento es ir con "ambos":
De esa manera, puede usar
n.Blocking
on is BlockingNotification
(todo en pseudocódigo), aunque, si va a permitir que una clase implemente unBlocking
valor sensible al contexto , ya que tendría que verificar ese valor cada vez, laBlockingNotification
clase se convierte en Menos útil.En cualquier caso, estoy de acuerdo con las otras respuestas que no desea que la implementación de la clase base
Blocking
tenga que saber sobre las clases derivadas.fuente
En lugar de hacer dos clases base y múltiples instancias de cada una, haga una clase de notificación con un bool para indicar si la notificación está bloqueando y cualquier otra información necesaria para comunicar la notificación al usuario.
Esto le permite usar un conjunto de código para procesar y presentar notificaciones y reduce la complejidad de su código.
fuente