Un'alternativa all'ereditarietà multipla quando si crea un livello di astrazione?

0

Nel mio progetto sto creando un livello di astrazione per alcune API. Lo scopo del livello è rendere la multi-piattaforma più semplice e anche semplificare le API al set di funzionalità di cui ho bisogno, fornendo al contempo alcune funzionalità, la cui implementazione sarà unica per ciascuna piattaforma.

Al momento, l'ho implementato definendo e astrattamente la classe, che ha metodi che creano oggetti che implementano interfacce. La classe astratta e queste interfacce definiscono le funzionalità del mio livello di astrazione.

L'implementazione di questi nel mio layer dovrebbe ovviamente essere arbitraria dalla vista POV della mia applicazione, ma l'ho fatto, per la mia prima API, creando catene di sottoclassi che aggiungono funzionalità più specifiche come le funzionalità delle API espongono diventano meno generici.

Un esempio probabilmente lo dimostrerebbe meglio:

//The interface as seen by the application

interface IGenericResource
{
    byte[] GetSomeData();
}

interface ISpecificResourceOne : IGenericResource
{
    int SomePropertyOfResourceOne {get;}
}

interface ISpecificResourceTwo : IGenericResource
{
    string SomePropertyOfResourceTwo {get;}
}

public abstract class MyLayer
{
    ISpecificResourceOne    CreateResourceOne();
    ISpecificResourceTwo    CreateResourceTwo();

    void UseResourceOne(ISpecificResourceOne one);
    void UseResourceTwo(ISpecificResourceTwo two);
}

//The layer as created in my library

public class LowLevelResource : IGenericResource
{
    byte[] GetSomeData()
    {}
}

public class ResourceOne : LowLevelResource, ISpecificResourceOne
{
    int SomePropertyOfResourceOne {get{}}
}

public class ResourceTwo : ResourceOne, ISpecificResourceTwo
{
    string SomePropertyOfResourceTwo {get {}}
}

public partial class Implementation : MyLayer
{
    override UseResourceOne(ISpecificResourceOne one)
    {
        DoStuff((ResourceOne)one);
    }
}

Come si può vedere, sto essenzialmente cercando di avere due catene di ereditarietà sullo stesso oggetto, ma ovviamente non posso farlo, quindi simulo la seconda versione con le interfacce.

La cosa è, però, non mi piace usare le interfacce per questo; mi sembra sbagliato, nella mia mente un'interfaccia definisce un contratto, qualsiasi classe che implementa quell'interfaccia dovrebbe essere in grado di essere usata dove viene utilizzata quell'interfaccia, ma qui chiaramente non è il caso perché le interfacce vengono utilizzate per consentire ad un oggetto di layer to masquerade come qualcos'altro, senza che l'applicazione debba avere accesso alla sua definizione.

Quale tecnica mi permetterebbe di definire una collezione completa e intuitiva di oggetti per un livello di astrazione, mentre la loro implementazione rimane indipendente?

(La lingua è C #)

    
posta sebf 03.06.2012 - 12:13
fonte

1 risposta

5

Senza saperne di più mi concentrerei su ... Non farlo. Le catene di sottoclassi sono molto raramente la risposta, e vorrei inviare mai la risposta per l'implementazione dell'API dell'interfaccia.

Il problema è che l'API non sta implementando l'interfaccia, è già fatta. Stai creando un'interfaccia meno comune dalle diverse librerie. L'attenzione dovrebbe quindi essere (se ho capito bene il problema) creare la propria API, con i propri tipi di dati agnostici di implementazione e un livello adattatore per le implementazioni della piattaforma (non un livello di astrazione dalle implementazioni).

    
risposta data 03.06.2012 - 15:20
fonte

Leggi altre domande sui tag