AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > JAVA编程

Java程序的脏数据问题

51自学网 2015-09-02 http://www.wanshiok.com

 

Fragment 3. 类使用的脏数据问题

  /**
    * A storage usage handler is used to query the storage usage of users.
    *
    * @version 1.0 9/9/2003
    * @author Bill
    */
   public class StorageUsageHandler implements AdminHandler {
   /**
       * Constructs a <code>StorageUsageHandler</code> instance.
   */
     private StorageUsageHandler() {
        users = Context.getAllUsers();
   }

   /**
       * Returns the storage sizes of all users.
  *
       * @return the storage sizes
   */
      public long[] getSizes() {
         long sizes[] = new long[users.size()];

        for(int i = 0; i < users.size(); i++) {
           sizes[i] = getOneSize(users.get(i));
    }
   }

   /**
       * Returns the storage size of a user.
  *
       * @param user the specified user
       * @return the storage size
   */
      protected long getSize(User user) {
         // do something...

       return 0;
   }

   /**
       * Displays the storage usage of users.
  *
       * @param req the http servlet request
       * @param res the http servlet response
  *
       * @throws IOException
       * @throws ServletException
   */
      public void process(HttpServletRequest req, HttpServletResponse res)
         throws IOException, ServletException {

         res.setContentType("text/html");
         res.setHeader("Cache-Control", "no-cache");
         res.setHeader("Pragma","no-cache");
         res.setDateHeader("Expires", 0);

         PrintWriter writer = new PrintWriter(res.getOutputStream());
         long sizes[] = getsizes();
         writer.println("<html><title>Storage Usage</title><body>");
         writer.println("<table width='100%'>");

        for(int i = 0; i < sizes.length; i++) {
           writer.print("<tr><td align='center' nowrap>");
           writer.print(users.get(i) + ": " + sizes[i]);
           writer.println("</td></tr>");
      }

         writer.println("</body></html>");
         writer.flush();
         writer.close();
   }

   /**
       * The users.
   */
     private List users;
  }

  /**
    * An admin servlet as a http servlet to process the admin http servlet
    * request and response.
    *
    * @version 1.0 9/9/2003
    * @author Bill
    */
   public class AdminServlet extends HttpServlet {
   /**
       * Initiates the configuration.
  *
       * @param config the servlet config
  *
       * @throws ServletException
   */
     private void initConfig(ServletConfig config) throws ServletException {
         // do something...

         handlerMap.put("__storage_Usage__", new StorageUsageHandler());
   }

   /**
       * Processes the http servlet request and response.
  *
       * @throws IOException
       * @throws ServletException
   */
      public void service(HttpServletRequest req, HttpServletResponse res)
         throws IOException, ServletException {

         AdminHandler handler = handlerMap.get(req.getParameter("handler"));

         if(handler == null) {
           // do something...

           return;
      }

         handler.process(req, res);
   }

   /**
       * The admin handler map(handler name->handler).
   */
     private HashMap handlerMap = new HashMap();
  }

  您一定看出了问题所在吧!

  Fragment 3中,由于StorageUsageHandler并不遵循Singleton模式,尽管StorageUsageHandler的类成员users只能在实例化StorageUsageHandler时被赋值,但是在单线程模式下,只要保证每次所使用的StorageUsageHandler实例是新实例化的,基本上还是没有问题的。

  问题在于,在初始化AdminServlet的过程中,StorageUsageHandler被实例化并存储起来。此后,除非servlet container重新装载AdminServlet,否则将无法重新实例化StorageUsageHandler,也将无法更新StorageUsageHandler的类成员users。这样,在发生了增加、删除或修改用户的操作之后,users将成为脏数据。

  如何避免类使用所带来的脏数据问题呢?

  i. 对于与类外部无依赖关系的类成员,不存在这种问题;
  ii. 对于依赖于类外部的类成员,且该类成员不存在更新机制。最好是将其去掉,需要时从类外部直接获取;如果这种办法不可行,应提供机制以确保在使用该类成员之前,该类成员已经被更新过;如果这种办法还不可行,请清晰地说明类的使用方式,以防止不当的类使用发生。

  小节

  以上用三个例子列举了三类常见的脏数据问题。事实上,Java程序中的脏数据问题存在形式非常多样,因而,在设计、实现、测试和重构过程中,紧记(Keep in mind)避免脏数据的存在是非常重要的,我们可以从系统、子系统、类和类成员等各个层次来检查Java程序。
   “只做好一件事”是对简单性的最佳诠释,这句话同样最好地诠释了软件系统在功能方面的正交性。然而,在面向对象的软件开发过程中,仅仅在功能方面确保正交性是不够的,还应该在数据存储方面来尽量保证正交性。当然,考虑到性能等因素,在数据存储方面确保正交性比较困难,对于破坏此规则的数据存储,应提供机制以确保所使用数据的实时性。

 
 
说明
:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。
 

上一篇:开发基于JBoss的J2EE应用  下一篇:Java列表对象的性能分析和测试