Actualmente tengo dos clases derivadas A
y B
ambas tienen un campo en común y estoy tratando de determinar si debería subir a la clase base.
Nunca se hace referencia desde la clase base, y digamos que si en algún momento en el camino se deriva otra clase C
, que no tiene un _field1
, entonces no se violaría el principio de "menos privilegiado" (o algo) si ¿fue?
public abstract class Base
{
// Should _field1 be brought up to Base?
//protected int Field1 { get; set; }
}
public class A : Base
{
private int _field1;
}
public class B : Base
{
private int _field1;
}
public class C : Base
{
// Doesn't have/reference _field1
}
Base
,A
,B
,C
, y_field1
son. Esos son detalles importantes que no deben dejarse de lado; Creo que deberías editar la pregunta para hablar sobre cuáles son.Respuestas:
Todo depende del problema exacto que intente resolver.
Considere un ejemplo concreto: su clase base abstracta es
Vehicle
y actualmente tiene implementaciones concretasBicycle
yCar
. Estás considerando mudartenumberOfWheels
desdeBicycle
yCar
hacia el vehículo. ¿Deberías hacer esto? ¡No! Porque no todos los vehículos tienen ruedas. Ya puede decir que si intenta agregar unaBoat
clase, entonces se romperá.Ahora, si su clase base abstracta era
WheeledVehicle
entonces es lógico tener lanumberOfWheels
variable miembro allí.Debe aplicar la misma lógica a su problema, porque como puede ver, no es una respuesta simple de sí o no.
fuente
roll()
método, momento en el cual la idea de la subclase parece premonitoria.Hablando lógicamente, más allá de colocar el campo replicado en subclases versus en común en la clase base, hay una tercera opción: que es introducir una nueva subclase en la jerarquía que tiene las propiedades comunes entre los dos. @Pete insinúa esto sin ir completamente allí.
Usando el ejemplo de @Pete, introduciríamos una subclase (posiblemente abstracta) para Vehículo con ruedas que desciende de la clase base original, mientras que las dos subclases descienden de ella. Por lo tanto, la clase base original no está contaminada con ruedas, pero la característica común de las ruedas es SECA (no se repite entre las subclases que tienen ruedas).
Esto puede, por supuesto, ser excesivo para sus propósitos, pero el mecanismo de jerarquía de clases lo admite.
fuente
Voy a jugar al abogado del diablo aquí.
En este momento no deberías hacer nada .
¿Está SECO? No. Pero es mejor tener un poco de duplicación que una abstracción prematura de la que no pueda retroceder fácilmente más adelante. El refactor para mover una propiedad a una clase base común es fácil. Ir por el otro lado no lo es. Espera y verás.
Cuando tomo este tipo de decisión, tiendo a usar una "regla de 3": una vez que he repetido lo mismo, por ejemplo, en tres lugares diferentes, y solo entonces, considero subirlo por la cadena. Nota: solo tienes 2 años.
fuente
En general, lo movería a la clase base. No creo que haya un objetivo sí / no, porque hay una compensación aquí: llevar campos no utilizados frente a reducir la complejidad.
Por lo general, prefiero las clases base 'pesadas' que contienen cualquier cosa que pueda compartirse. Esto simplifica la serialización de archivos ya que no necesita métodos de serialización descendientes en cada clase derivada. Pero si no tiene ese problema o un problema similar, o tal vez necesita hacer todo lo posible para reducir el uso de memoria, entonces solo mantener los campos donde los necesita debería estar bien.
Una clase 'intermedia' que introduce los campos comunes estará bien si tiene un número muy limitado de campos. Pero tenga en cuenta que el enfoque puede aumentar drásticamente la complejidad si tiene docenas de campos utilizados en diferentes combinaciones, lo que lleva a muchas clases intermedias, cada una de las cuales introduce un conjunto específico de campos. Eso puede convertirse en un problema de mantenimiento.
fuente