2013-10-29 40 views
0

我是新来的java和学习设计模式。我已经实现了一个简单的用例。 一个邮件服务,我想用不同的格式表示邮件。 1)普通2)XML 3)HTMl。我写了下面的代码。这是一个战略模式

服务 -

public interface GmailService { 
public void sendMessage(); 
} 

服务实现 -

public class GmailServiceImpl implements GmailService { 

private Message message; 

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

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

}

消息接口---

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

EMessage - Ť他EMessage calss有一个构造函数与静态生成器模式,我不张贴。

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(); 
} 

信息战略 - 请注意MessageStrategy正在扩大EMessage而不是消息接口...

public abstract class MessageStrategy extends EMessage{ 

protected Message message; 

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

XMLMessage - 只的toString实现不同的是,和toString()方法不在我的界面。

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(); 
} 
} 

和HTML实现一样。 客户端代码 -

@Test 
public void testXmlMessageStrategy(){ 
    Message m = new EMessage.EMessageBuilder().subject("Hi There").to("[email protected]").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(); 
} 

现在我想知道我可以把这个作为战略格局?

+1

你最好给我们展示一个UML图,而不是java代码...... –

回答

0

策略/策略模式是可以根据运行时实例选择行为的地方。 所以这是一种行为模式。行为根据实例而改变。

现在要问的问题是 - 这里改变了什么行为。看来你只能在你的类中实现toString()方法。您的对象将对toString()调用做出不同的响应。所以理论上toString是一种策略方法。但这似乎在这里发生。没有其他策略可以区分MessageStrategy的两个子类。如果MessageStrategy没有提及任何应该由不同子类实现的策略,那么创建MessageStrategy就没有用处。

+0

好吧,所以你只是说重写“toString()”并不是好策略。比方说,我将添加一个抽象方法“formatMessage()”,该类可以实现,我们可以从抽象MessageStrategy的toString()返回这个字符串。这是一个很好的策略实施吗?这样我们可以说我们将责任交给子类。 –

+0

我不是那个意思。我的意思是即使没有创建MessageStrategy类,你也可以实现toString。一般而言,应该有一种“指定”“改变的行为”的政策方法。然后子类可以提供他们自己的这种行为的实现。在你的代码中,这恰好是没有MessageStrategy类的基本上可用的toString。所以MessageStrategy并没有真正增加任何价值。它不包含任何可以通过子类实现的行为。 – Atul