开发者

Is this a good way to handle events in Java?

开发者 https://www.devze.com 2023-01-19 04:12 出处:网络
I\'m making a game in Java, and I think I have a good idea of how to handle events. Does this sound right?

I'm making a game in Java, and I think I have a good idea of how to handle events. Does this sound right?

A Window class--the view. It's a representation of the World at the current moment. There's also a Game class -- the controller. (The model's implementation is irrelevant for this question).

The Window class doesn't care about events. Therefore, the event listener simply dispatches them to the Game class (via something like game.notifyEvent(E开发者_高级运维vent e);.

The Game class, upon receipt of this event, will start updating values and the like, and some variables (like the location of the player) will be changed. At this point, it uses its class variable Window w to notify it of the changes (via various methods such as w.movePlayer(Position p), etc.

SO, does this sound like something that would make sense to you?


Yes, what you're doing makes some sense. I find it much more intuitive to have the Window listen to the Game than the other way round. I've also found that Java is much more maintainable if you separate out the different areas of the GUI and pass the Game into each of them through a fine-grained interface. I normally get the GUI elements to listen to changes in the model, and request any interactions to be dealt with. This way round makes for easier unit testing, and you can replace the GUI with a fake for acceptance testing if you don't have a decent automation suite, or even just for logging.

Usually splitting up the GUI results in some panels purely listening, and some panels purely interacting. It makes for a really lovely separation of concerns. I represent the panels with their own classes extending JPanel, and let the Window pass the Game to them on construction.

So for instance, if I have two panels, one of which displays the results and one of which has an "Update" button, I can define two interfaces: INotifyListenersOfResults and IPerformUpdates. (Please note that I'm making role-based interfaces here using the IDoThisForYou pattern; you can call them whatever you like).

The Game controller then implements both these interfaces, and the two panels each take the respective interface. The Update interface will have a method called RequestUpdate and the Results interface will have AddResultsListener. Both these methods then appear on the Game class.

Regardless of whether you get the Game to listen to the Window or the Window to the Game, by separating things through interfaces this way you make it much easier to split the Game controller later on and delegate its responsibilities, once things start getting really complicated, which they always do!


I think you should implement the Observer design pattern (http://en.wikipedia.org/wiki/Observer_pattern) without using .NET's events. In my approach, you need to define a couple of interfaces and add a little bit of code. For each different kind of event, create a pair of symmetric interfaces

public interface IEventXDispatcher
{
    void Register(IEventXHandler handler);

    void Unregister(IEventXHandler handler) throws NotSupportedException;
}

public interface IEventXHandler
{
    void Handle(Object sender, Object args);
}

X denotes the specific name of event (Click, KeyPress, EndApplication, WhateverYouWant). Then make your observed class implement IEventDispatcher and your observer class(es) implement IEventHandler

public class Dispatcher implements IEventXDispatcher, IEventYDispatcher ...
{
    private List<IEventXHandler> _XHandlers;
    private List<IEventYHandler> _YHandlers;

    void Register(IEventXHandler handler)
    {
        _XHandlers.Add(handler);
    }

    void Unregister(IEventHandler handler) throws NotSupportedException
    {
        //Simplified code
        _XHandlers.Remove(handler);
    }

    private MyMethod()
    {
        [...]
        for(IEventXHandler handler: _XHandlers)
            handler.Handle(this, new AnyNeededClass())
        [...]
    }
    //Same for event Y

All the code is hand-written. I have little experience with Java but I believe this pattern may help you!

0

精彩评论

暂无评论...
验证码 换一张
取 消