论坛首页 Java企业应用论坛

代码擂台,特别有请buaawhl

浏览 69608 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-07-28  
用servlet来实现:

//////////////////////////////////////////////////////

public class hi extends HttpServlet {
  private static final String CONTENT_TYPE = "text/html; CHARSET=utf8";

  //Initialize global variables
  public void init(); throws ServletException {
  }

  //Process the HTTP Get request
  public void doGet(HttpServletRequest request, HttpServletResponse response); throws ServletException, IOException {
    response.setContentType(CONTENT_TYPE);;
    PrintWriter out = response.getWriter();;
    
    /////////////////////////////////
    // 处理部分

    Table tbl = new Table();;

    Person psn1 = new Person();;
    psn1.setName("zhang san");;
    psn1.setAverage(80);;
    psn1.addSubject("yu wen",80);;

    Person psn2 = new Person();;
    psn2.setName("li si");;
    psn2.setAverage(85);;
    psn2.addSubject("yu wen",80);;
    psn2.addSubject("shu xue",90);;
    
    tbl.addRow(psn1);;
    tbl.addRow(psn2);;
    
    // 处理结束
   ///////////////////////////////////

    out.println("<html>");;
    out.println("<head><title>hi</title></head>");;
    out.println("<body bgcolor=\"#ffffff\">");;
    out.println("<p>The servlet has received a GET. This is the reply.</p>");;
    out.println(tbl.getContent(););;
    out.println("</body></html>");;
  }

  //Clean up resources
  public void destroy(); {
  }
}


///////////////////////////////////////////

public class Table {
  private String rows;

  // 初始化
  public Table(); {
    rows = new String();;
  }

  // 添加一行
  public void addRow(TableRow row); {
          rows += row;
  }

  // 取表内容
  public String getContent(); {
          rows = "<table border=1>"+rows+"</table>";
          return rows;
  }
}


/////////////////////////////////////////

interface TableRow {
  String toString();;
}


///////////////////////////////////////////

public class Person implements TableRow {
  private String name;
  private int average;
  private Subject[] subjects;
  private int subjectCount;

  // 初始化
  public Person(); {
    name = null;
    average = 0;
    subjects = new Subject[2];
    subjectCount = 0;
  }

  // 初始化
  public Person(String name); {
    this.name = name;
    average = 0;
    subjects = new Subject[2];
    subjectCount = 0;
  }

  // 设置名字
  public void setName(String name); {
    this.name = name;
  }

  // 设置平均成绩
  public void setAverage(int aver); {
    average = aver;
  }

  // 添加科目
  public void addSubject(String name,int num); {
    subjects[subjectCount] = new Subject();;
    subjects[subjectCount].setName(name);;
    subjects[subjectCount].setNum(num);;
    subjectCount++;
  }
  
  // 添加科目
  public void addSubject(Subject sub); {
    subjects[subjectCount++] = sub;
  }

  // 转化成字符串
  public String toString(); {
    String item = new String();;

    item += "<tr>";
    item += "<td rowspan='"+subjectCount+"'>"+name+"</td>";
    item += "<td rowspan='"+subjectCount+"'>"+average+"</td>";
    item += "<td>"+subjects[0].getName();+"</td>";
    item += "<td>"+subjects[0].getNum();+"</td>";
    item += "</tr>";

    for(int i=1; i<subjectCount; i++); {
      item += "<tr>";
      item += "<td>"+subjects[i].getName();+"</td>";
      item += "<td>"+subjects[i].getNum();+"</td>";
      item += "</tr>";
    }

    return item;
  }
}


///////////////////////////////////////////

public class Subject {
  private String name;
  private int num;

  // 初始化
  Subject(); {
    name = null;
    num = 0;
  }

  // 初始化
  Subject(String name,int num); {
    this.name = name;
    this.num = num;
  }

  // 设置科目名称
  public void setName(String name); {
    this.name = name;
  }

  // 设置科目分数
  public void setNum(int num); {
    this.num = num;
  }

  // 取科目名称
  public String getName(); {
    return name;
  }

  // 取科目分数
  public int getNum(); {
    return num;
  }
}



对服务项目列表可以使用一个实现 TableRow 接口的类来完成。最重要的格式化工作由 TableRow 中的 toString() 来完成。toString() 放到接口里面是为了强制实现该方法。

这里没有考虑优化的问题以及一些异常问题,有部分代码是硬编码,不过这会使代码比较清晰。

如果希望这段代码更加通用,可以考虑把 toString() 中的格式化操作再抽象出来做一个格式化器,但是这样做的代价会很高。即使作出来了可能也会难于理解。

如果希望用 jsp+javabean 的方式做,可以把 Person 类做成 javabean ,再把 Table 做的工作拿给 jsp 去做。

如果希望做成一个简单的框架,可以把 Table 和 TableRow 打包拿来分发使用,但是这样可能会使人不满意,因为重要的处理格式的部分仍然是交给使用者完成的,因此想做得完善些可能就必须完成格式化器的设计。一个通用格式化器需要耗费的精力是多少大家可以自己估算一下再决定值不值得。

如果希望做成一个可以动态发布的框架,如把 Person 换成 ServiceItem(服务项目),可能就需要用到工厂模式,以及在 Person 和 ServiceItem 中实现注册机制并且需要在运行系统中检测发布目录的变化以便自动装载。

如果希望实现分布式,可能需要把 Person 封装成 EJB ;

上述代码已经通过测试。

后面的论述是我进一步的考虑。我觉得现在的模式和框架这些名词铺天盖地,很多人不自觉的把能够比别人多说几个玄乎的术语认为是一件非常得意的事,经常讨论各种术语的深刻含义。其实这些术语在作为一种规范或者一种文献的载体是很合适的,因为简短的词语有不少美妙的含义包含在里面,但是作为实践者,应该剔除这种神秘的面纱,给以朴实的解释。现在不少人沉迷在模式和各种美妙的名词里面不能自拔了,我觉得这不是一件好事。
0 请登录后投票
   发表时间:2004-07-29  
我没看错吧?

public class Person implements TableRow 

person实现了一个tablerow接口,一个业务或者实体对象去实现一个view接口?

如果你要显示在一个tab page上,person是不是要实现tabpage接口?

我都不忍心说了,不过面向对象的模式和框架的历史已经整整超过了10个年头了,对计算机软件的发展史来说,这些实在是老得不能再老的东西了,讨论这些东西就好比讨论if then else一样没什么特别的,也没有什么值得说的。
0 请登录后投票
   发表时间:2004-07-29  
好象我也做过这样的事情。。。。。
我的Exception还有toJS()方法呢,实现自动为exception生成报告错误然后返回上页的javascript,现在想起来,汗死=。=!!
0 请登录后投票
   发表时间:2004-07-29  
potian 写道
我没看错吧?

public class Person implements TableRow 

person实现了一个tablerow接口,一个业务或者实体对象去实现一个view接口?

如果你要显示在一个tab page上,person是不是要实现tabpage接口?



你没有看错,这样做其实很自然。这段代码还没有很高的抽象度,但是扩展性已经有了,而且代码很清晰。不管业务和视图的隔离度有多高,业务到视图时总会有一个格式化输出的过程,因此数据和视图之间总会有发生交互的时候,在这里我选择了 Person 的另外一个属性 TableRow 作为交互点。不管是 Person 还是 ServiceItem , 它们在 Table 中都是作为 Row 存在的,因此把TableRow 作为一个接口提取出来并且把格式化操作规定在这个接口里。因为格式化的目的和数据是紧密相关的,因此我把格式化的操作放到了业务对象中。当然,格式化的操作也可以放到 Table 中,让 Person 和 ServiceItem 仅提供数据,但是这样一来,对格式的要求相对会比较死板一点,因为 Table 中需要尽可能考虑各种格式化的要求,在这种情况下,为了简化通用格式化操作的设计难度,通常会对格式提出不少附加条件以便使格式变化的可能性更小。当然,如果对格式的要求是固定的,那么格式化的操作放到 Table 中来是最恰当的。这样一来,上述代码的体系结构可能就会变成:

interface Data {
}

class Person implements Data {
}

class ServiceItem implements Data {
}

class Table {
}

其中,Data 接口规定了数据格式规范,Person 和 ServiceItem 实现这个规范,Table 中通过 Data 接口实现通用格式化操作。这样一来,视图和数据可以显得分离度更高,但是设计难度也在增加。
0 请登录后投票
   发表时间:2004-07-29  
potian 写道
我没看错吧?

public class Person implements TableRow 

如果你要显示在一个tab page上,person是不是要实现tabpage接口?



这要看tab page对格式的要求是怎么样的。如果不同的格式之间变化很大,我还是会选择把格式的实现放在 Person 中。这样可以把避免蹩脚的通用格式化设计放到 tab page 中,因为一旦将来格式变化很大,这个通用格式化会变得难以维护,而且也许会成为业务扩展的瓶颈。
0 请登录后投票
   发表时间:2004-07-29  
我认为不能让模式的概念成为实践的束缚,不能生硬的套模式。实际上,模式仅仅是一个通常情况下较佳的情景抽象,但是一个模式的名词本身不会包含太多的信息,它只是反映了一种通用的设计倾向。实践中涉及到的情景规模大小、产品可扩展性要求这些重要的信息并没有包含到这样的一个名词里,这些都可能会导致模式的变形,以致真正实现的模式与书上描述的模式看起来有很多的不同,但是这又有什么关系?关键在于我们根据实际情况作出了最佳的设计决策,而不是死板的套用某种经典模式。
0 请登录后投票
   发表时间:2004-07-29  
Apache Jakarta有一个构造HTML元素的项目。
http://jakarta.apache.org/ecs/index.html
0 请登录后投票
   发表时间:2004-07-29  
buaawhl 写道
Apache Jakarta有一个构造HTML元素的项目。
http://jakarta.apache.org/ecs/index.html

我看了一下这个项目的应用例子,我觉得这里的这个题目没有多大的帮助,因为题目中的格式是跟数据的显示要求紧密相关的,而这个项目只是把固定不变的HTML标签重新用java封装了一遍而已,对这里几乎无用。
0 请登录后投票
   发表时间:2004-07-29  
youngS 写道
我认为不能让模式的概念成为实践的束缚,不能生硬的套模式。实际上,模式仅仅是一个通常情况下较佳的情景抽象,但是一个模式的名词本身不会包含太多的信息,它只是反映了一种通用的设计倾向。实践中涉及到的情景规模大小、产品可扩展性要求这些重要的信息并没有包含到这样的一个名词里,这些都可能会导致模式的变形,以致真正实现的模式与书上描述的模式看起来有很多的不同,但是这又有什么关系?关键在于我们根据实际情况作出了最佳的设计决策,而不是死板的套用某种经典模式。


感觉像是在狡辩。
0 请登录后投票
   发表时间:2004-07-29  
为何?呵呵
我想表达的意思是,不能先入为主的摆一个模式的框框在自己的脑海里,然后使劲去套用,最重要的是观察项目的各种要求和边界情况再做决定。模式当然重要,通过模式我们可以观察一种有效的实施决策,不过不由自主的把套用模式当作行为准则却是不该。
0 请登录后投票
论坛首页 Java企业应用版

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