Click here to Skip to main content
14,027,907 members
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

14.6K views
8 bookmarked
Posted 13 Jul 2015
Licenced CPOL

C#-Like Events For Java

, 28 Aug 2016
Rate this:
Please Sign up or sign in to vote.
Simplifying Java events

Introduction

I was thrilled by the release of Java 8 so much. I have been waiting for features like Lambda expressions and streams for long as I am working with both C# and Java and these features have been supported in C# since a while. Unfortunately, I found a simple and efficient way for declaring events in classes is still missing. Don't get me wrong, I am not claiming that there are no event handling Java. Both have their own techniques based on Observable design pattern. I just expected to find in Java 8 an efficient and simple way to declare events and be able to register their handlers like C#.

There is a subtle difference between both techniques that gives the edge for C# in my opinion. In Java, the common technique is to consider the class which the events belongs to, as the observed subject. In C#, the event declared by the class is the observed subject and not the class. This makes the logic of keeping a list of event handlers and notifying them encapsulated in the event object itself and not in the class the events belong to. This reduces the effort of declaring an event in your class and achieves Single Responsibility Design Principle.

Because of this, I created some classes to declare events and assign handlers to them like in C# which makes handling events, a breeze. I use them with every class to declare events. Before we see them, keep in mind that we are trying to do the following:

  • Declaring events inside some class in a simple way
  • Being able to bind multiple listeners or handlers for the same event
  • Event logic should be written once and used many times
  • Event logic doesn't belong to the class declaring the event

The classes can be downloaded from here and are described below:

  • EventArgs: The class that holds the augments or the information about the event. For any information that needs to be shared about the event to its handlers, a new event argument class is to be created holding the required information and extending EventArgs class.
  • IEventHandler<T extends EventArgs>: The interface to be implemented by the event handler of this event.
  • IEvent<T extends EventArgs>: A generic interface for the event. It declares the essential functionalities of the event.
  • Event<T extends EventArgs>: The default implementation for the Event which encapsulates the logic of keeping records of the registered event handlers and notifying them all upon firing the event.

Example

Now, let's see an example of an email client class that needs to declare two events. The first is message received event and the second is connection lost event. For the latter, we don't need any further information about the event other than its occurrence. The declaration of this event inside this class will be like the following:

public final IEvent<EventArgs> ConnectionLostEvent = new Event<EventArgs>();

For the message received event, we need first to create MessageRcvArgs class that contains the contents of the message.

class MessageRcvArgs extends EventArgs {......}

Then, the declaration of the event will be like the following:

public final IEvent<MessageRcvArgs> MsgReveivedEvent = new Event<MessageRcvArgs>();

So the email client class will look like the following with two extra methods for testing the events:

class EmailClient{
    
    public final IEvent<MessageRcvArgs> MsgReveivedEvent = new Event<MessageRcvArgs>();
    public final IEvent<EventArgs> ConnectionLostEvent = new Event<EventArgs>();
    
    public void testMsgRcvEvent() 
    {
        MessageRcvArgs args = new MessageRcvArgs();
        args.setSender("someone@someDomain.com");
        args.setTitle("Hello, Events");
        args.setContent("This is the message content");
        this.MsgReveivedEvent.fire(this, args);
    }
    
    public void testConnectioLostEvent()
    {
        this.ConnectionLostEvent.fire(this, EventArgs.Empty);
    }
}

Now to add event handlers for this class, we can use Lambda expression or the old way for providing immediate interface definitions. Like the following:

EmailClient client = new EmailClient();

client.MsgReveivedEvent.addHandler((sender, arg) ->
{
    System.out.println("Event Sender: " + sender.toString());
    System.out.println("Message sender: " + arg.getSender());
    System.out.println("Message title: " + arg.getTitle());
    System.out.println("Message content: " + arg.getContent());
});

client.ConnectionLostEvent.addHandler(new IEventHandler<EventArgs>() {
    @Override
    public void handle(Object sender, EventArgs args) {
        System.out.println("The connection is lost");
    }
});

client.testMsgRcvEvent();
client.testConnectioLostEvent();

The output when executed will be like the following:

Event Sender: EmailClient@2f92e0f4
Message sender: someone@someDomain.com
Message title: Hello, Events Message
content: This is the message content The connection is lost

So whenever you need to add a new event, you just need to create its event arguments class and then declare the event directly.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Mohamed.Faried
Software Developer (Senior) Valeo
Egypt Egypt
-A 7 years experience software developer who adores Software Design And Architecture.

-Conducted many sessions in OOP in Java and C#.

-Wrote programs in JavaScript, Visual Basic and C but most of my experience is with C# and Java.

-Worked also in Model Based Development for embedded systems using Statemate and MATLAB.

You may also be interested in...

Comments and Discussions

 
GeneralThe Java kids might say they are right :) Pin
OneWinsto14-Jul-15 8:59
memberOneWinsto14-Jul-15 8:59 
GeneralGood one Pin
aarif moh shaikh13-Jul-15 18:34
professionalaarif moh shaikh13-Jul-15 18:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web06 | 2.8.190419.4 | Last Updated 28 Aug 2016
Article Copyright 2015 by Mohamed.Faried
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid