I read that chat is a sample of using of Mediator pattern. I wrote simple imitation of chat but I don't know how can I use mediator pattern in this situation. As I understand all my object already have loose coupling and Server class is similar to Mediator. Can someone show me using of Mediator pattern on my sample?
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class Main1 {
public static void main(String[] args) {
final Server chatObserver = new Server();
chatObserver.addObserver(new Client("User1", chatObserver));
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
chatObserver.addObserver(new Client("User2", chatObserver));
}
}, 5);
t.schedule(new TimerTask() {
@Override
public void run() {
chatObserver.addObserver(new Client("User3", chatObserver));
}
}, 10);
}
static class Client extends Observable implements Observer {
private String name;
private List<Message> chatHistoryToDisplay;
private Timer timer = new Timer();
private Random random = new Random();
public Client(final String name, Observer o) {
this.name = name;
addObserver(o);
chatHistoryToDisplay = new ArrayList<Message>(((Server) o).getChatHistory());
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
int msg = random.nextInt(10);
String str = name + " writed " + msg;
System.out.println("\t"+str);
setChanged();
notifyObservers(new Message(name,String.valueOf(msg)));
}
}, 0, 10000);
}
@Override
public void update(Observable o, Object msg) {
chatHistoryToDisplay.add((Message) msg);
System.out.println("----------- "+name+" screen -----------");
for (int i=0;i<chatHistoryToDisplay.size();i++) {
Message m = chatHistoryToDisplay.get(i);
System.out.println(m.toString());
}
}
}
static class Server extends Observable implements Observer {
private List<Message> chatHistory = new ArrayList<Message>();
@Override
public void update(Observable arg0, Object msg) {
chatHistory.add((Message) msg);
setChanged();
notifyObservers(msg);
}
public Collection<Message> getChatHistory(){
return chatHistory;
}
}
static class Message {
private String author;
private String message;
public Message(String author, String message) {
this.author = author;
this.message = message;
}
@Override
public String toString() {
return author + ": " + message;
}
}
}
CONSOLE:
User1 writed 3
----------- User1 screen -----------
User1: 3
User2 writed 9
----------- User2 screen -----------
User1: 3
User2: 9
----------- User1 screen -----------
User1: 3
User2: 9
User3 writed 9
----------- User3 screen -----------
User1: 3
User2: 9
User3: 9
----------- User2 screen -----------
User1: 3
User2: 9
User3: 9
----------- User1 screen -----------
User1: 3
User2: 9
User3: 9
and so on...
Not sure, that understand your question correctly.
But I think, in this case, you don't actually need mediator
pattern. If only there will be a lot of different objects that have to exchange some data. For example, ChatClient1 implementation, ChatClient2 implementation etc. They have to register themselves in mediator
and send commands to mediator
. Mediator knows everything about other registered classes, but every ChatClient
know nothing about others. Most of the times, this patter is using for UI.
In your case, since you only have 1 type of ChatClient and one type of Server, observer
is
appropriate