2011-02-18 28 views
6

ISomeBehavior uygulamasını uygulayan iki sınıfa sahibim. Şimdi işlevsellik paylaşmalarını istiyorum. Normalde, ISomeBehavior yerine, SomeBehaviorBase gibi soyut bir sınıfla yer değiştirirdim. Sorun, alt sınıflardan birinin zaten başka bir sınıftan türediği ve diğer sınıfın sahip olduğumuz bir yazılım olmadığıdır. (Bu C#, çok sayıda miras, bir seçenek değildir.) 3. parti sınıfından türeyen alt sınıfın hiçbir uygulaması yoktur. Sadece 3. parti sınıfından türetilir ve ISomeBehavior uygular, böylece 3. taraf sınıfı ISomeBehavior'ı uygulayan diğer alt sınıflarla aynı şekilde ele alınabilir.Alt sınıflar, zaten farklı bir temel sınıftan türetildiğinde davranışları nasıl paylaşabilir?

Şu an için yaptığım, ISomeBehavior üzerinde bir uzantı yöntemi uygular. Şimdi tüketen kod yöntemini çağırabilir. Bu yaklaşımdaki sorun, bu kodlama yöntemini kullanmak için çağrı kodunu zorlamak istemem. Uzantı yönteminin sonunda çağırması gerektiğinden, SomeMethod() öğesini arabirimden kaldıramıyorum.

iki sınıfları zarif aynı davranışı paylaşmasına izin konusunda herhangi bir fikir, bir tanesi zaten başka türetilmiştir, üçüncü şahıs, sınıf? Not: Strateji tasarım deseni, buradaki mantıklı gibi görünür, ancak bu model, alt sınıflar arasında davranışı arasında değiştiğinde kullanılır. Buradaki davranış farklı değil; Sadece paylaşılması gerekiyor. http://www.codeproject.com/KB/architecture/smip.aspx

GJ

+0

SomeMethod() nedir? Bunu yalnızca ikinci paragrafta, bunu kaldıramayacağınızı söylüyorsunuz - ama neden * hakkında bir fikir vermeden * bunu kaldırmak istersiniz. –

+0

SomeMethod() öğesini kaldırmak istiyorum, bu nedenle istemci kodu kullanamaz. Uzantı yöntemi buna rağmen arayacaktır. Ve istemci kodu uzatma yöntemini çağırır. Uzantı yöntemi temelde SomeMethod(), ancak iki ek parametredir. Bu, SomeMethod() 'ın SomeMethod'u çağırmadan önce bazı işlemleri yapmasına izin verir. –

cevap

5

şu anda 3. parti sınıfından türetilmiş sınıf uygulamak yerine heyetinin kompozisyonu kullanamaz herhangi bir neden var mı:

+0

Bu, alt sınıfın arabirimi uygulayacağı ve üçüncü taraf sınıfında aynı yöntemleri çağırdığı anlamına gelir. Bu doğru mu? Daha sonra bu alt sınıfın üçüncü parti sınıfına da bir referans göstermesi gerekecektir. Bunu bir şans verebilirim. –

+0

@Bob: Evet, tam olarak bu. –

+0

Teşekkürler. Bunu bir atış yapabilir ve nasıl çalıştığını görebilirim.Yukarıdaki simüle edilmiş çoklu kalıtım yorumu ilgi çekicidir. Bunu da kontrol etmek istiyorum. –

2

İşte bu konuda iyi bir makale? Tüm arayüz yöntemlerini üçüncü parti sınıfının bir örneğine aktarın. Bu şekilde, işlevsellik eklemek istiyorsanız ortak bir temel sınıf kullanabilirsiniz.

Bu, nesne kimliğinin alakalı olduğu bazı durumlarda işe yaramaz, ancak çoğu durumda mükemmel bir tasarımdır.

+0

İyi bağlantı ve konu, ama uğraşmak istemediğim bazı karmaşıklıklar ve eksiler var. Teşekkürler. –

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; 
     } 
    } 

ve sonra kullanmak bu

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

Nasıl böyle bir şey hakkında:

class MyClass: ThirdPartyClass 
{ 
} 

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

interface IMyFunctionality 
{ 
    public MyFunctionality MyFunctionality; 
} 

Yani arayüzü, türetilmiş sınıf eklentiyi üyesi örneğini gerektiğini zorunlu olacak ve MyFunctionality'nin tasarımı sadece temel sınıfa yapılan bir referansa karşı çalışır. Yine de, iç erişime ihtiyacınız olan korumalı üyeler varsa bu işe yaramayabilir.

+0

Arabirimin üçüncü parti sınıfının örneklemesini zorlamasını istemiyorum, çünkü alt sınıfların yalnızca bir * için * mantıklı. –

+0

Yalnızca arayüzü, onu kullandığınız alt sınıfta uygularsınız. Yani, alt sınıfta "MyFunctionality" türünde bir üye ekleyebilir ve bir arayüz kullanamazsınız, ancak bir arayüzün tasarım amacını daha iyi ifade ettiğini düşünüyorum. –