论坛首页 Java企业应用论坛

一个接口设计模式的探讨

浏览 3197 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-11-26  
OO

我在设计一个UI时,采用了模版引擎实现,为了隔绝和各模版引擎实现的依赖性,我对模版引擎进行了包装,抽象出一层接口层:

Template

  1. public interface Template {   
  2.        public void merge(Context context)throws MergeException;   
  3. }   

Context

java 代码
  1. public interface Context {   
  2.  public void clear();   
  3.   
  4.  public abstract Writer getOut();   
  5.     
  6.  public Object get(String key);   
  7.     
  8.  public void put(String key,Object value);   
  9. }   
  10.   

TemplateEngine

java 代码
  1. public interface class TemplateEngine{   
  2.   
  3.  public void mergeTemplate(String templateName, Context context,   
  4.    Writer pWriter) throws MergeException;   
  5.   
  6.  public abstract void mergeTemplate(Template template,   
  7.    Context context) throws MergeException;   
  8.   
  9. }   
  10.   

但是在各个实现包里却出现了一个非常晦涩的问题:

VelocityTemplateImpl

java 代码
  1. public class VelocityTemplate implements org.jwebap.ui.template.Template {   
  2.     
  3.  private org.apache.velocity.Template _template=null;   
  4.     
  5.  public CTLTemplate(org.apache.velocity.Template template){   
  6.   _template=template;   
  7.  }   
  8.     
  9.  public void merge(Context context) throws MergeException {   
  10.   Writer writer=context.getOut();   
  11.   if(!context instanceof VelocityContext){   
  12.    throw new ClassCastException("...");   
  13.   }   
  14.   ...;   
  15.  }   
  16.   
  17. }   
  18.   

按照接口语义,对于传进来的任何Context实现,应该都能处理,但是这里确不得不判断是不是一个VelocityContext。

java 代码
   发表时间:2007-11-26  
从上面的问题看来,Template,Context,Engine之间是紧耦合的,应该被封装在一起,那么

现在一个折衷的做法就是,取消Template接口,

修改TemplateEngine 接口,去除根据Template进行绑定的方法。

只能通过模版名称进行绑定。

同时也要去除Context接口,转而采用Map。

public interface class TemplateEngine{    
   
 public void mergeTemplate(String templateName, Map context,    
   Writer pWriter) throws MergeException;       
   
}   


这样所有的实现都紧密地放在TemplateEngine里面,但是同样也是有问题的,有些情况下外层还是需要Template和Context的。

同时,对于OO分析,只从抽象概念来考虑的话Template,Context,Engine都是很自然的模型,他们的这些行为也是很自然的。可是,因为语言实现上的一些困扰,不得以,把他们揉在一起,是因为我抽象分析的有问题,还是语言本身并不完全贴近实际意义上的OO分析?

大家给点建议
0 请登录后投票
   发表时间:2007-11-27  
1. Context definition is more like a hashmap, in my experience, this is very harmful when this appears in an interface. The reason is that at runtime, any key/value pair could be there and thus it breaks your encapsulation. With large set of data, this kind of runtime interface pencentration makes debug very hard. Take a closer look to see whether you can further isolate the uncertainty, e.g., to a variable in a method in the interface.

2. A common way to avoid the checking on the VelocityContext is to use a double-dispatcher(or visitor), make your template a visitor of the context.
0 请登录后投票
   发表时间:2007-11-27  
应该将Teamplate和Context都隐藏,只暴露TemplateEngine作为通用接口,所有传入参都用JDK中已有的常规类,
如:
public interface TemplateEngine {   
  
    public void mergeTemplate(String templateName, Map model, Writer out) throws MergeTemplateException;   
  
}


然后,每种模板引擎都实现:

public interface VelocityTemplateEngine {
	public void mergeTemplate(String templateName, Map model, Writer out) throws MergeTemplateException {
		VelocityContext...
		VelocityTemplte...
	}
}


public interface CommonTemplateEngine {
	public void mergeTemplate(String templateName, Map model, Writer out) throws MergeTemplateException {
		org.commontemplate.core.Context...
		org.commontemplate.core.Templte...
	}
}
0 请登录后投票
   发表时间:2007-11-27  
晕没看到你自己的回复已经这样改了,还不能删除,当我没说,呵呵,
0 请登录后投票
   发表时间:2007-11-27  
这样是不是也不太好啊,

难道Context对于外层,真的就只是个Map?
0 请登录后投票
   发表时间:2007-11-27  
即然要通用,你就只能取最小交集。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics