2011-02-18 7 views
6

Tengo dos clases que implementan ISomeBehavior. Ahora quiero que compartan la funcionalidad. Normalmente reemplazaría ISomeBehavior con una clase abstracta, como SomeBehaviorBase. El problema es que una de las subclases ya deriva de otra clase, y esa otra clase no es un software que poseemos. (Esto es C#, por lo que la herencia múltiple no es una opción). La subclase, que se deriva de la clase de terceros, no tiene implementación. Simplemente deriva de la clase de terceros e implementa ISomeBehavior, por lo que la clase de terceros se puede tratar de la misma manera que las otras subclases que implementan ISomeBehavior.¿Cómo pueden las subclases compartir el comportamiento cuando uno ya se deriva de una clase base diferente?

Lo que he hecho, por el momento, es implementar un método de extensión en ISomeBehavior. Ahora el código de consumo puede llamar al método. El problema con ese enfoque es que quiero obligar al código de llamada a usar este método de extensión. No puedo eliminar SomeMethod() de la interfaz, porque el método de extensión tiene que llamarlo finalmente.

¿Alguna idea sobre cómo permitir que dos clases compartan elegantemente el mismo comportamiento, cuando una de ellas ya proviene de otra clase de terceros? Nota: El patrón de diseño de estrategia suena como si tuviera sentido aquí, pero ese patrón se usa cuando el comportamiento varía entre las subclases. El comportamiento aquí no varía; solo necesita ser compartido. no http://www.codeproject.com/KB/architecture/smip.aspx

GJ

+0

¿Qué es SomeMethod()? Solo lo menciona en el segundo párrafo, diciendo que no puede eliminarlo, pero sin dar ninguna idea sobre * por qué * desea eliminarlo. –

+0

Quiero eliminar SomeMethod() para que el código del cliente no pueda usarlo. El método de extensión lo llamará sin embargo. Y el código del cliente llamará al método de extensión. El método de extensión es básicamente SomeMethod(), pero con dos parámetros adicionales. Esto permite que la extensión SomeMethod() realice algunos procesos antes de llamar a SomeMethod. –

Respuesta

5

alguna razón no se puede utilizar en lugar de la composición delegado de ejecutar la clase que deriva actualmente de la clase 3 ª parte:

+0

Eso significaría que la subclase implementaría la interfaz y simplemente llamaría a los mismos métodos en la clase de terceros. ¿Está bien? Entonces esa subclase también necesitaría tener una referencia a la clase de terceros. Puedo darle una oportunidad. –

+0

@Bob: Sí, eso es exactamente. –

+0

Gracias. Puedo darle una oportunidad y ver cómo funciona.Ese comentario simulado de herencia múltiple, arriba, es intrigante. Quiero verificar eso también. –

2

He aquí un buen artículo sobre este tema? Simplemente delegue todos los métodos de interfaz a una instancia de la clase de terceros. De esta manera, si desea agregar funcionalidad, puede usar una clase base común.

Esto no funcionará en algunos casos donde la identidad del objeto es relevante, pero en muchos casos es un diseño perfectamente razonable.

+0

Buen enlace y tema, pero hay algunas complejidades y desventajas allí que no quiero tratar. Gracias. –

0
public interface ISomeBehavior 
    { 
     int Sample(); 
    } 

    public class A : ISomeBehavior 
    { 
     int ISomeBehavior.Sample() 
     { 
      return 1; 
     } 
    } 

    static class SomeExtension 
    { 
     public static int Sample(this ISomeBehavior obj) 
     { 
      return 2; 
     } 
    } 

y luego utilizar este

A a = new A(); 
    var a1 = ((ISomeBehavior)a).Sample(); // a1 = 1 
    var a2 = a.Sample();      // a2 = 2 
0

¿Qué tal algo como esto:

class MyClass: ThirdPartyClass 
{ 
} 

class MyFunctionality 
{ 
    public MyFunctionality(ThirdPartyClass target) 
    ... 
} 

interface IMyFunctionality 
{ 
    public MyFunctionality MyFunctionality; 
} 

lo que la interfaz haría cumplir que la clase derivada tiene que crear una instancia del complemento de miembro, y el diseño de MyFunctionality simplemente operaría contra una referencia a la clase base. Sin embargo, esto podría no funcionar si hay miembros protegidos a los que se necesita acceso interno.

+0

No deseo que la interfaz ejecute la instanciación de la clase de terceros, porque solo tiene sentido para * una * de las subclases. –

+0

Solo implementaría la interfaz en la subclase donde la usó. Quiero decir, podrías agregar un miembro de tipo "MyFunctionality" en la subclase y no usar una interfaz, pero creo que tener una interfaz expresa mejor la intención del diseño. –

Cuestiones relacionadas