I am designing a simple chat application (just for the kick of it). I have been wondering of a simple design for that chat application. To give you overview.. here are the r
Just looking at the User
object, why does equality depend on id and nickname ? That seems a little counter intuitive to me. I would expect if you have an id, then that is the identification of the object, and hence what you'd use in an equality condition.
I see also that you have a setter for the user id. So do you really want to change user id ? I see that you can change the nickname, which makes sense. But I would expect the id to remain constant.
Note also that since you're overriding equals(), you should also override hashCode().
Now, if hashCode() and equals() rely on immutable fields (e.g. the id), then the results of hashCode() won't change, and if you put a User in a hashed collection (e.g. HashMap) then you're not going to lose it later (which is very confusing)!
Finally (!) I would protect the constructor and setters against null nicknames (make them throw IllegalArgumentExceptions) and then code like equals() doesn't have to worry about a null nickname (unless 'null' has a meaning for the nickname). I would do the same for id, since you have this as a Long (object). But couldn't this be a primitive long ?
I would suggest looking into messaging frameworks instead of using Observer pattern.
Take a look at this simple implementation which will be sufficient for your toy project - eventbus (no longer available). Alternatively you could go with full blown JMS implementation like ActiveMQ.
Basically it allows you to define a common bus to which you can register and unregister participants, and also send messages that all of the participants will see. The big advantage over observer pattern is the very low coupling between the participants - you don't register with each object to get his messages - you just register once with the bus. In addition you get asynchronous processing - let's say you have 1000 chat sessions - if you use observer it means that for each message to complete it will take to update 1000 sessions. With message framework message send is very quick, and notifying all 1000 sessions is done in the background.
The basic design looks sound to me. Obviously to complete this, you would nee to add a lot more features. The current design keeps all messages in memory indefinitely, but at some point you are going to need code for purging old messages.
The few significant design issues that I do see are: