0

I am new to java and learning Design Patterns. I have implemented a simple use case. a mail service, in which i want to represent the mail in different formats. 1) Plain 2) XML 3 ) HTMl . I have written following code .

The service --

public interface GmailService {
public void sendMessage();
}

Service Implementation --

public class GmailServiceImpl implements GmailService {

private Message message;

public GmailServiceImpl(Message message){
    this.message = message;
}

@Override
public void sendMessage(){
    System.out.println(this.message);
}

}

Message Interface ---

public interface Message {
public String getBody();
public String getSubject();
public String getTo();
}

EMessage -- The EMessage calss has a constructor with Static Builder pattern, i am not posting that.

public class EMessage implements Message {

protected String to;
protected String body;
protected String subject;

@Override
public String getBody(){
    return this.body;
}

@Override
public String getSubject() {
    return this.subject;
}

@Override
public String getTo() {
    return this.to;
}

protected Field[] getClassFields(){
    return this.getClass().getDeclaredFields();
}

@Override
public String toString(){
    StringBuilder sb = new StringBuilder();
    Field[] fileds = this.getClass().getDeclaredFields();
    for(Field field:fileds){
        try {
            sb.append(field.getName()).append(":-").append(field.get(this)).append(" ");
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    return sb.toString();
}

Message Strategy -- Please note MessageStrategy is extending EMessage and not the Message Interface...

public abstract class MessageStrategy extends EMessage{

protected Message message;

public MessageStrategy(Message message){
    this.message = message;
}
}

XMLMessage -- Only the toString implementation is different, and toString() method is not in my interface.

public class XMLMessage extends MessageStrategy {

public XMLMessage(Message message) {
    super(message);
}

@Override
public String toString(){
    StringBuilder sb = new StringBuilder();
    Field[] fields = this.message.getClass().getDeclaredFields();
    sb.append("<class>");
    for(Field field:fields){
        try {
            sb.append("<filed><name>").append(field.getName()).append("</name><value>").append(field.get(this.message)).append("</value><field>");
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    sb.append("</class>");
    return sb.toString();
}
 }

And same way there is HTML implementation. Client code is --

  @Test
public void testXmlMessageStrategy(){
    Message m = new EMessage.EMessageBuilder().subject("Hi There").to("toSomeone@gmail.com").body("How r u buddy").build();

    MessageStrategy xMessage = new  XMLMessage(m);
    GmailService service = new GmailServiceImpl(xMessage);
    service.sendMessage();

    System.out.println();

    MessageStrategy htmlMessage = new HTMLMessage(m);
    service = new GmailServiceImpl(htmlMessage);
    service.sendMessage();
}

Now i want to know can i call this as Strategy Pattern ?

1 Answers1

0

The strategy/policy pattern is where behaviour can be selected based on the runtime instance. So it is a behavioural pattern. And the behaviour changes as per the instance.

Now the question to ask here is- what behaviour is being changed here. It seems that you only implement toString() methods in your classes. Your objects will respond differently to toString() invocations. So theoretically toString is a strategy method. But that seems to be pretty much happening here. There is no additional policy differentiating the two subclasses of MessageStrategy. There is no use creating MessageStrategy if it does not mention any strategy that should be implemented differently by different subclasses.

Atul
  • 2,673
  • 2
  • 28
  • 34
  • Ok, so you are saying that just overriding "toString()" is not good strategy. Lets say, i will add a abstract method "formatMessage()", which subclasses can implement and we can return this string from toString() of abstract MessageStrategy. Will it be a good implementation for strategy ? This way we can say that we are giving responsibility to subclasses. – Gunwant Walbe Oct 29 '13 at 12:45
  • I did not mean that. I meant even without creating MessageStrategy class, you could implement toString. Generally there should be a policy method 'specifying' the 'behaviour which changes'. Then subclasses can provide their own implementation of that behaviour. In your code this happens to be toString which is basically available without MessageStrategy class. So MessageStrategy is not really adding any value. It does not contain any behaviour which could be implemented differently by subclasses. – Atul Oct 29 '13 at 13:18