yutian727

面向对象设计的原则

      明天就是五一了,先祝各位老友们五一快乐。
      公司终于让我做设计了,哈哈,不过是详细设计,还没有到系统的份上。不还我还是比较满意的,以前有辞职的想法,现在,怎么也要等这个项目做完之后再说了。
      这段时间一直在研究“面向对象设计的原则”,以下是学习的一点经验:
      1.类的设计原则
         在网上,一般认为灯的设计原则有五类,如下:
   1)SRP,单一职责原则,一个类应该有且只有一个改变的理由。 
                  所谓单一职责原则,就是就一个类而言,应该仅有一个引起它的变化的原因。换句话说,一个类的功能要单一,只做与它相关的事情。
  这个原则是最简单、最容易理解,却是最不容易做到的事情。这个原则的道理谁都理解,可是在实践中呢?

  我们来看一个例子:

if(action.equals("load")&&tab.equals("1")){
request.setAttribute("tabId",tab);
form.set("tabId",tab);
speciManager.loadIncrement(actionForm, request, tab);
}
if(action.equals("Save")&&tab.equals("1")){
System.out.println("inter increment save action");
……
request.setAttribute("tabId",tab);
}
if(action.equals("load")&&tab.equals("2")){
request.setAttribute("tabId",tab);
form.set("tabId",tab);
speciManager.loadMeasureMent(actionForm, request, tab);
}
if(action.equals("Save")&&tab.equals("2")){
……
System.out.println("inter increment save action");
speciManager.loadIncrement(actionForm, request, tab);
form.set("tabId",tab);
request.setAttribute("tabId",tab);

}
  一看就知道这个类做了太多的工作,它既要load一个tab为1的页面和一个tab为2的页面;又要save一个tab为1页面和一个tab为2的页面。这个类的代码我只截取了里面很少的一部分,绝大部分的代码我都省略掉了。这段代码写到最后是越来越混乱,直到最后失败。

  对照着这个例子,我们再来分析一下为什么要遵守单一职责愿则:

  第一、有助于我们分析和编码的思路的清晰。当你的代码里有了三层或以上的if语句或for语句的嵌套的时候,你不要跟我说,你已经把问题分析得很清楚了。多层嵌套的if或for语句只能说明你还没有把问题分析清楚。

  第二、使我们的编码、测试和维护变得简单。

  第三、将一个个复杂的问题简单化以后,易于代码的重用。当你的代码的多个功能搅和在一起的时候,你是没办法考虑代码的重用的,因为你的每一处代码都有不同。

  第四、易于系统的扩展。 
 2)OCP,开放封闭原则,你应该能够不用修改原有类就能扩展一个类的行为。 
               “开一闭”原则讲的是:一个软件实体应当对扩展开放,对修改关闭。 这个规则说的是,在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展。 从另外一个角度讲,就是所谓的“对可变性封装原则”。“对可变性封装原则”意味着两点: 1 .一种可变性不应当散落在代码的很多角落里,而应当被封装到一个对象里面。同一种可变性的不同表象意味着同一个继承等级结构中的具体子类。 2.一种可变性不应当与另一种可变性混合在一起。即类图的继承结构一般不应超过两层。 做到“开—闭”原则不是一件容易的事,但是也有很多规律可循,这些规律同样也是设计原则,它们是实现开—闭原则的工具
  3)  LSP,Liskov替换原则,派生类要与其基类自相容。 
                   里氏代换原则:就是子类代替父类,程序或者代码的行为不变。例如如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有对象o1都换成o2时,程序P的行为没有变化,那么类型T2是T1的子类型。 即如果一个软件实体使用的是基类的话那么也一定适用于子类。但反过来的代换不成立。 如果有两个具体类A和B之间的关系违反了里氏代换原则,可以在以下两种重构方案中选择一种: 1 创建一个新的抽象类C,作为两个具体类的超类,将A和B共同的行为移动到C中,从而解决A和B行为不完全一致的问题。 2 从B到A的继承关系改写为委派关系。 
 4) DIP,依赖倒置原则,依赖于抽象而不是实现。 
                  依赖倒转原则讲的是:要依赖于抽象,不要依赖于具体。即针对接口编程,不要针对实现编程。针对接口编程的意思是,应当使用接口和抽象类进行变量的类型声明、参量的类型声明,方法的返还类型声明,以及数据类型的转换等。不要针对实现编程的意思就是说,不应当使用具体类进行变量的类型声明、参量的类型声明,方法的返还类型声明,以及数据类型的转换等。 依赖倒转原则虽然强大,但却不易实现,因为依赖倒转的缘故,对象的创建很可能要使用对象工厂,以避免对具体类的直接引用,此原则的使用还会导致大量的类。维护这样的系统需要较好的面向对象的设计知识。 此外,依赖倒转原则假定所有的具体类都是变化的,这也不总是正确的。有一些具体类可能是相当稳定、不会发生变化的,消费这个具体类实例的客户端完全可以依赖于这个具体类。
  5) ISP,接口隔离原则,客户只要关注它们所需的接口。 
                  接口隔离原则讲的是:使用多个专门的接口比使用单一的接口要好。从客户的角度来说:一个类对另外一个类的依赖性应当是建立在最小的接口上的。如果客户端只需要某一些方法的话,那么就应当向客户端提供这些需要的方法,而不要提供不需要的方法。提供接口意味着向客户端作出承诺,过多的承诺会给系统的维护造成不必要的负担。 

         2.包原则

      REP,重用发布等价原则,重用的粒度就是发布的粒度。 
      CCP,共同封闭原则,包中的所有类对于同一类性质的变化应该是共同封闭的。  
      CRP,共同重用原则,一个包中的所有类应该是共同重用的。 

      3  .包之间的耦合性原则 
       ADP,无环依赖原则,在包的依赖关系图中不允许存在环。 
      SDP,稳定依赖原则,朝着稳定的方向进行依赖。 
      SAP,稳定抽象原则,包的抽象程度应该和其稳定程度一致。
posted @ 2007-04-30 13:47 牛宝雷 阅读(235) | 评论 (0) | 编辑 收藏
 
java jxl导出excel文件

前两天公司的同事用java jxl写了一段导出excel的代码,值得学习,现提供代码如下:(导出一个list,要作到iterator)
首先导出jxl.jar,然后方法如下:
/**
  * @param mapping
  * @param form
  * @param request
  * @param response
  * @return ActionForward 得到输入的起始客户代码和结束客户代码,查询结算清单,返回结果
  */
 public void doExportAsXLS(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response) {
  String userCodeBegin = request.getParameter("uCodeBegin");
  String userCodeEnd = request.getParameter("uCodeEnd");
  log.info("userCodeBegin " + userCodeBegin.toString());
  log.info("userCodeEnd " + userCodeEnd.toString());
  if (userCodeBegin == null || userCodeBegin.equals("")) {
   userCodeBegin = userCodeEnd;
  }
  if (userCodeEnd == null || userCodeEnd.equals("")) {
   userCodeEnd = userCodeBegin;
  }
  List balanceList = settleService.getSettleBill(userCodeBegin,
    userCodeEnd);

  OutputStream os = null;
  WritableWorkbook wwb = null;
  Date date = new Date();
  Format format = new SimpleDateFormat("yyyyMMdd");
  String strDate = format.format(date);
  try {

   os = new FileOutputStream(strDate + "settle.xls");
   wwb = Workbook.createWorkbook(os);
   Iterator it = balanceList.iterator();
            doConfigExcel(it, wwb);
  } catch (Exception e) {

  } finally {
   try {
    wwb.write();
    wwb.close();
    os.close();
   } catch (Exception e) {
    e.printStackTrace();
   }

  }

  response.setHeader("Content-disposition", "attachment;filename="
    + strDate + "settle.xls\"");
  response.setContentType("application/msexcel");
  try {
   FileInputStream fileInputStream = new FileInputStream(strDate
     + "settle.xls");
   OutputStream out = response.getOutputStream();
   int i = 0;
   while ((i = fileInputStream.read()) != -1) {
    out.write(i);
   }
   fileInputStream.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }

 }

private void doConfigExcel(Iterator it, WritableWorkbook wwb) {
  
  
  try {
   
   
   while (it.hasNext()) {
    Label lchild;
    SettleVo sv = (SettleVo) it.next();
    String userCode = sv.getUserCode();
    int i = 2;
    int j = 0;
    WritableFont wf = new WritableFont(WritableFont.TIMES, 18, WritableFont.BOLD, true);
    WritableCellFormat wcfF = new WritableCellFormat(wf);
    
    WritableSheet ws = wwb.createSheet(userCode, 0);
    Label labelMain = new Label(4, 0, "中国玉米淀粉网 -- 客户结算清单",wcfF);
    
    Label labelMain1 = new Label(4, 1, "客户结算清单",wcfF);
    ws.addCell(labelMain);
    ws.addCell(labelMain1);
    lchild = new Label(0, 2, "客户代码");

    
    ws.addCell(lchild);

    lchild = new Label(0, 3, userCode);
    ws.addCell(lchild);

    String code = sv.getCode();
    lchild = new Label(2, 2, "摊位代码");
    ws.addCell(lchild);
    lchild = new Label(2, 3, code);
    ws.addCell(lchild);

    String fdate = sv.getFormatDate();
    lchild = new Label(4, 2, "日期");
    ws.addCell(lchild);
    lchild = new Label(4, 3, fdate);
    ws.addCell(lchild);

    lchild = new Label(4, 4, "当日成交清单",wcfF);
    ws.addCell(lchild);

    Iterator its = sv.getOrders().iterator();
    lchild = new Label(0, 5, "序 号");
    ws.addCell(lchild);
    lchild = new Label(2, 5, "交货时间");
    ws.addCell(lchild);
    lchild = new Label(4, 5, "市 场");
    ws.addCell(lchild);
    lchild = new Label(6, 5, "合约名称");
    ws.addCell(lchild);
    lchild = new Label(8, 5, "成交时间");
    ws.addCell(lchild);
    lchild = new Label(10, 5, "上网时间");
    ws.addCell(lchild);
    lchild = new Label(12, 5, "价 格");
    ws.addCell(lchild);
    lchild = new Label(14, 5, "数 量");
    ws.addCell(lchild);
    lchild = new Label(16, 5, "类 型");
    ws.addCell(lchild);
    int ii = 6;
    
    BigDecimal totalDealprice = new BigDecimal(0);
    Long totalAmount = new Long(0);
    while (its.hasNext()) {
     ii ++;
     TSpotOrder order = (TSpotOrder) its.next();

     String ordercode = order.getOrderCode();
     lchild = new Label(0, ii, ordercode);
     ws.addCell(lchild);

     String tradeTime = order.getLastTradeTime().toString();
     lchild = new Label(2, ii, tradeTime);
     ws.addCell(lchild);

     String exchange = order.getExchange();
     lchild = new Label(4, ii, exchange);
     ws.addCell(lchild);

     String stockname = order.getFuturesStockBase()
       .getStockName();
     lchild = new Label(6, ii, stockname);
     ws.addCell(lchild);

     String dealtime = order.getForMateDealTime();
     lchild = new Label(8, ii, dealtime);
     ws.addCell(lchild);


     lchild = new Label(10, ii, "-");
     ws.addCell(lchild);

     String dealprice = order.getDealPrice().toString();

     lchild = new Label(12, ii, dealprice);
     ws.addCell(lchild);
                   
     totalDealprice = totalDealprice.add(order.getDealPrice());
     
     String amount = String.valueOf(order.getAmount());

     lchild = new Label(14, ii, amount);
     ws.addCell(lchild);
                    
     totalAmount = totalAmount + order.getAmount();
     
     String buy = order.getBuyFormat();

     lchild = new Label(16, ii, buy);
     ws.addCell(lchild);

    }
    lchild = new Label(0, ii + 1, "合计");
    ws.addCell(lchild);
    lchild = new Label(12, ii + 1, totalDealprice.toString());
    ws.addCell(lchild);
    lchild = new Label(14, ii + 1, totalAmount.toString());
    ws.addCell(lchild);
    
    
    int jj = ii + 3;
                int jjj = jj + 2;
    lchild = new Label(4, ii + 2, "订货表",wcfF);
    ws.addCell(lchild);

    lchild = new Label(0, jj, "交货月份");
    ws.addCell(lchild);
    lchild = new Label(2, jj, "市 场");
    ws.addCell(lchild);
    lchild = new Label(4, jj, "合约名称");
    ws.addCell(lchild);
    lchild = new Label(6, jj, "买 / 卖");
    ws.addCell(lchild);
    lchild = new Label(8, jj, "平均价格 ");
    ws.addCell(lchild);
    lchild = new Label(10, jj, "数 量");
    ws.addCell(lchild);
    lchild = new Label(12, jj, "保证金");
    ws.addCell(lchild);
    lchild = new Label(14, jj, "浮 亏");
    ws.addCell(lchild);
    
    BigDecimal totalAvgprice = new BigDecimal(0);
    Long totalAvgamount = new Long(0);
    BigDecimal totalDeposit = new BigDecimal(0);
    BigDecimal totalProloss = new BigDecimal(0);
    
    Iterator _its = sv.getHolds().iterator();
    while (its.hasNext()) {
     jjj ++ ;
     HoldVo4settle hold = (HoldVo4settle) _its.next();

     String month = hold.getDeliverMonth();
     lchild = new Label(0, jjj, month);
     ws.addCell(lchild);

     String market = hold.getMarket();
     lchild = new Label(2, jjj, market);
     ws.addCell(lchild);

     String ordername = hold.getOrderName();
     lchild = new Label(4, jjj, ordername);
     ws.addCell(lchild);

     String buyformat = hold.getBuyFormat();
     lchild = new Label(6, jjj, buyformat);
     ws.addCell(lchild);

     String avgprice = hold.getPrice().toString();
     lchild = new Label(8, jjj, avgprice);
     ws.addCell(lchild);
                   
     totalAvgprice = totalAvgprice.add(hold.getPrice());
     
     String avgamount = hold.getAmount().toString();
     lchild = new Label(10, jjj, avgamount);
     ws.addCell(lchild);
 
     totalAvgamount = totalAvgamount + hold.getAmount();
     
     String deposit = hold.getDeposit().toString();
     lchild = new Label(12, jjj, deposit);
     ws.addCell(lchild);
     
     totalDeposit = totalDeposit.add(hold.getDeposit());

     String proloss = hold.getPro_loss().toString();
     lchild = new Label(14, jjj, proloss);
     ws.addCell(lchild);
     
     totalProloss = totalProloss.add(hold.getPro_loss());

    }

    lchild = new Label(0, jjj , "合计");
    ws.addCell(lchild);
    
    lchild = new Label(8, jjj, totalAvgprice.toString());
    ws.addCell(lchild);
    
    lchild = new Label(10, jjj, totalAvgamount.toString());
    ws.addCell(lchild);
    
    lchild = new Label(12, jjj, totalDeposit.toString());
    ws.addCell(lchild);
    
    lchild = new Label(14, jjj, totalProloss.toString());
    ws.addCell(lchild);
    
    
    lchild = new Label(4, jjj + 2, "资金结算表",wcfF);
    ws.addCell(lchild);
               
    BigDecimal capital = sv.getAddCapital();
    lchild = new Label(0, jjj + 3, "+ 当日存入");
    ws.addCell(lchild);
    lchild = new Label(6, jjj + 3, "- 当日支出 ");
    ws.addCell(lchild);
    lchild = new Label(0, jjj + 4, "+ 当日交易盈亏");
    ws.addCell(lchild);
    lchild = new Label(6, jjj + 4, "- 交易手续费 ");
    ws.addCell(lchild);
    
    if(capital != null){
     lchild = new Label(2, jjj + 3, capital.toString());
     ws.addCell(lchild);
    }
    

    BigDecimal redcapital = sv.getReduceCapital();
    if(redcapital != null){
     lchild = new Label(8, jjj + 3, redcapital.toString());
     ws.addCell(lchild);
    }
    

    BigDecimal pro_loss = sv.getPro_loss();
    if(pro_loss != null){
     lchild = new Label(2, jjj + 4, pro_loss.toString());
     ws.addCell(lchild);

    }
    
    BigDecimal fee = sv.getFee();
    if(fee != null){
     lchild = new Label(8, jjj + 4, fee.toString());
     ws.addCell(lchild);
    }
    
               
   }
  } catch (RowsExceededException e) {

   e.printStackTrace();
  } catch (WriteException e) {
   e.printStackTrace();
  }
 }

posted @ 2007-04-26 11:03 牛宝雷 阅读(8526) | 评论 (1) | 编辑 收藏
 
开源面向对象数据库 db4o 之旅

         一天一个新技术.今天网友介绍了db4o,据说是mysql+hibernate的44倍!人都是很感性的动物,不能性能如何,先学习一下吧,总归没有什么坏处.
         因为是刚刚学习,根本没有任何的经验可言.下面是学习的几个文档,先学习下.同时作为资料保存在这里.
      开源面向对象数据库 db4o 之旅,
      第 1 部分:
初识 db4o:http://www.ibm.com/developerworks/cn/java/j-lo-db4o1/index.html
      第 2 部分: db4o 查询方式:http://www.ibm.com/developerworks/cn/java/j-lo-db4o2/index.html
      第 3 部分: 深入db4o:   http://www.ibm.com/developerworks/cn/java/j-lo-db4o3/index.html

      其它参考资料在http://www.ibm.com/developerworks/cn/java/j-db4o/中的下文可以看到,比如:db4o 官方网站 db4o 开发者论坛 db4o 中国开发者论坛 等,以后在学习过程中,会把相关的学习体会写到下面,也请众多网友共同学习和交流
posted @ 2007-04-24 14:05 牛宝雷 阅读(215) | 评论 (0) | 编辑 收藏
 
iframe边界移动问题
iframe是对窗口分区的一个控件,详细情况请上网搜索一下,我这里描述一下分区后的边界移动问题.
为了使分区后边界不能移动,请加入noresize="noresize",如下面代码所示.否则可以去掉.呵呵 ,有些废话了.这段时间比较郁闷,没想到我还要去做美工,这可是美工的工作呀!!
郁闷ing..................

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
 String path = request.getContextPath();
%>   
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>管理员控制台</title>
</head>
<FRAMESET cols="160,*" frameborder=0 name="mainFrame">
 <FRAME SRC="<%=path%>/admin/adminMenu.do" NAME="menu" noresize="noresize">
 <FRAME SRC="<%=path%>/admin/userManagement.do?method=initPage" NAME="content" noresize="noresize">
</FRAMESET>
<noframes>
 <body>
  你的浏览器不支持frame结构,请用支持frame的浏览器使用此系统!
 </body>
</noframes>
</html>
posted @ 2007-04-20 17:13 牛宝雷 阅读(1254) | 评论 (0) | 编辑 收藏
 
使用eclipse生成文档(javadoc)
使用eclipse生成文档(javadoc)主要有三种方法:
1,在项目列表中按右键,选择Export(导出),然后在Export(导出)对话框中选择java下的javadoc,提交到下一步。
在Javadoc Generation对话框中有两个地方要注意的:
javadoc command:应该选择jdk的bin/javadoc.exe
destination:为生成文档的保存路径,可自由选择。
按finish(完成)提交即可开始生成文档。
2,用菜单选择:File->Export(文件->导出),
剩下的步骤和第一种方法是一样的。
3,选中要生成文档的项目,然后用菜单选择,
Project->Generate Javadoc直接进入Javadoc Generation对话框,剩余的步骤就和第一种方法在Javadoc Generation对话框开始是一样的。
posted @ 2007-04-18 17:15 牛宝雷 阅读(198) | 评论 (0) | 编辑 收藏
 
springside开发过程

前段时间一直在学习springside,今天想做一些例子,发现又忘记了很多,呵呵,没有办法,只好再从网上找学习资料了.现将学习资料放到这里,供以后学习使用方便,也方便一下大家,可以一次性找到很多供学习的东西.
1.http://www.blogjava.net/youxia/archive/2006/12/21/89365.html SpringSide开发实战(一):使用Eclipse让SpringSide跑起来
2.http://www.blogjava.net/youxia/archive/2006/12/23/89692.html SpringSide开发实战(二):修改数据库、字符编码和快速部署应用程序
3.http://www.blogjava.net/youxia/archive/2006/12/26/90112.html SpringSide开发实战(三):漫谈CSS和页面布局
4.http://www.blogjava.net/youxia/archive/2007/01/05/91994.html SpringSide开发实战(四):打通数据持久层的任督二脉
5.http://www.blogjava.net/youxia/archive/2007/01/11/93277.html SpringSide开发实战(五):兵马未动,粮草先行

6.http://www.blogjava.net/youxia/archive/2007/03/09/101320.html SpringSide开发实战(六):AJAX,在地狱中漫步
7.http://www.blogjava.net/youxia/archive/2007/03/15/104077.html SpringSide开发实战(七):在项目中整合FCKeditor
 8.http://www.blogjava.net/youxia/archive/2007/03/28/107083.html SpringSide开发实战(八):不是结局的结局,谈谈程序员的境界
这几篇资料从浅入深吧,有基础,也有扩展.让初学者学习的时候,有一个慢慢的过程.很是受用.
最后,应该对海边沫沫说声感谢.
posted @ 2007-04-16 15:55 牛宝雷 阅读(204) | 评论 (0) | 编辑 收藏
 
