2015-07-23 21 views
6

La nostra applicazione sta diventando complessa, ha principalmente 3 flussi e deve essere elaborata in base a uno dei 3 tipi. Molte di queste funzionalità si sovrappongono l'una all'altra.Modelli di progettazione che possono sostituire le istruzioni se

Così attualmente il codice è completamente di istruzioni if-else, è tutto incasinato e non organizzato. Come creare un modello in modo che 3 flussi siano chiaramente separati l'uno dall'altro, ma facendo uso del potere della riutilizzabilità.

Si prega di fornire alcune considerazioni, questa è un'applicazione MVC, in cui è necessario produrre e utilizzare i servizi Web utilizzando la tecnologia jaxb.

Può essere possibile visualizzare l'applicazione come un singolo oggetto come input su cui devono essere implementate strategie diverse in base al valore di runtime.

+5

Si prega di inviare una porzione (o tutti) di questo codice di spaghetti in modo che possiamo darvi risposte reali e significative. –

+0

Dipende dalla logica che questo codice fa –

+0

La prima cosa che viene in mente è implementare le tabelle decisionali per sbarazzarsi delle dichiarazioni if ​​/ else. –

risposta

0

Dopo un po 'di tempo trovo che le strutture del motore di regole opensource come "drools" sono un'ottima alternativa per soddisfare le mie esigenze.

7

La tua domanda è molto ampia e quasi impossibile rispondere senza una descrizione o una panoramica della struttura della tua applicazione. Tuttavia, sono stato in una situazione simile e questo è l'approccio che ho preso:

Sostituire condizioni con polimorfismo, ove possibile

ha principalmente 3 flusso e deve elaborare sulla base di questo una delle il tipo 3 . Molte di queste funzionalità si sovrappongono l'una all'altra.

Si dice che il progetto ha 3 flussi principali e che gran parte del codice si sovrappone l'un l'altro. Mi sembra un modello di strategia:

Si dichiara un'interfaccia che definisce le attività eseguite da un flusso.

public interface Flow{ 
    public Data getData(); 
    public Error validateData(); 
    public void saveData(); 
    public Error gotoNextStep(); 
} 

Si crea una classe astratta che fornisce un'implementazione comune a tutti e 3 i flussi. (Metodi di questa classe astratta non devono essere definitiva, ma è sicuramente voglia di prendere in considerazione con attenzione.)

public abstract class AbstractFlow{ 

    private FlowManager flowManager 

    public AbstractFlow(FlowManager fm){ 
    flowManager = fm; 
    } 

    public final void saveData(){ 
     Data data = getData(); 
     saveDataAsXMl(data); 
    } 

    public final Error gotoNextStep(){ 

     Error error = validateData(); 
     if(error != null){ 
     return error; 
     } 

     saveData(); 
     fm.gotoNextStep(); 
     return null; 
    } 
} 

Infine, si crea 3 classi concrete che si estendono dalla classe astratta e definiscono concreta attuazione per la dato il flusso.

public class BankDetailsFlow extends AbstractFlow{ 

    public BankDetailsData getData(){ 
    BankDetailsData data = new BankDetailsData(); 
    data.setSwiftCode(/*get swift code somehow*/); 
    return data; 
    } 

    public Error validateData(){ 
     BankDetailsData data = getData(); 
     return validate(data); 
    } 

    public void onFormSubmitted(){ 
     Error error = gotoNextStep(); 
     if(error != null){ 
     handleError(error); 
     } 
    } 
} 
7

Non sono stati specificati quali sono i vostri if-else dichiarazioni stanno facendo. Supponiamo che siano filter in base a qualche value.

Se ho capito bene la tua domanda, vuoi dare un'occhiata a Factory Pattern.

Questo è un approccio pulito, di facile manutenzione e produce codice leggibile. Aggiungere o rimuovere uno Filter è anche semplice, basta rimuovere la classe e rimuoverla dall'hashmap FilterFactory.

creare un'interfaccia: Filtra

public interface Filter { 
    void Filter(); 
} 

Creare una fabbrica che restituisce corretta Filtro secondo la vostra value.Invece della vostra if-else ora si può semplicemente utilizzare il seguente:

Filter filter = FilterFactory.getFilter(value); 
    filter.filter(); 

Un modo comune di scrivere FilterFactory sta usando una HashMap al suo interno.

public class FilterFactory{ 
    static HashMap<Integer, Filter> filterMap; 
    static{ 
     filterMap = new HashMap<>(); 
     filterMap.put(0,new Filter0()); 
     ... 
    } 
    // this function will change depending on your needs 
    public Filter getFilter(int value){ 
     return filterMap.get(value); 
    } 

} 

Crea il tuo tre (nel tuo caso) Filtri in questo modo: (con nomi significativi però)

public class Filter0 implements Filter { 

    public void filter(){ 
     //do something 
    } 
} 

NOTA: Come si desidera riutilizzare alcuni metodi, creare una classe FilterUtility e fare tutti i filtri estendono questa classe in modo da poter utilizzare tutte le funzioni senza riscriverle.

+0

grazie per aver condiviso le informazioni, questo sembra molto leggibile e buono – Valath

3

Consente di prendere ad esempio, si supponga di avere il modello detto "Data" [che ha alcuni attributi e getter, setter, metodi opzionali] .In contesto di applicazione mobile, in particolare di applicazioni Android ci possono essere due modalità off-line o on -linea. Se il dispositivo è connesso alla rete, i dati vengono inviati alla rete altrimenti archiviati nel database locale del dispositivo. In procedurale modo in cui qualcuno può, definire due modelli come OnlineData, OfflineData e scrivere codice come [Il codice non è esatto, è proprio come pseudo codice]:

if(Connection.isConnected()){ 
    OnlineData ond=new OnlineData(); 
    ond.save();//save is called which stores data on server using HTTP. 
} 
else{ 
    OfflineData ofd=new Onlinedata(); 
    ofd.save();//save is called which stores data in local database 
} 

Un buon approccio per implementare questo sta usando OOPS principi:

programma di interfaccia non Implementazione

Vediamo come fare questo. Sto solo scrivendo frammenti di codice che sarà più efficace rappresentare quello che mean.The frammenti sono i seguenti:

public interface Model { 
    long save();//save method 
    //other methods ..... 
} 


public class OnlineData extends Model { 
    //attributes 
    public long save(){ 
    //on-line implementation of save method for Data model 
    } 
    //implementation of other methods. 
} 

public class OfflineData extends Model { 
    //attributes 
    public long save(){ 
    //off-line implementation of save method for Data model 
    } 
    //implementation of other methods. 
} 
public class ObjectFactory{ 
    public static Model getDataObject(){ 
    if(Connection.isConnected()) 
     return new OnlineData(); 
    else 
     return new OfflineData(); 

    } 
} 

e qui è il codice che la classe client deve utilizzare:

public class ClientClass{ 
    public void someMethod(){ 
     Model model=ObjectFactory.getDataObject(); 
     model.save();// here polymorphism plays role... 
    } 
} 

Anche questo segue:

responsabilità unico principio [SRP]

perché on-line e off-line sono due compiti diversi, che abbiamo può essere in grado di integrarsi in Single save() usando l'istruzione if-else.

Problemi correlati