sostituto per ereditarietà statica

0

Al momento ho un numero di classi (~ 20) che fanno tutte la stessa cosa (astrattamente), cioè generano un'istanza di una particolare classe da un file xml.

Il modo in cui usano il contenuto del file xml varia un po 'e i dati vengono archiviati in diverse sottostrutture (campi, gruppi, ecc.) che sono condivisi tra le classi, quindi ho preso tutto l'analisi e il campo informazioni dai file e creato una classe helper (come è il tipo costruttivo finale)

Tutte le classi e i metodi sopra riportati sono statici, in quanto non hanno bisogno di contenere nessuno stato.

Quindi volevo che tutte le classi derivassero da una classe comune in modo tale che non mi riferissi costantemente a una classe apparentemente non correlata, solo per scoprire che ereditarietà e staticità non funzionano bene insieme.

Qual è il modo appropriato di configurarlo? È basicamente un grande insieme di metodi di fabbrica per un tipo che non richiede stato.

Aggiornamento: il flusso di controllo è attualmente il seguente:

  1. Scegli uno dei ~ 20 metodi di fabbrica
  2. Leggi in un file XML (tutti i tag, gli attributi sono gli stessi tra i file, ma i file sono distinti attraverso i metodi).
  3. Converti il contenuto dei file XML in una classe che ha alcune strutture dati come membri ( List<Field>, List<Group>, Dictionary<string,string> ecc.). Queste strutture dati utilizzano tipi annidati nell'helper.
  4. Aggiungi queste raccolte all'oggetto non inizializzato.
  5. Restituisce l'oggetto al chiamante.

In questo momento, i 20 metodi di fabbrica sono le proprie classi statiche e tutti restituiscono oggetti dello stesso tipo, anche se potrebbe esserci qualche differenza semantica tra i "tipi" tutti i memebers e le funzioni sono gli stessi. Il codice che analizza il file XML è in un helper, poiché questa logica è comune a tutti i metodi di fabbrica. Il passaggio 3 deve essere diverso per tutti i metodi, in modo tale che la parte si trovi nelle classi statiche.

    
posta soandos 08.07.2013 - 18:44
fonte

4 risposte

0

Non sono riuscito a capire perché qui potrebbero essere necessarie 20 lezioni. Penso che ci vuole una lezione con 20+ metodi.

class XMLMaker {
  public OutputClassA ParseA(File input) { ... }
  public OutputClassB ParseB(File input) { ... }
  // etc, however many classes you need to create
  //
  // reusable helper methods for the public methods above
  protected XML.Node _ParseFoo(...) {...}
  protected string _ParseBar(...) {...}
  //
  // I can imagine you might want it, too:
  public OutputClass Parse(File input) {
    var file_kind = _DetectKind(input);
    if (file_kind == KIND_A) return ParseA(input);
    // etc
  }
}

Posso anche immaginare che puoi distribuire ParseA , ParseB , ecc in un set gestibile di file separati creando XMLMaker una classe parziale.

XMLMaker non ha bisogno di memorizzare alcun stato, quindi può essere istanziato una volta da una fabbrica di caching o da un meccanismo DI.

    
risposta data 08.07.2013 - 21:28
fonte
2

I then wanted to have all the classes derive from one common class so that I am not referencing a seemingly unrelated class constantly, only to discover that inheritance and static do not work together well.

Ero con te fino a questo punto, ma questo bit sembra un cattivo uso dell'ereditarietà.

Se ritieni che le tue classi siano troppo legate alla classe helper, concentrati sul miglioramento dell'interfaccia pubblica della classe helper.

    
risposta data 08.07.2013 - 18:54
fonte
1
  1. Pick one of ~20 factory methods

Questa parte è interessante e potrebbe contenere la chiave per risolvere questo problema. Come si sceglie il metodo di produzione appropriato? Esiste una classe Factory ? Senza un esempio è abbastanza difficile fornire una risposta concreta, ma il modo in cui prevedo di risolvere questo problema è il seguente:

public abstract class BaseClass
{
    //common code and maybe some abstract methods

    //This could (should?) go into it's own class.
    public static BaseClass Factory(File file)
    {
        if (something)
        {
            return Class1.Create(file) //or just call the constructor
        }
        if (somethingElse)
        {
            return Class2.Create(file)...
        }
    }
}

public class Class1 : BaseClass
{
    //private constructor so that you have to go through the Create() method
    private Class1()
    {}

    //variables/code for handling the file and populating the variables

    private void ParseFile(File file)
    {
    }

    public static Class1 Create(File file)
    {
        Class1 class1 = new Class1();
        class1.ParseFile(file);
        return class1;
    }
}

Ovviamente questo è tutto pseudo-codice!

Ho notato che tu dici che le classi non hanno bisogno di mantenere nessuno stato ed è per questo che sono statiche, ma qualcosa in proposito e la necessità di ereditarietà non si sommano. Con il mio codice chiameresti il metodo Factory sulla classe base (o nella sua stessa classe se lo desideri) passando in ogni file e quello che ottieni è un elenco di BaseClass es che passi indietro al chiamante che presumibilmente fa qualcosa con loro.

Forse potresti fornire più dettagli su ciò che inizi, su cosa vuoi finire e su ciò che fai nel mezzo potremmo offrire qualche consiglio più concreto.

    
risposta data 08.07.2013 - 19:39
fonte
0

I then wanted to have all the classes derive from one common class so that I am not referencing a seemingly unrelated class constantly

Questo è il tuo errore mentale qui - sembra che tu ritenga che "l'ereditarietà" sia in qualche modo migliore per il riutilizzo che usare una classe di helper separata. In effetti, nella maggior parte dei casi è il contrario, e dal momento che tutte le classi sono statiche, non otterrai alcun beneficio dall'ereditarietà, anche se potresti usarla qui. Il tuo esempio mostra esattamente il tipo di pensiero che porta al tipico uso errato dell'eredità. Meglio dare al tuo helper un nome migliore, quindi non sembra essere così "non correlato".

    
risposta data 09.07.2013 - 16:43
fonte

Leggi altre domande sui tag