在Java / JSP中寻找一种好的模式来实现对象的View适配器

时间:2011-02-03 10:10:10

标签: java design-patterns

这更像是一个设计问题。假设你有很多豆A,B,C ....然后你有一个类,用豆子创建表格。您需要一些东西来告诉这个类要显示哪些bean的属性,为列提供的名称和其他渲染属性。我不想在类中为每个bean类硬连接这个,所以我想给bean一个像TableAdapterProvider这样的通用接口,它会出现一个给渲染类提供所有指令的类。问题是我无法在Java中创建一个静态的接口方法。由于多种原因,这似乎不太干净......例如,创建一个空表我必须分配一个bean,然后调用接口方法TableAdapterProvider来检索“呈现”类。

我想创建一个像TableAdapterFactory(Class beanClass)这样的工厂,为每个bean类返回正确的TableAdapter,而不会立即执行任何操作。无论如何,我必须为我创建的每个bean更新这个工厂。

另一种解决方案可能是使用特殊的命名约定,例如,如果bean名称是Apple,则AppleTableRenderer将是渲染器。当TableRenderer启动时,我可以扫描一个包来搜索它,以便自动完成关联。

你知道更好的模式吗?您如何看待我的方法?

对于未来,是否有一本好书,其中包含这些在网络应用中使用的食谱?

3 个答案:

答案 0 :(得分:0)

你可以使用抽象类。

在抽象类中实现所选的常用方法

在每个类中实现特定于类的方法。

添加了代码。

生成表,需要使用processBean方法生成的paremeter调用generateTable方法

public abstract class Parent {
    /**
     * This method generates table from common input
     * @param commonTableMaterial
     * @return
     */
    private String generateTable(String commonTableMaterial ){
        return commonTableMaterial+"table me";
    }

    /**
     * This method is class specific - generating needed input to table
     * @return
     */
    abstract protected String processBean() ;

}

public class ChildA extends Parent {

    private String firstName ;
    private String lastName ;
    private String hiddenName ;

    @Override
    protected String processBean() {

        return firstName +lastName ;
    }
}

答案 1 :(得分:0)

也许是一个组合。保持工厂,这是你的任务的好模式:为给定bean创建正确渲染器的工厂。

但是让工厂尝试找到渲染器 - 通过扫描某个包或从配置文件中读取渲染器类名。

如果工厂找不到渲染器,它可以使用一个默认的渲染器,它只反映bean类并为所有字段创建单元格。

答案 2 :(得分:0)

对我来说,任何需要显示为HTML表(通过某种TableRenderer)的bean(A,B,C ..)都应该实现一个为渲染器提供所需信息的接口。可能的接口方法将获得列标题和表数据。也许还有一种用于桌面风格,但这有点主观。

考虑到这一点,你可能会有;

public interface Renderable
{
  public List<String> getHeaders();
  public List<List<String>> getData();
}

public class A implements Renderable
{
  private String name;
  private int age;

  public List<String> getHeaders()
  {
    List<String> headers = new ArrayList<String>();
    headers.add("Name");
    headers.add("Age");
    return list;
  }

  public List<List<String>> getData()
  {
    List<List<String>> data = new ArrayList<List<String>();
    List<String> row = new ArrayList<String>();
    row.add(name);
    row.add(String.valueOf(age));
    data.add(row);
    return data;
  }

  //getters and setters

}

编写TableRenderer;

是非常简单的
public class TableRenderer
{
  public String render(Renderable r)
  {
     //draw a HTML table
     //draw table headers from r.getHeaders()
     //draw table rows from r.getData()
  }
}

请注意,您可能希望使用JSTL TableRenderer语法,而不是编写<c:forEach>类,这是一种更标准的方法。