Creazione di widget, impostazione / acquisizione di dati da essi - Problema del motivo

1

Diciamo che ho una classe Widget . Ho anche TextWidget , ComboWidget , ChoiceWidget classi ereditate dalla classe Widget .

Creo questi widget in base alla situazione. Dopo aver creato il widget, mostro solo alcuni dati sul widget e ne ottengo uno dall'utente. Dopo questo il widget viene distrutto. Il mio codice corrente è qualcosa del genere: (Il codice è totalmente arbitrario)

Widget createWidget(DataType type, Data data) {
    Widget widget;
    if (type == DataType.Text) {
        widget = new TextWidget();
        widget.setText(data.toStrig());
    } else if (type == DataType.Choice) {
        widget = new ChoiceWidget();
        widget.setChoices(data.toChoices())
    } else if (type == DataType.MultiText)
        widget = new ComboWidget();
        widget.setItems(data.toItems())
    }
    return widget;
}

Dopo la creazione, ottengo alcuni dati dall'utente che utilizza quel widget. Quindi lo distruggo.

void widgetReturnPressedEvent(Widget widget) {
    UserData data;
    if (widget.type() == TextWidget)
        data.setText(((TextWidget)widget).getText())
    // ...
    // You get the idea.
}

Lo sto utilizzando in diverse parti del mio programma. Così facendo se-else ogni volta non è un buon modo per gestire questa situazione. Quindi cosa dovrei fare qui? Può qualcosa del genere funziona, o c'è un buon schema per questa situazione?

class DataWidget {
    Widget widget;
    Widget createWidget(DataType type) {
        Widget w;
        //...
        this.widget = w;
    }

    void setData(Data data) {
        if (this.widget == TextWidget)
            this.widget.setText(data.toString());
        //...
    }

    Data getData() {
        Data data;
        // set data
        return data;
    }

    Widget widget() {
        return this.widget;
    }
}
    
posta isamert 18.08.2016 - 09:55
fonte

1 risposta

0
  • Ci sono stato, fatto. Modello di metodo di fabbrica.

  • La factory ha un HashMap<String,WidgetCreator> statico, quindi la creazione di un widget consiste nel cercare il creatore in Map e chiamare il metodo create. Ecco perché non è necessario if o switch .

  • Puoi mettere tutti i creatori e la fabbrica in un pacchetto separato per un'area di lavoro più pulita.

  • Inoltre, poiché ogni tipo di Widget sa quale metodo chiamare su Data , perché non passare invece i dati?

  • Ho presupposto che le selezioni e gli articoli siano List<String> , puoi scegliere diversamente.

  • Prima UML (questo software dipinge le interfacce viola invece di mettere <<name>> nel titolo)

  • Codice sotto.

==>Factory.java<==

importjava.util.HashMap;importjava.util.Map;publicclassFactory{privatestaticMap<String,WidgetCreator>widgetCreators=newHashMap<String,WidgetCreator>();static{widgetCreators.put("TEXT",new TextWidgetCreator());
        widgetCreators.put("CHOICE",new ChoiceWidgetCreator());
        widgetCreators.put("COMBO",new ComboWidgetCreator());
        // add as many creators as types od widgets you have
        // tags must be unique, feel free to use CONSTANSTS      
        // instead of magic literals for the tags
    }

    public static Widget getWidget(String tag) throws UnknownWidgetTagException{
        WidgetCreator c = widgetCreators.get(tag);
        if (c == null) {
            throw new UnknownWidgetTagException(tag);
        }
        return c;
    }
}

== > WidgetCreator.java < ==

public interface WidgetCreator {
    public Widget createWidget(Data data);
}

== > Widget.java < ==

public interface Widget {
    public void setData(Data data);
    public Data getData();
}

== > Data.java < ==

import java.util.List;

public interface Data {
    public String toString();
    public List<String> toChoises();
    public List<String> toItems();
}

== > UnknownWidgetTagException.java < ==

public class UnknownWidgetTagException extends Exception {

    public UnknownWidgetTagException(String tag) {
        System.out.println("No Widget registered with tag: "+tag);
    }

}

== > TextWidgetCreator.java < ==

public class TextWidgetCreator implements WidgetCreator {

    @Override
    public Widget createWidget(Data data) {
        Widget w = new TextWidget();
        w.setData(data);
        return w;
    }

}

== > ChoiceWidgetCreator.java < ==

public class ChoiceWidgetCreator implements WidgetCreator {

    @Override
    public Widget createWidget(Data data) {
        Widget w = new ChoiceWidget();
        w.setData(data);
        return w;
    }    
}

== > ComboWidgetCreator.java < ==

public class ComboWidgetCreator implements WidgetCreator {

    @Override
    public Widget createWidget(Data data) {
        Widget w = new ComboWidget();
        w.setData(data);
        return w;       
    }
}

== > TextWidget.java < ==

public class TextWidget implements Widget {

    private String text;
    private Data data;

    @Override
    public void setData(Data data) {
        this.data = data;
        this.text = data.toString();        
    }

    @Override
    public Data getData() {
        return data;
    }
}

== > ChoiceWidget.java < ==

import java.util.List;

public class ChoiceWidget implements Widget {

    private List<String> choices;
    private Data data;

    @Override
    public void setData(Data data) {
        this.data = data;
        this.choices = data.toChoises();        
    }

    @Override
    public Data getData() {
        return data;
    }
}

== > ComboWidget.java < ==

import java.util.List;

public class ComboWidget implements Widget {

    private List<String> items;
    private Data data;

    @Override
    public void setData(Data data) {
        this.data = data;
        this.items = data.toItems();        
    }

    @Override
    public Data getData() {
        return data;
    }

}

============

void widgetReturnPressedEvent(Widget widget) {
    UserData data;
    widget.setData(data); // widget already knows how to handle the data
}

===============

    
risposta data 18.08.2016 - 15:34
fonte

Leggi altre domande sui tag