请教此时该如何设计接口?

public interface MyRenderer {
    String render(MyModel m);
}

如上所示的接口,当我实现一个将我的 model 转为 json 的字符串时,这样的设计是足够的。

但当我想要实现一个使用 Freemarker 根据一个模板文件将我的 model 渲染为一个 HTML 文件时。我发现此时的 render 方法与 “可以灵活地改变模板文件” 的需求冲突了——当然可以使用一个成员变量来实现这样的渲染器,但是如此一来,模板文件换一个,就要新生成一个实例?又或者对保存模板文件的成员开放 setter,每次修改模板文件前调用再渲染?可是这样就要考虑潜在的多线程不安全的风险了。。

而将 remder 方法改变,改为

public interface MyRenderer {
    String render(MyModel m, File templateFile);
}

可是这对于使用 jackson 将 model 渲染为 json 的实现来说,第二个参数完全多余。而这样的多余发生在作为抽象的最顶层的接口上,这是良好的设计吗?

谢谢。

阅读 1.5k
1 个回答
public interface Render  {

  Function<Model, String> JACKSON_RENDER = model -> json2str(model);
  Function<File, Function<Model, String>> FREEMARKER_RENDER = template -> model -> renderWithModelAndTemplate(model, template);

  static String render(Model model, Function<Model, String> function) {
    return function.apply(model);
  }
}

// Using
Render.render(model, Render.JACKSON_RENDER);
Render.render(model, Render.FREEMARKDER_RENDER.apply(template));

本质上就是把渲染过程延迟到第二个参数,这样就抽出来了.

所以写成这样也行:

Render.JACKSON_RENDER.apply(model);
Render.FREEMARKER_RENDER.apply(template).apply(model);

Render#render 只是包装了一下.

这种做法可以适应 if/switch/streaming, 你只要能判断出要渲染成哪种目标格式,就可以填充目标格式所需要的额外参数.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题