2009-01-28 12 views
5

Tengo una clase A que implementa muchas funciones. La clase A es muy estable.Refactorización de una clase en C++

Ahora tengo un nuevo requisito de función, parte de cuya funcionalidad coincide con la implementada por A. No puedo heredar directamente mi nueva clase de la clase A, ya que eso traería mucha redundancia a mi nueva clase.

Entonces, ¿debería duplicar el código común en ambas clases?

O, ¿debería crear una nueva clase base y mover el código común a la clase base, y derivar la clase A y la nueva clase de ella? Pero esto llevará a cambios en mi clase existente.

Entonces, ¿cuál sería un mejor enfoque?

+0

¿No se copiará la clase para crear aún más redundancias en el código? – mmmmmmmm

Respuesta

16

A menos que haya una muy buena razón para no modificar la clase A, refactorizar y hacer una base común (o mejor aún, una clase común que ambos puedan usar, pero no necesariamente derivar de).

Siempre puede usar la herencia privada para obtener acceso a la funcionalidad compartida sin modificar la clase Como interfaz externa: este cambio requeriría una reconstrucción, pero nada más. Deje todas las funciones en la clase A, y solo haga que se reenvíen a la clase de implementación compartida.

Una razón por la que quizás no desee refactorizar, sino que copie el código si es probable que la funcionalidad de la nueva clase cambie, pero sin que se necesite el mismo cambio en la clase anterior. Una de las razones para no duplicar el código es que una corrección o un cambio solo necesitan realizarse en un solo lugar. Si van a ocurrir cambios que rompan la clase original, entonces quizás quieras copiar el código. Aunque en la mayoría de los casos, esto solo ocurrirá si las dos clases no son tan similares como creías, y estarías luchando para tratar de abstraer un conjunto común de funcionalidades.

+0

Tienes razón. Mi nueva implementación de clase probablemente cambie en el futuro y puede que no comparta la misma implementación con la clase A. – chappar

+0

Por supuesto, todavía es mejor que muevas las cosas comunes a una clase en algún lado y usas eso mientras tanto. – Eclipse

+0

+1 para decir que el código común podría ir en una clase utilizada por A y B en lugar de estar en una clase base de A an B. –

8

(1) No duplique el código común en ambas clases a menos que usted o su empleador estén preparados para mantener ambas copias indefinidamente.

(2) La refabricación por definición cambia las clases que ya tiene. El refactorizador que propone se llama "Extract SuperClass" seguido de "Pull Up Method" para cada método que sea común a las clases derivadas. Este es un buen enfoque.

Editar: Recordé la verdadera gema detrás de Refactoring: dentro de lo razonable, es perfectamente fluido y reversible. Nunca hay un "Derecho", solo hay un "Derecho por ahora". Si más adelante decide que usar la herencia para estas clases no es un buen modelo de objetos, entonces puede refactorizar nuevamente para usar la composición (como lo sugiere magníficamente Josh).

1

Las clases deben compartir una clase base común si se pretende que las clases sean sustituibles (la relación "IS-A").

Puede considerar la composición. Su nueva clase B podría ser una clase contenedora alrededor de una variable miembro privada de tipo clase A. La clase B podría aumentar la clase A con nuevos métodos o lógica sin cambiar la clase A. Esto es conveniente si no puede cambiar la clase A (por ejemplo, software de código cerrado, propiedad de otro equipo, o tiene miedo de romper la compatibilidad con el código existente usando la clase A).

Para un buen diagrama, vea "Replace Inheritance with Delegation" patrón de refactorización.

Cuestiones relacionadas