Pregunta

Estoy tratando de convencer a un colega de que una función debe tomar una interfaz como parámetro y no el objeto en sí. Pienso que los objetos pequeños pueden pasar bien, pero para los grandes les daría una interfaz y solo pasarían el i / f, no todo.

Tenga en cuenta que solo habrá una de estas clases grandes: el i / f nunca se usará para un objeto diferente. Esto es simplemente para ocultar la implementación de un objeto.

¿Estaría de acuerdo en que separar una clase grande en una interfaz (es) es una buena práctica?
¿Hay alguna desventaja al hacer esto?

Ejemplo:

public interface class IVeryLargeClass
{
    void DoSomething();
    ...
};

public ref class VeryLargeClass : public IVeryLargeClass
{
public:
    virtual void DoSomething() { ... }
    ...
};

public ref class AnotherClass
{
public:
    AnotherClass(VeryLargeClass^ vlc)  { vlc->DoSomething(); }
 // OR
    AnotherClass(IVeryLargeClass^ vlc) { vlc->DoSomething(); }
};
¿Fue útil?

Solución

Uno de los primeros principios que aprende en el desarrollo OO:

  

Programa para una interfaz, no un   implementación.

Indicas que " solo habrá una de estas clases grandes, la i / f nunca se usará para un objeto diferente " ;. Esto podría ser cierto en su caso, pero me gustaría tener un centavo por cada vez que tal declaración resultó ser errónea.

Además de considerar si puede haber múltiples implementaciones de su interfaz, también debe considerar si su objeto concreto exporta (o podría exportar) métodos adicionales que no comparten una afinidad lógica con las operaciones declaradas en la interfaz. En tal caso, simplemente puede declarar las operaciones adicionales en una o más interfaces adicionales. Un cliente, entonces, solo necesita acoplarse con la interfaz que exporta las operaciones en las que está interesado.

En pocas palabras, las interfaces proporcionan un medio para gestionar el acoplamiento entre clientes y proveedores.

Otros consejos

El Principio de inversión de dependencia se puede resumir como: Es mejor Depende de las abstracciones que de las concreciones.

Casi siempre es mejor pasar una interfaz que pasar una clase concreta.

Dicho esto, la alta cohesión contra los tipos internos está bien dentro de un módulo en particular, pero eso es muy subjetivo en cuanto a cuándo y cómo debe pasar objetos concretos.

Prefiero evitar crear e interactuar por crear una interfaz. Si puede usar esa interfaz en más de un lugar, entonces tiene un ganador, o si se trata de una función pública y una clase y desea simplificar específicamente.

Si pasa una implementación, pierde una de las ventajas de usar interfaces, lo que significa separar la lógica de la implementación real.

  

La interfaz de un módulo de software A   se mantiene deliberadamente separado del   Implementación de ese módulo. los   este último contiene el código real de la   procedimientos y métodos descritos en   la interfaz, así como otros   " privado " variables, procedimientos, etc.   Cualquier otro módulo de software B (que puede   ser referido como un cliente a A) que   interactúa con A se ve obligado a hacerlo   Sólo a través de la interfaz. Uno   ventaja práctica de esto   arreglo es que la sustitución de la   implementación de A por otro   que cumple con las mismas especificaciones de   la interfaz no debería causar que B   Fallo & # 8212; siempre que su uso de A cumpla   con las especificaciones de la   interfaz (ver también Liskov   principio de sustitución).

http://en.wikipedia.org/wiki/Interface_(computer_science)

El otro problema es tu clase muy grande. Esto puede no estar dentro del alcance de lo que está haciendo, pero una clase muy grande implica que podría estar haciendo demasiado en primer lugar. ¿Puede refactorizarlo en clases más pequeñas, donde la información requerida dentro de la función a la que llama está encapsulada en su propia clase más pequeña? Si creas una interfaz contra esa clase, puedes encontrarla mucho más reutilizable que contra la clase más grande que tienes actualmente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top