Este es un problema de diseño que sigo encontrando, así que pensé que finalmente lo sacaría y vería cómo las personas se acercarían a él. El problema es el siguiente:OO design: manejo genérico de las subclases que introducen nuevos campos
Identifico una determinada clase que en su mayor parte describe todas las instancias de objetos que utilizaré, tanto en el comportamiento como en los datos. Eso es genial y funciona bien para objetos básicos. Luego surgen otros tipos de objetos que necesitan los mismos datos y el mismo comportamiento, pero también desean tener un campo adicional aquí o allá o una estructura de datos adicional.
Vamos a llamar a la clase algo :
public class Something {
private int id;
private String fieldA;
private String fieldB;
private List<Data> list;
// Then we have getters, setters, and some base methods
}
A veces tendrá que utilizar somethingelse y somethingdifferent. Son 90% como Algo en que los mismos datos y el comportamiento de los describe, sin embargo cada uno de ellos, además, han campos adicionales que deben ser utilizados por el resto del programa:
public class SomethingElse extends Something {
private String dataSpecificToSomethingElse;
// Then we have getters, setters, and some new-data specific methods
}
public class SomethingDifferentextends Something {
private List<DifferentData> dataSpecificToSomethingDifferent;
// Then we have getters, setters, and some new-data specific methods
}
me gustaría llegar con una forma decente de manejar la familia de objetos Something de forma genérica OO, ya que no me gustaría vincular el resto de mi aplicación a los detalles concretos de implementación (porque es posible que necesitemos agregar SomethingWacky más adelante). No quiero tratar directamente con las subclases, ya que eso rompe el polimorfismo, y probablemente incluirá la necesidad de abatir/hacer un cambio de tipo - ¡puaj!
Los enfoques que se me ocurre para resolver esto son las siguientes:
- crear una clase base abstracta que define todos los métodos para la Algo familia. Luego, los niños solo implementan el comportamiento que les preocupa proporcionar, dejando un NOP/anulación en blanco para los métodos que no son motivo de preocupación. Esto permite que todo se trate de la misma manera, pero introduce la hinchazón de la interfaz.
- Mueva la responsabilidad a la clase base a través de métodos de trabajador genéricos, siguiendo Tell, Don't Ask. Por ejemplo, esto podría ser cosas como display(), doWork(), persist(), getStateFromDisplay(), etc. Cada subclase tendría en cuenta sus datos al anular estos métodos base. Leí un artículo de Allen Holub recientemente que sugería que algo así podría ser una buena práctica. Esto parece estar transfiriendo demasiada responsabilidad a las preocupaciones externas de la clase.
- Crea un tipo de clase de datos que agrupe todos los datos/comportamientos adicionales de las subclases, y refiérase a eso en Algo. Esto no se siente muy parecido a OO.
He usado enfoque 1 durante un proyecto anterior -, pero en ese caso a pesar de que cada subclase única implementado/hizo caso omiso de los métodos que se preocupaba, las operaciones eran en realidad lo suficientemente genérica por lo que era posible que una clase podría coherentemente implementar todos o solo algunos.
Cada enfoque se siente sucio de una manera y realmente no me gusta ninguno. ¿Cuáles son mis alternativas? Tal vez estoy haciendo un uso indebido de la herencia o acercándome a esto de la manera equivocada por completo. Estoy abierto a cualquier sugerencia y me gustaría aprovechar las técnicas de OO para obtener diseños más limpios y desacoplados. Realmente me gustaría saber cómo las personas han resuelto problemas como este, y cualquier recurso al que me puedas remitir sería muy apreciado.
Gracias
Re # 2: si su clase persiste, ¿no está violando la Responsabilidad individual? Necesito saber más sobre el contexto, pero me parece que está usando en exceso la herencia, si realmente necesita hacer cosas diferentes con 'SomethingElse', ¿debería ser realmente una subclase? – David
No persiste. Solo estaba tratando de enumerar comportamientos de ejemplo que moverían las preocupaciones externas dentro de la clase, y violarían a SRP como usted dice. Las subclases en realidad no hacen nada diferente, solo tienen información adicional para cuidar ... –