¿Cómo evito escribir muchas funciones de paso en un contenedor?

13

Tengo una clase, que envuelve otra clase de un tipo base común. Debido a que la interfaz de tipo base es bastante grande, esto implica escribir muchas funciones de paso. Estoy buscando una manera de evitar esto.

Hagamos un ejemplo:

      Car
     /   \
Volvo     VolvoWithTrailer

Ahora tengo que implementar todas y cada una de las funciones en la interfaz del auto para VolvoWithTrailer y llamar a la función apropiada en el objeto Volvo envuelto, excepto quizás GetMaxSpeed (), que devolverá algo más bajo. Básicamente tendré muchas funciones como

int VolvoWithTrailer::GetNumSeats() {
  return mVolvo.GetNumSeats()
}

Una forma obvia de resolver esto sería hacer de VolvoWithTrailer una subclase de Volvo

    Car
     |
   Volvo
     |
VolvoWithTrailer

pero eso parece violar el principio de favorecer la composición sobre la herencia.

¿De qué otra manera podría evitar escribir todos esos envoltorios (el lenguaje es C ++)? O, si esa es su posición, ¿por qué debería escribirlas o simplemente usar la herencia? ¿Hay alguna plantilla mágica que pueda ayudar con esto?

    
pregunta Sarien 22.04.2013 - 23:30

2 respuestas

5

Mi opinión es que debes escribir lo que necesites escribir para mejorar la estabilidad y el mantenimiento del programa a largo plazo. ¿Qué sentido tiene evitar escribir 20 líneas de código hoy, si cada vez que toca algo que usa este código o regresa para mantener esta Clase, le cuesta 5 minutos adicionales o más porque no invirtió el tiempo hoy?

Entonces, la pregunta se convierte en "¿qué necesitas escribir?" No creo que proporcione suficiente información para poder dar una respuesta definitiva, así que solo enumeraré algunas cosas en las que I pensaría al tomar una decisión:

1. ¿Necesita tener el objeto Trailer solo, ahora o en un futuro previsible?
Si es así, tiene un argumento bastante bueno para hacer la envoltura alrededor de ambos objetos compuestos, ya que ya tendrá que envolver uno u otro. También podría ser consistente.

2. ¿Alguno de los tres tipos (Car, Trailer, CarWithTrailer) está en un área del código en el que los desarrolladores escriben frecuentemente o parece que no?
Si es así, tenga mucho cuidado, ya que las ramificaciones de elegir una cosa incorrecta pueden ser amortizadas muy costosa cada vez que se toca el código. Si no, puede que no haya ninguna diferencia en lo que decida. Solo elige una dirección y ve con ella.

3. ¿Qué es más fácil de entender?
¿Acaso un enfoque te llama la atención de que alguien que viene detrás de ti "comprenda" inmediatamente lo que intentas hacer? ¿Sus compañeros de equipo tienen sesgos particulares que podrían dificultar el mantenimiento de un enfoque? Si todas las cosas son iguales, elija la solución que imponga la carga cognitiva más baja.

4. ¿Existen ventajas adicionales al utilizar un enfoque sobre otro?
Una cosa que me sorprende es que la idea de la envoltura tiene una clara ventaja si escribe que su CarWithTrailerWrapper puede envolver cualquier coche y cualquier en un CarWithTrailer. Luego, termina escribiendo todos sus métodos de transferencia, pero solo los escribe una vez , en lugar de una vez para cada clase de automóvil.

Esto hace que su inversión inicial en escribir los métodos de transferencia sea mucho más barata a medida que agrega más carros y remolques. También ayuda a reducir la tentación de acoplar cosas directamente al Volvo o VolvoWithTrailer, al tiempo que reduce las consecuencias del acoplamiento al CarWithTrailerWrapper, ya que puede hacer mucho más con solo esa implementación.

Tal vez hay ventajas distintas que obtendrías gratis al usar el método de extensión, pero no las veo.

Bien, entonces parece que me he hablado para seguir adelante y completar los métodos de transferencia, para aplicaciones no triviales.

No soy un programador de C ++, por lo que no tengo idea de qué herramientas de generación de código están disponibles para usted. El IDE que uso puede generar métodos desde una interfaz, y puedo agregar código Plantillas que harían que la escritura de los textos sea bastante sencilla. Si no tiene acceso a un IDE que hace esto, puede llegar bastante lejos permitiendo que Excel escribe el código para ti .

    
respondido por el Amy Blankenship 23.04.2013 - 03:53
3
  

Debido a que la interfaz de tipo base es bastante grande, esto implica escribir muchas funciones de paso.

Y ahí está tu problema.

Las interfaces deben manejar una sola responsabilidad. Mantenerlos delgados y concentrados limita la cantidad de trabajo de paso que podría necesitar hacer en caso de un decorador, proxy u otra envoltura (además de hacer que el simpiler de la clase use, pruebe, mantenga y extienda).

    
respondido por el Telastyn 22.04.2013 - 23:36

Lea otras preguntas en las etiquetas