相关工作流-什么是工作流引擎(Workflow Engine )

所谓工作流引擎是指workflow作为应用系统的一部分,并为之提供对各应用系统有决定作用的根据角色、分工和条件的不同决定信息传递路由、内容等级等核心解决方案。例如开发一个系统最关键的部分不是系统的界面,也不是和数据库之间的信息交换,而是如何根据业务逻辑开发出符合实际需要的程序逻辑并确保其稳定性、易维护性(模块化和结构化)和弹性(容易根据实际业务逻辑的变化作出程序上的变动,例如决策权的改变、组织结构的变动和由于业务方向的变化产生的全新业务逻辑等等)。 Workflow 引擎解决的就是这个问题:如果应用程序缺乏强大的逻辑层,势必变得容易出错(信息的路由错误、死循环等等)。

就好比一辆汽车,外表做得再漂亮,如果发动机有问题就只是一个摆设。应用系统的弹性就好比引擎转速方面的性能,加速到100 公里需要1 个小时(业务流程发生变动需要进行半年的程序修改)还能叫好车吗?引擎动不动就熄火(程序因为逻辑的问题陷入死循环)的车还敢开吗?

工作流解决方案与传统管理软件的关系传统的管理软件注重解决企业应用层现存的问题(例如提高企业的资源配置率或提高单一员工的生产效率)。例如:EXCEL 可以提高员工画表格的效率、财务软件可以规范财务人员的工作并提高帐目查询的效率、CRM 可以规范客户管理从而使客户资源掌握在公司手中而不是被一部分业务人员把持并提高客户响应时间、ERP 解决的是如何配置企业资源:使企业的人力资源、财力资源和物资资源能够根据业务的需求实现最大化配置。 workflow 关注的是如何缩短流程闲置时间,从而提高企业的业务处理能力并使企业能够关注于真正对企业有意义的增值业务上。从建立企业神经系统的角度也许更能理解两者的区别。传统软件不能解决工作流的问题,例如ERP 关注的是企业的资源配置,但不可能解决资源传输过程中的损耗和降低传输(流程)的成本;同样workflow也不能完全解决传统管理软件所能解决的问题,例如对生产管理的MRP 系统所能解决的生产过程控制通过workflow很难实现。但一个好的传统软件如果希望能自动化地在整个企业中应用起来,必须有一个强大的逻辑层,用以解决信息传递的逻辑判断和自动流转,这个时候就需要workflow的平台。所以说: 1.workflow 和传统管理软件不是同一种软件,不具可比性; 2.workflow 对于已经有传统管理软件的企业的作用非常明显,可以籍此平台整合企业的各种应用系统,使之成为一个完整的企业级应用,也就是通常所说的EAI. 3. 具备workflow功能的管理软件(workflow与传统管理软件的结合)对于传统管理软件有绝对的优势;4.workflow可以根据企业的需要开发解决信息传递问题的流程以及帮助企业开发与现有应用系统的接口

工作流自动化并不复杂因为下述几个原因,工作流自动化业界有" 适合处理复杂业务流程" 的名声。

1.常规工作流自动化软件包及其部署相当昂贵。通常,伴随产品的是长时期的咨询关系。所以为了非常简单的业务流程购买和部署软件是被不被采纳的。这些软件通常只被用于复杂、关键和控制成本相对较高而工作流自动化带来的效益明显的量产型工作流应用。因此经销商和用户都会不自觉地关注于将复杂的业务问题自动化。 2. 处于类似原因,工作流研究人士首先会关注解决了哪些复杂的业务流程问题。

而对于大多数案例而言,为解决简单工作流程问题部署自动化软件的成本显然是不经济的。这里遵循一条简单的道理:走之前必须先会爬,跑之前必须先会走。 3. 最后一条原因,也是"IT 业的尴尬".总经理对IT部门经理工作衡量的标准就是:能够解决复杂问题的能力。自然,IT经理就会不遗余力地解决那些复杂的问题,他们的方案通常也就复杂而且昂贵。

所有这些目前都在改变。针对桌面电脑的应用方案快速发展以及工作流解决方案的发展使解决日常工作流程问题成为可能。费用不再昂贵,部署更为简便。事实上,企业越来越意识到工作流的重要性,同时在部署复杂关键的流程自动化之前,愿意从一些简单的流程入手积累经验。

工作流会成为操作系统的一部分吗?

有人认为工作流会成为操作系统平台(例如WINDOWS 平台)的一部分。我们的观点是,基于下述几个原因,在可预见的未来,工作流不会成为操作系统的一部分: 1. 扩展表格、文字处理程序和数据库存在了20多年,成了家喻户晓的名词。这些技术被广泛理解和应用,也相应形成了各自的标准和相关术语。然而因为很多原因,直到今天这些技术也没有成为操作系统的一部分。最重要的原因之一是用户需要差异和选择的自由。相比较而言,工作流自动化软件是较新的技术,也更有差异性、不易被广泛理解并且比这些技术更为先进。因为工作流程的差异性和复杂性,工作流自动化的用户需要更多的选择空间。

2.财务软件包从电脑发明后就迅速普及了。这是实施、术语和规则被普遍接受的另一个领域。然而至今也没有哪种操作系统吹嘘集成了多少财务软件的功能。而工作流自动化软件比财务软件更为复杂和有差异性。 3. 操作系统提供商,例如微软和Sun ,不会为了使其系统具备工作流自动化的功能而大量改变他们现有的系统。他们有什么必要为工作流自动化软件投入开发和支持的成本呢? 4. 操作系统是为常规条件设计并使之最优化。正因如此,目前操作系统的开发成本几乎都要上亿美元。业务流程十分复杂并充满了例外情况,如在操作系统中内嵌工作流自动化程序会极大地增加开发成本和难度。因此,即便操作系统提供商决定做工作流软件,也会是巨额投入开发一套新的操作系统,而不是将工作流嵌入。

事实上,今天的很多优秀的工作流解决方案集成了短信息、页面服务、目标管理、文件管理和其他一些操作系统才提供的服务。

工作流自动化的主要成分工作流自动化如今成了管理的一句时髦话。市面上也有很多号称能激活工作流的自动化产品。只要他们的应用程序支持基本的E-mail功能,卖主就会随意地把" 激活工作流" 作为标签贴在产品上。然而,这类产品和真正工作流自动化软件之间的差别就如同写字版和Word之间的差别。我们相信,应用程序只有具备了下列主要特征,才能称其为工作流自动化解决方案:

能够画出工作流程图,当然以图形化界面设计的为佳;能为每个步骤设计电子表格;能将外部应用程序结合为工作流自动化的一部分;能与电子表格及企业数据库相连接;能设计基于复杂业务规则的条件型路由的工作流程图,最好无须编程;能根据功能、用户名称或上下级关系按规则传递信息;能够监控工作流执行状况;能够对工作流进行调节;能够模拟并测试工作流的行为;工作流的应用必须支持多用户并具高度可靠性;工作流的应用必须支持内部网或英特网及跨多种平台。

网友讨论工作流应该是一个中间件而不应该是一个完整的系统。工作流应该整合到其他系统中而不是单独使用。

工作流要完成的核心功能有流程设计,流程执行,流程和线程的调度,任务的分派与通知,集成已有信息系统(很多人忘了)。

工作流应该提供对组织机构,用户,权限管理,流程,任务的管理能力,但是对这些管理能力最基本实现方式是提供API ,而不是一个管理系统,即使把这些管理作为一个管理系统来实现(A ),也主要是用于演示,因为当工作流用于其它系统(B ),因为B 需要一个统一的管理界面,所以通常不会直接使用A.而表单设计,报表之类根本就是外围功能,是二次开发商的任务。

我基本赞同wangtaoyy 的说法,再补充一点。我觉得工作流与其说是中间件,还不如说是一个应用整合和集成的框架。类似在j2ee规范下各产商开发的应用服务器,工作流也应当是在wfmc标准下开发出来的" 容器" ,只要是满足了标准的应用程序或组件都能够在这个" 容器" 中按照预定的规则被调度和执行。我认为理想情况下工作流系统不应该提供API 作二次开发,工作流的内部对基于工作流的应用程序应当是完全不透明的,工作流应当提供给开发者的是一个类似于J2EE那样的标准,一套编程模型和接口模型。开发者在这个模型下去实现那些接口,开发出应用组件,再利用工作流提供的管理器进行" 注册".总而言之,对开发者而言,工作流是黑箱,他需要做的事情是开发标准组件,在工作流提供的UI管理工具中配置业务流程,包括业务过程、资源、权限、时间、规则等等。

1. j2ee 应用服务器也是中间件的一种。
2. 工作流要做成j2ee哪样的标准还是比较困难的, j2ee 重点在于提供开发全新系统的能力,所以可以制定比较好的容器- 组件标准,而工作流的重点是整合已经存在的系统,要在这些各式各样的老系统上强加标准是不现实的。
3.工作流应该提供api ,因为其他系统中的一些事件可能会启动一个流程,或者触发其他与流程相关的东西

工作流分为两种类型,一种是嵌入式的,另一种是非嵌入式的。这在WFMC的文档中已经有所介绍,大家可以找找看一下。按照工作流管理联盟的文档,大家说的都没有什么错误,只是侧重点不同。wangtaoyy 的观点倾向于前者,而coffeewoo 的观点倾向于后者。

我的看法并不是趋向于嵌入式工作流。我理解的工作流提供的api 并不是一般软件包的API ,而是一种服务方式的API ,类似于操作系统中的系统调用。

我们在软件中大量使用了操作系统提供的系统调用API ,但是操作系统并不是嵌入到我们软件系统中的。我认为工作流系统与操作系统有很强的可比性,只是工作流层次更高。比如流程设计相当于编程,模型相当于程序,流程实例相当于进程,流程分支相当于线程,操作系统要对进程和线程进行调度,工作流引擎要对流程实例和分支进行调度,操作系统和工作流系统都应该对内存进行管理避免耗尽系统内存,操作系统提供系统调用API 而工作流引擎提供工作流API.何其相似。

从功能的角度看:工作流系统的本职工作就是管理和控制业务流程,例如:流程实例的启动、停止;环节实例的启动、结束;任务的分配等等。从工作流系统的组成看:工作流系统应该包括流程引擎、流程定义工具、运行管理工具、api 系统。工作流系统应该该不包括表单定义、组织机构定义及其管理、权限管理、数据流管理等等。

工作流系统虽然不包括上述功能,但是工作流系统一定会和上述功能发生交互关系,所以好的工作流产品并不是一个包办上述功能的产品,而是一个设计良好的能够和上述功能交互的系统。从和其他系统的关系看待工作流:如果站在基础业务平台的角度,那么,工作流系统、组织机构管理系统、表单自定义系统、权限管理系统、数据流管理系统、报表系统都是这个基础业务平台的服务。业务功能系统在运行的过程中会调用这些服务,这些服务之间本身也可能互相调用。例如:工作流服务和组织机构管理服务之间的关系就非常密切,尽管如此,如果认为工作流系统一定包含组织机构管理系统应该是不正确的。在oa系统中,表单自定义好像比较重要,而且流程常常需要引用表单上的数据,但是表单自定义绝对不是工作流系统的组成部分。流程在运行的过程中可能跨多个数据库系统,任务在流转的过程中需要“携带”大量的业务数据,但是这些也不是工作流要做的事情,完成这些工作的系统我称之为“数据流管理系统”。总之:从功能的角度,所有的功能都是必要的,但是从技术的角度,这些功能不可以做到一个“铁板一块”的所谓的“工作流”里面去。从技术发展的趋势看:工作流系统很可能发展成为一个类似关系型数据库管理系统的专职的系统。我那个工作流东东还在改进中,希望作出一个设计合理的(决对不是强行coding出来的),工程实用的东西出来。

posted @ 2007-03-26 10:57 牛宝雷 阅读(1310) | 评论 (3) | 编辑 收藏
 
据说这是外企面试官最爱提的10个问题(附答案)
既然是BLOG嘛,我想杂一些,多些生活和工作也就无所谓了。做为一个技术BLOG,我还是想找个空间,记录一下别的东西,让我有感触和感兴趣的东西。不是为了给网上的朋友们看,而是做为一个收藏吧。
下面是这10个问题的详细信息:
         1.请介绍一下你自己。

  这是外企常问的问题。一般人回答这个问题过于平常,只说姓名、年龄、爱好、工作经验,这些在简历上都有,其实,外企最希望知道的是求职者能否胜任工作,包括:最强的技能、最深入研究的知识领域、个性中最积极的部分、做过的最成功的事,主要的成就等,这些都可以和学习无关,也可以和学习有关,但要突出积极的个性和做事的能力,说得合情合理外企才会相信。外企很重视一个人的礼貌,求职者要尊重考官,在回答每个问题之后都说一句“谢谢”。外企喜欢有礼貌的求职者。

  2.在学校你最不喜欢的课程是什么?为什么?

  这个问题外企不希望求职者直接回答“数学”、“体育”之类的具体课程,如果直接回答还说明了理由,不仅代表求职者对这个学科不感兴趣,可能还代表将来也会对要完成的某些工作没有兴趣。这个问题外企招聘者最想从求职者口里听到:我可能对个别科目不是特别感兴趣,但是正因为这样,我会花更多的时间去学习这门课程,通过学习对原本不感兴趣的科目也开始有了兴趣,对于本来就有兴趣的科目我自然学习得更认真,所以各门课的成绩较为平衡。通过这样的问题,外企可以找到对任何事情都很感兴趣的求职者。

  3.说说你最大的优缺点?

  这个问题外企问的概率很大,通常不希望听到直接回答的缺点是什么等,如果求职者说自己小心眼、爱忌妒人、非常懒、脾气大、工作效率低,外企肯定不会录用你。外企喜欢求职者从自己的优点说起,中间加一些小缺点,最后再把问题转回到优点上,突出优点的部分。外企喜欢聪明的求职者。

  4.你认为你在学校属于好学生吗?

  外企的招聘者很精明,问这个问题可以试探出很多问题:如果求职者学习成绩好,就会说:“是的,我的成绩很好,所有的成绩都很优异。当然,判断一个学生是不是好学生有很多标准,在学校期间我认为成绩是重要的,其他方面包括思想道德、实践经验、团队精神、沟通能力也都是很重要的,我在这些方面也做得很好,应该说我是一个全面发展的学生。”如果求职者成绩不尽理想,便会说:“我认为是不是一个好学生的标准是多元化的,我的学习成绩还可以,在其他方面我的表现也很突出,比如我去很多地方实习过,我很喜欢在快节奏和压力下工作,我在学生会组织过××活动,锻炼了我的团队合作精神和组织能力。” 有经验的招聘者一听就会明白,外企喜欢诚实的求职者。

  5.说说你的家庭。

  外企面试时询问家庭问题不是非要知道求职者家庭的情况,探究隐私,外企不喜欢探究个人隐私,而是要了解家庭背景对求职者的塑造和影响。外企希望听到的重点也在于家庭对求职者的积极影响。外企最喜欢听到的是:我很爱我的家庭!我的家庭一向很和睦,虽然我的父亲和母亲都是普通人,但是从小,我就看到我父亲起早贪黑,每天工作特别勤劳,他的行动无形中培养了我认真负责的态度和勤劳的精神。我母亲为人善良,对人热情,特别乐于助人,所以在单位人缘很好,她的一言一行也一直在教导我做人的道理。外企相信,和睦的家庭关系对一个人的成长有潜移默化的影响。

  6.说说你对行业、技术发展趋势的看法?

  外企对这个问题很感兴趣,只有有备而来的求职者能够过关。求职者可以直接在网上查找对你所申请的行业部门的信息,只有深入了解才能产生独特的见解。外企认为最聪明的求职者是对所面试的公司预先了解很多,包括公司各个部门,发展情况,在面试回答问题的时候可以提到所了解的情况,外企欢迎进入企业的人是“知己”,而不是“盲人”。

  7.就你申请的这个职位,你认为你还欠缺什么?

  外企喜欢问求职者弱点,但精明的求职者一般不直接回答。他们希望看到这样的求职者:继续重复自己的优势,然后说:“对于这个职位和我的能力来说,我相信自己是可以胜任的,只是缺乏经验,这个问题我想我可以进入公司以后以最短的时间来解决,我的学习能力很强,我相信可以很快融入公司的企业文化,进入工作状态。”外企喜欢能够巧妙地躲过难题的求职者。

  8.你期望的工资是多少?

  外企的工资水平是很灵活的,何种能力拿何种工资。外企喜欢直率的人,但这个问题却不能正面回答,外企希望听到:“以我的能力和我的优势,我完全可以胜任这个职位,我相信我可以做得很好。但是贵公司对这个职位的描述不是很具体,我想还可以延后再讨论”。外企欢迎求职者给其定薪的自由度,而不是咬准一个价码。

  9.你能给公司带来什么?

  外企很想知道未来的员工能为企业做什么,求职者应再次重复自己的优势,然后说:“就我的能力,我可以做一个优秀的员工在组织中发挥能力,给组织带来高效率和更多的收益”。外企喜欢求职者就申请的职位表明自己的能力,比如申请营销之类的职位,可以说:“我可以开发大量的新客户,同时,对老客户做更全面周到的服务,开发老客户的新需求和消费。”等等。

  10.你还有什么问题吗?

  外企的这个问题看上去可有可无,其实很关键,外企不喜欢说“没有问题”的人,因为其很注重员工的个性和创新能力。外企不喜欢求职者问个人福利之类的问题,如果有人这样问:贵公司对新入公司的员工有没有什么培训项目,我可以参加吗?或者说贵公司的晋升机制是什么样的?外企将很欢迎,因为体现出你对学习的热情和对公司的忠诚度以及你的上进心。
posted @ 2007-03-15 10:50 牛宝雷 阅读(358) | 评论 (1) | 编辑 收藏
 
开博了,原来我也是一俗人

      我终于没有耐的住寂寞。我是一个不爱追求时尚的人,当很多人都在追求一个东西时,我的态度就是旁观,就像是追星一样,既然我不认识他,他也不认识我,为什么我要认为他是我的偶像呢?所以我不追星。
      哈哈,有点远了!在BLOG满天飞的今天,我就认为:我不会写这个东西的,每个人都有自己的一点隐私,而且每个人都有自己的难处,一个虚拟的网络不会帮你解决任何问题。但现在有点不同了,我做的是IT,做的是研发,在我学习的过程中,没少在网上学习大虾们的大作,受了不少恩惠。所以,我想,也做一个技术的BLOG吧,当做是为人为己的一件好事,也为我提供了一个与大虾们共同学习交流的平台,同时也可以记录我在工作中的点点滴滴。
       就这样吧,我再呼喊两声:开博了!开博了!欢迎名位大虾们来此指导,共同学习交流。哈哈

posted @ 2007-03-14 16:41 牛宝雷 阅读(258) | 评论 (2) | 编辑 收藏
 
仅列出标题
共3页: 上一页 1 2 3 
 
<2025年7月>
日一二三四五六
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

 导航

  • BlogJava
  • 首页
  • 发新随笔
  • 发新文章
  • 联系
  • 聚合
  • 管理

 统计

  • 随笔: 30
  • 文章: 6
  • 评论: 50
  • 引用: 0

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论

留言簿(4)

  • 给我留言
  • 查看公开留言
  • 查看私人留言

随笔档案

  • 2008年2月 (1)
  • 2007年12月 (1)
  • 2007年11月 (1)
  • 2007年9月 (3)
  • 2007年7月 (2)
  • 2007年6月 (3)
  • 2007年5月 (8)
  • 2007年4月 (7)
  • 2007年3月 (4)

文章档案

  • 2007年7月 (1)
  • 2007年3月 (5)

搜索

  •  

最新评论

  • 1. re: spring AOP的事务管理[未登录]
  • dsasd
  • --dd
  • 2. re: Eclipse 中CheckStyle安装和使用指南
  • 07年的中企员工啊,前辈~
  • --xiao瓶盖1121
  • 3. re: tomcat 和 jboss的热部署(热发布)问题
  • @songguanjun
    确实不可用
  • --lin
  • 4. re: java.lang.String中,match()的用法,即String.match(String pattern)[未登录]
  • 评论内容较长,点击标题查看
  • --匿名
  • 5. re: Eclipse 中CheckStyle安装和使用指南
  • 我们可以利用CheckStyle可以方便的对于编码的Code Conventions进行检查,同时,也有效地减少了Code Review的工作,使得开发人员的精力更多的集中到逻辑和性能检查。
  • --gucci outlet

阅读排行榜

  • 1. java.lang.String中,match()的用法,即String.match(String pattern)(27579)
  • 2. JAVA 处理时间 - java.sql.Date、java.util.Date与数据库中的Date字段的转换方法[转](20533)
  • 3. Eclipse 中CheckStyle安装和使用指南(8561)
  • 4. java jxl导出excel文件(8526)
  • 5. 存储过程生成临时表用从临时表中取数据(5352)

评论排行榜

  • 1. hibernate自定义生成主健(8)
  • 2. java.lang.String中,match()的用法,即String.match(String pattern)(7)
  • 3. 存储过程生成临时表用从临时表中取数据(4)
  • 4. [DWR(Ajax)]DWR使用笔记(4)
  • 5. eclipse的远程调试(jboss+tomcat),已成功(3)

Powered by: 博客园
模板提供:沪江博客
Copyright ©2025 牛宝雷