I have implemented the following scenario for the Mediator pattern sample:
MailingListMediator
: Manages the subscription and send the mail back and forth.
JavaMailingList
SQLMailingList
(Colleagues)MailUsers
: They can login, subscribe to the mailing list, send mails to mailing list.
GmailUsers
YahooUsers
My implementation looks like this:
MailingListMediator
public abstract class MailingListMediator {
protected List<MailUser> mailingList;
public MailingListMediator() {
this.mailingList = new ArrayList<MailUser>();
}
public void sendMail(String message){
for(MailUser mUser:mailingList){
System.out.println("Mail message: '"+message+"' sent to "+ mUser.getMailId());
}
}
public abstract String subscribe(MailUser mailUser);
}
MailUser
public abstract class MailUser {
public abstract void login(String mailID);
public abstract void sendMailToMailingList(MailingListMediator mailingList, String message);
public abstract String getMailId();
}
GmailUser
public class GmailUser extends MailUser {
String mailID;
@Override
public void login(String mailID) {
this.mailID = mailID;
}
@Override
public void sendMailToMailingList(MailingListMediator mailingList, String message) {
mailingList.sendMail(message);
}
@Override
public String getMailId() {
if(mailID != null){
return mailID;
}else{
return "Login First";
}
}
}
YahooUser
public class YahooUser extends MailUser {
String mailID;
@Override
public void login(String mailID) {
this.mailID = mailID;
}
@Override
public void sendMailToMailingList(MailingListMediator mailingList, String message) {
mailingList.sendMail(message);
}
@Override
public String getMailId() {
if(mailID != null){
return mailID;
}else{
return "Login First";
}
}
}
JavaMailingList
public class JavaMailingList extends MailingListMediator {
private final String mailingListId = "java";
@Override
public String subscribe(MailUser mailUser) {
mailingList.add(mailUser);
return mailingListId;
}
}
SQLMailingList
public class SQLMailingList extends MailingListMediator {
private final String mailingListId = "sql";
@Override
public String subscribe(MailUser mailUser) {
mailingList.add(mailUser);
return mailingListId;
}
}
ForumUsers
public class ForumUsers{
public static void main(String[] args) {
MailingListMediator javaMailingList = new JavaMailingList();
//User 1
MailUser gmail = new GmailUser();
gmail.login("[email protected]");
javaMailingList.subscribe(gmail); // He subscribes
//User 2
MailUser yahoo = new YahooUser();
yahoo.login("[email protected]");
javaMailingList.subscribe(yahoo); // He subscribes
//gmail user sends a question to the Java Mailing List
gmail.sendMailToMailingList(javaMailingList, "How to excel in Java??!!");
}
}
Does this implementation adhere to the Mediator Design? What improvements can be made?
3 Answers 3
login
is a setter method and should be named setLogin
, or even better, only used in the constructor to make subclasses of MailUser
immutable
-
\$\begingroup\$ Since,its not a real implementation, but just a simulation of Mediator pattern, I have done it with assumption like login logic will differ for different type of mail users. \$\endgroup\$Sowmiya– Sowmiya2014年06月15日 05:42:19 +00:00Commented Jun 15, 2014 at 5:42
-
\$\begingroup\$ This you should have a
MailUser(address)
constructor and alogin()
instead. \$\endgroup\$rds– rds2014年06月15日 10:17:37 +00:00Commented Jun 15, 2014 at 10:17 -
\$\begingroup\$ Understood.I have done those design changes. \$\endgroup\$Sowmiya– Sowmiya2014年06月16日 05:42:38 +00:00Commented Jun 16, 2014 at 5:42
I am not familiar with the Mediator pattern, but I think your code is not complex enough to make good use of the pattern. Take your JavaMailingList
and SQLMailingList
, what is the difference between those classes ? The value of mailingListId
. The implementation of subscribe
is exactly the same, you add the same variable to the class. If your MailingListMediator
would look like :
public class MailingListMediator {
private final String mailingListId;
protected List<MailUser> mailingList;
public MailingListMediator(String mailingListId) {
this.mailingList = new ArrayList<MailUser>();
this.mailingListId = mailingListId;
}
public void sendMail(String message){
for(MailUser mUser:mailingList){
System.out.println("Mail message: '"+message+"' sent to "+ mUser.getMailId());
}
}
public String subscribe(MailUser mailUser) {
mailingList.add(mailUser);
return mailingListId;
}
}
There is suddenly no need for JavaMailingList
and SQLMailingList
.
The same principle apply to YahooUser
and GmailUser
. Those classes are almost a copy-paste of each other. Same implementation for all the methods and adding the same variable to the class. Why is mailID
an attribute in the children classes but not in MailUser
? I could repeat the same process that I used for MailingListMediator
and I could remove YahooUser
and GmailUser
.
My conclusion is your code looks like trying to be complicated when in fact it is not. You want to try the Mediator pattern ? Well wait when you will need it, do not force your code into a pattern. Pattern will be useful when you need it, otherwise it will only make your code less readable and harder to maintain.
Since you wanted to implement the Mediator pattern, I will expand more on that part. You do have a mediator pattern implemented. Your "colleagues" do interact between each other through the mediator that is the MailingList
. There isn't a MailUser
that interact directly with each other, that is the main point of the mediator pattern. Do know that your example is a little weak. I would suggest you, if you really want to test the mediator pattern, try a to code a chat application. This could be a good exercise since you will have a lot of users that will need to communicate, but you don't want the class to be tightly coupled.
-
\$\begingroup\$ Thanks for that. I get what you are telling. But all I wanted to do is not a real implementation of a Mailing List, but to simulate a scenario to understand how the Mediator Pattern works. \$\endgroup\$Sowmiya– Sowmiya2014年06月13日 16:41:34 +00:00Commented Jun 13, 2014 at 16:41
-
\$\begingroup\$ @Sowmiya From what I'm reading of the mediator pattern it looks like a good implementation of the pattern. \$\endgroup\$Marc-Andre– Marc-Andre2014年06月13日 16:59:15 +00:00Commented Jun 13, 2014 at 16:59
-
1\$\begingroup\$ @Sowmiya this could be a good link to read : stackoverflow.com/questions/373598/… \$\endgroup\$Marc-Andre– Marc-Andre2014年06月13日 17:12:11 +00:00Commented Jun 13, 2014 at 17:12
In your case, you just have several classes that implement the same MailUser
interface. That's just inheritance.
I'm not familiar with mediator pattern, but I see it like a hub. From Wikipedia:
The essence of the Mediator Pattern is to "Define an object that encapsulates how a set of objects interact".
Here, the different MailUsers don't interact with each other.
-
\$\begingroup\$ Mailusers do interact with each other, through the MailingList. (MailUser can send mails to MailingList, which encloses other(subscribed) MailUsers). \$\endgroup\$Sowmiya– Sowmiya2014年06月15日 05:21:43 +00:00Commented Jun 15, 2014 at 5:21
-
\$\begingroup\$ That would be a mediator pattern if the YahooMailUser and GmailMailUser had different interfaces. But here, you simply have a MailingList that contains MailUsers of different implementations. See also Head first on design patterns \$\endgroup\$rds– rds2014年06月15日 10:24:58 +00:00Commented Jun 15, 2014 at 10:24
-
\$\begingroup\$ I get it. But as I see in this link's chatroom example, the Colleague's can be of same type also, is what I understand. Correct me if I am wrong. \$\endgroup\$Sowmiya– Sowmiya2014年06月16日 05:00:19 +00:00Commented Jun 16, 2014 at 5:00
Explore related questions
See similar questions with these tags.