Come dovrei chiamare questi metodi? [chiuso]

2

Ho due interfacce, una con e una senza parametri di tipo generico. L'interfaccia non generica viene utilizzata internamente in modo da poter memorizzare le istanze dell'interfaccia generica in una raccolta. Tutto andrebbe bene, tranne per il fatto che C # non genera firme di metodo basate sul tipo di ritorno. Ho un metodo in ogni interfaccia chiamata GetItems. Uno restituisce un IList l'altro un ILIST & Tt; Dal momento che non posso dare loro entrambi lo stesso nome, ho bisogno di inventare due nomi diversi che trasmettono entrambi quello che fanno. Ecco le interfacce:

public interface IBatchProcessingStorage {
    void Enqueue(object o);
    void Enqueue(IEnumerable items);
    void Dequeue(object o);
    void Dequeue(IEnumerable items);
    IList GetItems(int maxItems);
}
public interface IBatchProcessingStorage<T> : IBatchProcessingStorage {
    void Enqueue(T item);
    void Enqueue(IEnumerable<T> item);
    void Dequeue(T item);
    void Dequeue(IEnumerable<T> item);
    IList<T> GetItems(int maxItems);
}

Esiste un'attività che viene eseguita ogni tanto che ottiene elementi dall'archivio di elaborazione batch, li passa a una risorsa esterna e, se vengono elaborati dalla risorsa esterna, vengono rimossi dallo store. L'attività richiede l'interfaccia non generica, che è l'unica ragione per cui esiste. Ho creato una classe astratta che implementa entrambi e reindirizza le chiamate nell'interfaccia non generica a quelle generiche e quelle generiche sono astratte in questo modo:

public abstract class BatchProcessingStorage<T> 
  : IBatchProcessingStorage<T>
  , IBatchProcessingStorage {

    void IBatchProcessingStorage.Enqueue(object o) { Enqueue((T)o); }

    void IBatchProcessingStorage.Enqueue(IEnumerable items) {
        Enqueue((IEnumerable<T>)items); }

    void IBatchProcessingStorage.Dequeue(object o) { 
        Dequeue((T)o); }

    void IBatchProcessingStorage.Dequeue(IEnumerable items) {
        Dequeue((IEnumerable<T>)items); }

    IList IBatchProcessingStorage.GetItems(int maxItems) {
        return this.GetItems(maxItems).ToArray(); }

    public abstract void Enqueue(T item);

    public abstract void Enqueue(IEnumerable<T> item);

    public abstract void Dequeue(T item);

    public abstract void Dequeue(IEnumerable<T> item);

    public abstract IList<T> GetItems(int maxItems);
}

Questa dovrebbe essere la classe da cui i clienti erediteranno, ma non ho intenzione di forzarli nella nostra gerarchia ereditaria. Quindi potrebbero dover implementare entrambe le interfacce. Questo è il motivo della mia grande preoccupazione per i nomi. Non voglio che la nostra API abbia nomi di metodi crap. Quindi, che cosa dovrei chiamare GetItem in ogni classe che trasmette un significato senza sembrare che io stia lavorando intorno ai limiti della lingua?

Aggiornamento:

Per quelli di voi che pensano che io stia analizzando questo: abbiamo imparato molto sulla nostra API pubblica negli ultimi 5 anni. Ho una possibilità di ottenere questo nuovo giusto. Dopo di ciò siamo bloccati con ciò che viene rilasciato. Questa non è la tua applicazione software interna media. È una piattaforma software che è molto estensibile. È usato da alcune delle aziende più conosciute al mondo. Sarà molto difficile per loro onestamente salire sul palco delle nostre conferenze e promuovere l'utilità della nostra piattaforma software, se ha un'API schifosa. Questo non è eccessivamente complesso o troppo astratto. È progettato per soddisfare esigenze aziendali specifiche. I nostri clienti avranno bisogno di questo, meglio ancora, lo fanno già attraverso un'API con un nome molto basso e un sistema troppo complesso che ti fa saltare attraverso i cerchi per fare le cose (il senno di poi è sempre 20/20).

    
posta Charles Lambert 23.04.2011 - 04:36
fonte

3 risposte

0

Non è necessario generare un nuovo nome per entrambi i metodi qui. Aggiungendo la parola chiave 'new' al metodo GetItems definito in IBatchProcessingStorage < T >, puoi assegnare a entrambi i metodi lo stesso nome quando definisci esplicitamente una delle interfacce in una classe di implementazione.

public interface IBatchProcessingStorage {
    void Enqueue(object o);
    void Enqueue(IEnumerable items);
    void Dequeue(object o);
    void Dequeue(IEnumerable items);
    IList GetItems(int maxItems);
}
public interface IBatchProcessingStorage<T> : IBatchProcessingStorage {
    void Enqueue(T item);
    void Enqueue(IEnumerable<T> item);
    void Dequeue(T item);
    void Dequeue(IEnumerable<T> item);
    new IList<T> GetItems(int maxItems);
}

Apparentemente non sono riuscito a notare che ciò che veniva generato era un avvertimento del compilatore e non un errore. Li disprezzo e li tratto allo stesso modo. Poiché mi aspetto che facciano esplicitamente implementare l'interfaccia non generica per chiamare i metodi non generici, questo metodo di nascondere è un comportamento accettabile.

    
risposta data 25.04.2011 - 23:47
fonte
2

Questo è il caso d'uso perfetto per l'implementazione esplicita dell'interfaccia. È sufficiente utilizzare l'implementazione dell'interfaccia esplicita per l'interfaccia non generica e quindi il chiamante che ha bisogno di quell'interfaccia può chiamare direttamente attraverso l'interfaccia non generica e entrambe le interfacce possono avere il nome del metodo amichevole appropriato senza entrare in conflitto tra loro.

    
risposta data 25.04.2011 - 07:05
fonte
0

Due suggerimenti.

  1. Non nominare la classe BatchProcessingStorage, chiamarla BatchProcessingStorageSystem.
  2. Non esporre le funzioni enqueue e dequeue a meno che la classe non sia chiamata FooQueue

Stai esponendo un po 'troppe informazioni in questa API. Innanzitutto, nessuno dovrebbe sapere o preoccuparsi che si accoda o si abboni. Se è necessario che le persone sappiano che stai usando una sorta di elenco LIFO, va bene, ma non dovrebbero dovere accodare e dequotare, dovrebbero solo aggiungere e ottenere.

E, se la tua classe è lo Storage, la persona che la implementa potrebbe aspettarsi un controllo maggiore sulla classe di quanto tu non voglia esporre nell'API, se la chiami BatchProcessingStorageSystem, allora puoi esporre ciò che deve essere esposto , quando ha bisogno di essere esposto.

    
risposta data 25.04.2011 - 17:48
fonte

Leggi altre domande sui tag