Best practice per raccogliere informazioni dagli oggetti figlio

2

Sto regolarmente seguendo il seguente schema:

public abstract class BaseItem
{
    BaseItem[] children;

    // ...

    public void DoSomethingWithStuff()
    {
        StuffCollection collection = new StuffCollection();
        foreach(child c : children) c.AddRequiredStuff(collection);
        // do something with the collection ...
    }

    public abstract void AddRequiredStuff(StuffCollection collection);
}

public class ConcreteItem : BaseItem
{
    // ...

    public override void AddRequiredStuff(StuffCollection collection)
    {
        Stuff stuff;
        // ...
        collection.Add(stuff);
    }
}

Dove preferirei qualcosa del genere, per nascondere meglio le informazioni:

public abstract class BaseItem
{
    BaseItem[] children;

    // ...

    public void DoSomethingWithStuff()
    {
        StuffCollection collection = new StuffCollection();
        foreach(child c : children) collection.AddRange(c.RequiredStuff());
        // do something with the collection ...
    }

    public abstract StuffCollection RequiredStuff();
}

public class ConcreteItem : BaseItem
{
    // ...

    public override StuffCollection RequiredStuff()
    {
        StuffCollection stuffCollection;

        Stuff stuff;
        // ...
        stuffCollection.Add(stuff);

        return stuffCollection;
    }
}

Quali sono i pro e i contro di ciascuna soluzione?

Per me, dare l'accesso all'implementazione alle informazioni dei genitori è un po 'sconcertante. D'altra parte, l'inizializzazione di un nuovo elenco, solo per raccogliere gli elementi è un overhead inutile ...

Qual è il design migliore? Come cambierebbe, se DoSomethingWithStuff non sarebbe parte di BaseItem ma una terza classe?

PS: potrebbero mancare punti e virgola o errori di battitura; scusa per quella cosa! Il codice precedente non è pensato per essere eseguito, ma solo per illustrazione.

    
posta Markus 27.05.2014 - 17:31
fonte

1 risposta

1

initializing a new list, just to collect the items is a useless overhead

istanzia due raccolte di livello di classe, una volta. Il primo è per il% cumulativo% co_de e l'altro per passare al figlio - ed è riutilizzato.

public abstract class BaseItem
{
    BaseItem[] children;
    StuffCollection masterCollection;
    StuffCollection transferCollection;

    // ...

    public void DoSomethingWithStuff()
    {
        masterCollection = masterCollection?? new StuffCollection();
        transferCollection = transferCollection?? new StuffCollection();

        transferCollection.Clear();

        foreach(child c : children) {
            c.RequiredStuff(transferCollection);
            masterCollection.AddRange(transferCollection);
            transferCollection.Clear();
        }

        // do something with the collection ...
    }

    public abstract void RequiredStuff(StuffCollection aTransferCollection);
}

public class ConcreteItem : BaseItem
{
    // ...

    public override void RequiredStuff(StuffCollection collector )
    {
        Stuff stuff;
        // ...
        collector.Add(stuff);
    }
}
    
risposta data 28.05.2014 - 04:09
fonte

Leggi altre domande sui tag