Design Pattern dilemma. La strategia sembra sbagliata?

3

Vorrei ricevere aiuto / consigli su un modello di progettazione o simili che potrei usare per il mio problema.

Ho alcune funzionalità condivise nel mio codice e attualmente utilizzo lo schema della strategia. Ho una classe base chiamato "ProjectSectionBase" e da qui ho 2 classi derivate, "ProjectSectionStandard" e "ProjectSectionSuperior". Ora il problema è che "ProjectSectionSuperior" ha molte funzionalità extra rispetto a "ProjectSectionStandard" e io sono trovando che attraverso il mio codice sto chiamando metodi come questo:

DirectCast (_projectSection, ProjectSectionSuperior) .DoSuperiorStuff

E sto anche eseguendo il wrapping delle istruzioni IF come IF typeof (_projectSectio) è superiore allora.

Sembra un cattivo design di classe. Sia standard che superiori condividono molte funzionalità comuni, ma in seguito superiori ha molte più funzionalità Qualsiasi consiglio sarebbe molto apprezzato.

    
posta Ahmad Zandi 06.08.2013 - 17:00
fonte

3 risposte

1

Ciò che descrivi non è certamente il modello di strategia. In Strategia tutte le classi (della strategia) hanno la stessa interfaccia.

Quello che hai è eredità. Il 'superiore' dovrebbe derivare da 'standard' e quindi eventualmente sovrascrivere alcune funzioni virtuali e aggiungere alcuni metodi e comportamenti aggiuntivi. Non sono sicuro che ci sia un altro modello che possa aiutarti. Forse lo schema dello Stato, ma tutto dipende dalle tue esigenze.

Poiché "standard" e "superiore" sono così diversi, idealmente collocherai una sola istruzione IF da qualche parte nella tua logica e poi avrai due componenti completamente autonomi che gestiscono la situazione particolare. Quindi, applichi qualche forma di refactoring.

    
risposta data 07.08.2013 - 06:35
fonte
2

Questo è un problema comune. Di solito il problema è che la tua classe ha troppe responsabilità. Prendere in considerazione:

public interface IProjectSection
{
    void DoSectionStuff()
}

public class SimpleProjectSection : IProjectSection
{
    public void DoSectionStuff(){/*simple stuff here*/}
}

public class SuperiorProjectSection: IProjectSection
{
    public void DoSectionStuff(){/*complex stuff here*/}
    public void DoSuperiorSectionStuff(){/*additional superior stuff here*/}
}

public class ProjectSectionUser
{
    public void DoSomeProjectSectionThings(IProjectSection section)
    {
        section.DoSectionStuff();
        var superior = section as SuperiorProectSection;
        if(superior != null)
            superior.DoSuperiorSectionStuff();
    }
}

Questo è in realtà più bello da rappresentare come due modelli di strategia, separando DoSuperiorSectionStuff () in un'altra interfaccia, in questo modo:

public interface IProjectSection
{
    void DoSectionStuff();
}

public interface ISuperiorProjectSection
{
    void DoSuperiorSectionStuff();
}

public class SimpleProjectSection : IProjectSection
{
    public void DoSectionStuff(){/*simple stuff here*/}
}

public class SuperiorProjectSection: IProjectSection, ISuperiorProjectSection
{
    public void DoSectionStuff(){/*complex stuff here*/}
    public void DoSuperiorSectionStuff(){/*additional superior stuff here*/}
}

public class ProjectSectionUser
{
    public void DoSomeProjectSectionThings(IProjectSection section, ISuperiorProjectSection superior)
    {
        section.DoSectionStuff();
        superior.DoSuperiorSectionStuff();
    }
}

Quindi i due modi per usarlo sono:

...
var superiorSection = new SuperiorProjectSection();
projectSectionUser.DoSomeProjectSectionThings(superiorSection, superiorsection);
...

o

...
var superiorSection = new NullSuperiorProjectSection();
var section = new SimpleProjectSection();
projectSectionUser.DoSomeProjectSectionThings(section, superiorsection);
...

dove NullSuperiorProjectSection è definito come

public class NullSuperiorProjectSection : ISuperiorProjectSection
{
    public void DoSuperiorSectionStuff(){/*do nothing*/}
}

Nota: normalmente implementerei queste due interfacce in classi separate. In questo caso, non so abbastanza del tuo codice per fare un esempio decente in questo modo, quindi l'ho lasciato così. Dividere le responsabilità separate in classi separate dove ha senso; aumenta la flessibilità dei codici nel tempo.

    
risposta data 07.08.2013 - 04:05
fonte
1

Una soluzione potrebbe essere che tutte le funzioni sono implementate come virtuali nella classe base e hanno corpi vuoti, e solo la classe superiore le sostituisce con codice significativo. Una funzione speciale è bool IsSuperior() che restituisce false nella classe base e sovrascritta in superiore restituisce true. Tutto ciò purifica un po 'il codice. Forse la pulizia del codice è proprio ciò di cui hai bisogno, poiché il codice non deve essere perfetto e idealistico, ma deve svolgere il lavoro.

    
risposta data 06.08.2013 - 17:07
fonte

Leggi altre domande sui tag