简体   繁体   中英

Best practice of handling input of components in Java

Consider this 3 examples of handling input:

/*EXAMPLE A*/
public class HandlingInputExampleA
{
    private Label labelFromOtherClass; //injected by setter/constructor
    private String myText = "hello ";
    private int myInt = 1;

    private void init()
    {
        Button button = new Button();
        button.addClickListener(event -> labelFromOtherClass.setCaption(myText + myInt));
    }
}

public class HandlingInputExampleB
{
    private ClickListener inputHandler; //injected by setter/constructor
    private String myText = "hello ";
    private int myInt = 2;

    private void init()
    {
        Button button = new Button();
        button.addClickListener(inputHandler);
    }
}

/*EXAMPLE B*/
public class HandlingInputExampleB
{
    private ClickListener inputHandler; //injected by setter/constructor
    private String myText = "hello ";
    private int myInt = 2;

    private void init()
    {
        Button button = new Button();
        button.addClickListener(inputHandler);
    }
}

public class InputHandlerB implements ClickListener
{
    private HandlingInputExampleB exampleB; //injected by setter
    private Label label; //injected by setter/constructor

    @Override
    public void buttonClick(ClickEvent event)
    {
        Button button = event.getButton();
        if( button == exampleB.getButton() )
        {
            label.setCaption(exampleB.getMyText() + exampleB.getMyInt());
        }
    }
}

/*EXAMPLE C*/
public class HandlingInputExampleC
{
    private ClickListener inputHandler; //injected by setter/constructor
    private String myText = "hello ";
    private int myInt = 2;

    private void init()
    {
        Button button = new Button();
        button.setData(this);
        button.addClickListener(inputHandler);
    }
}

public class InputHandlerC implements ClickListener
{
    private Label label; //injected by setter/constructor

    @Override
    public void buttonClick(ClickEvent event)
    {
        Button button = event.getButton();
        if( button.getData() instanceof HandlingInputExampleC )
        {
            HandlingInputExampleC exampleC = (HandlingInputExampleC)button.getData();
            label.setCaption(exampleC.getMyText() + exampleC.getMyInt());
        }
    }
}

I suppose I should keep one way of handling input in my project. Most of the time I'm creating one class to deal with input and I'm injecting all needed objects there so every action associated with user input is managed in one place. Of course the bigger my project become, the bigger input handler class is, and its starting to look a bit messy. Maybe I'm missing much better solution? Please tell me which of those examples should I avoid?

It depends on the size of the project and how many similar/different handlers you'll need. For some very simple situations I would go for option A but if you have few similar handlers it's better to extract to a new class.

For example if the text "exampleC.getMyText() + exampleC.getMyInt()" is not changing during the execution I would prefer :

public class HandlingInputExample {
    private ClickListener inputHandler; //injected by setter/constructor
    private String myText = "hello ";
    private int myInt = 2;

    private void init() {
        Button button = new Button();
        button.setData(this);
        button.addClickListener(new SetCaptionClickListener(example.getMyText() + example.getMyInt()));
    }
}

public class SetCaptionClickListener implements ClickListener {
    private Label label; //injected by setter/constructor
    private String caption;

    public SetCaptionClickListener(String caption) {
        this.caption = caption;
    }

    @Override
    public void buttonClick(ClickEvent event) {
            label.setCaption(caption);
    }
}

But if the data may change you can add another layer that have the responsability to retrieve the information needed by the handler, something like:

public class HandlingInputExample {
    private ClickListener inputHandler; //injected by setter/constructor
    private String myText = "hello ";
    private int myInt = 2;

    private void init() {
        Button button = new Button();
        button.setData(this);
        button.addClickListener(new SetCaptionClickListener(new Context(this)));
    }
}

public class SetCaptionClickListener implements ClickListener {
    private Label label; //injected by setter/constructor
    private Context context;

    public SetCaptionClickListener(Context context) {
        this.context = context;
    }

    @Override
    public void buttonClick(ClickEvent event) {
        label.setCaption(context.getCaption());
    }
}

public class Context {
    HandlingInputExample handlingInputExample;

    public Context(handlingInputExample handlingInputExample) {
        this.handlingInputExample = handlingInputExample;
    }

    public String getCaption() {
        return handlingInputExample.getMyText() + handlingInputExample.getMyInt();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM