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 rules:
THATS IT! (See I told you it was a simple chat application). So, my intention is not really the application; but the design pattern and objects used in it.
Now here is how I have designed it. (I am coding in java.. in case that really matters)
Alright.. so now I have implemented observer pattern by making ChatWindow implement "ChatListener" patter which has method called "notify(Message)". So ChatSession notifies every registered ChatWindow.
Now here are few things I want to clarify/want your opinion on. 1. I need to have de-register method also for all chat windows, in case a chat window is closed and doesn't want to get any more notifications. That potentially means, that either I should have a "Static" central registration manager which has only one instance and then any chat window should be able to de-register itself by providing a "chat session" id. For that reason, each chat session should have an id. (Included hereon). OR I could maintain an instance of ChatSession in Chat Window too, to always have an instance ready. (I hate singletons as I think they go against oops). Another way would be to not have de-registration control of chat window, with chat window, instead the notification of window closure should come directly to ChatSession and it should do, what it should do!
Does this design makes sense at all? If you'd say it's a piece of CRAP and give me a yet better approach; you'll definitely get a BIG THANK YOU from me. Apart from observer pattern what all patterns could be used here to simplify it more or make it better. Also.. any weak points of this design, if it's appropriate but can be improved.
Also when a user types a new message in his own chat window; it needs to be propogated to all chat windows, which is what chat session does, but at the same time; does that mean that.. chat session needs to get a message with "chat window id" and message? And then it propogates it to all windows, including the one which is the owner of the message? What is a better way to handle this. I mean, a way where window lets the chat session know of the message and then chat session to all other windows. (I am thinking it'll need some if's... don't like them either)
Anyway... do let me know your comments. Also please rem. working application is not the intent, I am looking for a good discussion, good Design pattern practices and usage.
Complete code below, if it gives you a high... Feel free to tear it apart and bring up issues related to almost any semantics.
package com.oo.chat;
public class User {
private Long userId;
private String nickname;
public User(Long userId, String nickname) {
this.userId = userId;
this.nickname = nickname;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Long getUserId() {
return userId;
}
public String getNickname() {
return nickname;
}
public boolean equals(Object objectToCompare) {
if (!(objectToCompare instanceof User)) {
return false;
}
User incoming = (User) objectToCompare;
if (incoming.getNickname() != null && incoming.getUserId() != null) {
if (incoming.getNickname().equalsIgnoreCase(this.nickname)
&& incoming.getUserId().equals(this.userId))
return true;
}
return false;
}
}
package com.oo.chat;
public interface Message {
public String getValue();
public void setValue(String value);
}
package com.oo.chat;
public class SimpleMessage implements Message {
private String value;
public SimpleMessage() {
}
public SimpleMessage(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package com.oo.chat;
public interface ChatListener {
public void notify(Message newMessage);
}
package com.oo.chat;
import java.util.ArrayList;
import java.util.List;
public class ChatWindow implements ChatListener {
private User user;
private List<Message> messageList;
private Long id;
public User getUser() {
return user;
}
public List<Message> getMessageList() {
return messageList;
}
public void setUser(User user) {
this.user = user;
}
public void setMessageList(List<Message> messageList) {
this.messageList = messageList;
}
public void addMessageToList(Message newMessage) {
if (this.messageList == null) {
this.messageList = new ArrayList<Message>();
}
this.messageList.add(newMessage);
}
public void notify(Message newMessage) {
addMessageToList(newMessage);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
package com.oo.chat;
import java.util.ArrayList;
import java.util.List;
public class ChatSession {
private List<ChatListener> registeredChatListeners;
public void register(ChatWindow chatWindow) {
if (registeredChatListeners == null)
registeredChatListeners = new ArrayList<ChatListener>();
registeredChatListeners.add(chatWindow);
}
public List<ChatListener> getRegisteredChatListeners() {
return registeredChatListeners;
}
public void setRegisteredChatWindows(
List<ChatListener> registeredChatListeners) {
this.registeredChatListeners = registeredChatListeners;
}
public void incomingMessage(Long chatListenerId, Message message) {
publish(message);
}
protected void publish(Message messageToPublish) {
if (registeredChatListeners != null) {
for (ChatListener eachListener : registeredChatListeners) {
eachListener.notify(messageToPublish);
}
}
}
}
Thanks to all contributers in advance. Cheers
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With