前面两锤后,得到很多朋友的鼓励,并希望继续深入探讨2BizBox这款免费ERP的开发方面的经验。这两天有空,就又写了一锤,欢迎大家拍砖。首先回顾前两锤大家关注的一些问题:
- ServletFacade总控制器每次收到请求通过反射区分发业务处理吗?是否性能问题?
没错,每次都反射,性能方面没啥问题。首先,这里的分发有两层,首先是对模块EJB的分发,这里会对EJB访问实例进行缓存,下次有invoke就直接拿出来用就行了;接下来会对业务层以及进一步对DAO一层的类进行反射创建实例并调用。因为DAO类非常简单专一,就是HQL的处理组织,创建时基本没有任何复杂业务,速度会很快。而且随着现代虚拟机和硬件配置的大幅提高,反射的效率影响很小,甚至可以忽略。用Sun官方的话说:There is some overhead with reflection, but it's a lot smaller on modern VMs than it used to be。而且,如果以后这个环节真的产生性能问题,可以再处理成缓存机制即可。当然缓存也会带来清理维护的麻烦以及内存消耗的成本。这块的设计必须要左右权衡,均衡就好。至今来说,2BizBox的ERP后台运行还是比较轻量高效的,大家可以试试看。当然如果规模大的商用,服务器还是要配置好一点,内存大一点更佳(现在内存老便宜了)。 - 这个构架中,最后用hibernate 与数据库连,遇到数据量大的时候能支持吗?
没问题,要相信Hibernate和JBoss的水平,呵呵。Hibernate是非常、非常、非常好而成熟的框架,相信大多数人都在用了很多年了。效率方面,用JavaEye老大Robbin的话说,它产生的SQL可能比在座大多数人写的SQL水平很可能会高好一点,效率不差。对于一些复杂的查询和SQL操作,可以穿插直接使用SQL和JDBC的方式来解决。我们这里也经常有创建临时表等复杂的操作,都很正常,Hibernate本身也鼓励如此。 - ERP主要是业务上的东西,你这个架构是在浪费时间。
没错,ERP其实最主要内容还是业务,铺天盖地的功能界面、模块、报表、无数的字段和数据…。但是任何软件系统的业务都是靠软件本身支撑起来的。如果造一座大楼,就必须打好地基;如果造或者,就必须先建好铁轨;如果建大桥,就必须先打好桥墩。否则只强调“航母主要是飞行甲板,你这个龙骨设计是浪费时间”,也是有失偏颇的。目前2BizBox ERP我们接触到的代码就已经将近200万行,如果没有一个好一点的架构和基础,肯定就乱套了。搞建筑咱不都想造一个埃菲尔铁塔百年经典作品么,咱做软件的也不能示弱啊。 - 这样的话还不如直接用RMI通讯。
用RMI确实是一个可行方案,其实我们的ERP以前采用过,不过后来换掉了,不是很推荐。RMI+IIOP曾经一度被Sun委以重任,却最终没流行起来,尤其在Web为王的今天。主要原因还是太复杂笨重。我们也曾经使用RMI+IIOP+EJB的方式来做前后台通讯,但是效率、稳定性、复杂度都很高,开发和部署都很麻烦,就一个异常传递处理就够弄一壶的。如果再要实现回调,还要在本地起一个服务server,部署麻烦。另外一个大问题是端口,它需要独立的端口(例如通常是1099),如果前台回调,还要客户端起Socket服务端口。如果考虑到后台的Web本身还要80端口,这势必要求防火墙开放更多端口,很多服务器和管理员都不愿如此,他们基本上只相信80,其他一概关闭。基于“效率低”、“使用部署麻烦”、“防火墙端口”等几个方面问题,2BizBox ERP还是使用了Java Serialization over HTTP的思路处理前后台通讯。这样,后台只需要开一个80端口就行了,和Web服务器一样,前台则和一个浏览器一样。当然,这样也没法实现Callback了,不过基本上无所谓,所有的Web应用不都是如此么。 - 对于 把ejb换成 80 直接访问,速度是快了,ejb容器很多用途现在都怎么完成的?比如事务完整性的控制?
首先,这个设计并非直接把ejb弄到80上去。2BizBox ERP是把EJB用在后台容器内部,而外部用Servlet+80的方式。其实JBoss真有类似“EJB over HTTP/HTTPS”的类似技术,感兴趣的朋友可以看看这里:http://docs.jboss.org/ejb3/docs/tutorial/http_https/http_https.html 不过没试验过,对其效率、复杂度、等安全性等方面不敢下结论。其次,ejb的所有特性(例如最重要的事务控制)都没有变化,该怎么用还是怎么用就行了。(这里插入2BizBox事务的启动和回滚代码)
- 问个题外话,这个打包的安装文件是用什么工具生成,能否说说使用方法?
安装文件是用Inno Setup这个开源工具做的,它支持多component、多语言,很简单方便,很推荐。Inno Setup发展十多年了,很稳定成熟,使用人很多,资料也不少,详细可以看这里:http://www.jrsoftware.org/isinfo.php - 我们现在也在用swing做开发,不过客户端部署方式上我们直接采用web start方式。
关于Java Web Start使用,忍不住想多说一些。我们以前也是使用Java Web Start来对客户端进行部署的。最主要觉得这个东西可以让客户端自动更新,比较省事。但是随着客户量增大、客户端复杂度越来越高、发现的Java Web Start的bug越来越多,我们最终放弃了Java Web Start,转而使用传统的安装文件的方式。对JWS技术,我的意见是:一定要慎用。JWS的思路很好,Sun也一直想把它做好,可惜人手不够,Swing都顾不上了,哪里有心思JWS,结果导致bug暴多。大家如果不信,可以看看JDK6的每个update有多少bug fixing是关于JWS的,简直不计其数。我们客户碰到的问题也是千奇百怪:下载速度特别慢的问题、update进度条不准(JWS的下载进度条就从来没准过)、快捷创建的问题、有时候死活不update的问题、不同语言的问题、需要同时存在不同版本客户端连接不同版本后台的问题、快捷键无法删除问题、不同浏览器问题、JNLP文件内容修改维护问题…等等等等,想起来简直是罄竹难书,经常被客户逼的要跳楼,你却毫无办法:因为你无法控制这些东西。最终我们选择彻底放弃JWS,用传统的setup方式反而更加方便直观。这里有我们同事整理的一些文章,感兴趣的朋友可以看看:http://sailing8036.spaces.live.com/blog/cns!69D05DFD4294F487!479.entry?wa=wsignin1.0&sa=728927372 - 现实告诉我们,即使做java的,还得分windows版和linux版。请教楼主一个问题,你们用ejb是什么道理?是做事务管理吗?
其实2BizBox前后台都可以在linux下面运行,不过要做到自动安装等比较麻烦,现在为了让大家都能免费方便的使用这款ERP,所以仅仅制作了windows的安装程序,方便下载、安装。2BizBox ERP的前后台都具有非常好的跨平台特性,后续发布版本可能会做到zip方式合二为一。用EJB,确实一个重要原因是事务控制。作为大型的ERP系统,数据的一致性和完整性是必须要严格控制的,事务控制也必不可少。由于EJB下层使用了大量的业务层并进一步调用DAO层进而操作数据库,这些方法必须在EJB层进行统一的事务管理。通过JTA的统一封装,可以做到原子化的成功和失败回滚,保证数据安全和完整性。大家都抨击EJB很烂,不过使用Local的无状态Bean+事务控制,还是很好的一个东西。 - 当时没考虑国际化? 这个东西免费太匪夷所思了。
国际化是必须的,Java有I18N这么好的框架,2BizBox怎能不用呐?我们是直接使用Java的PropertyResourceBundle,把所有的字符串都拉入properties文件,对不同语言文件进行维护。我们甚至内部开发了专用的多语言字符串翻译维护工具,减少工作量。目前v3新版本的汉化工作正在紧张有序进行,接近尾声,还需要测试和检验,请大家再耐心等待!关于这类大型管理软件的翻译、汉化和多语言支持还有很多话题和细节,如果大家感兴趣,我会专门写一篇介绍。另外这个ERP免费,确实很难以置信!让人鸡动!!不过免费是一种潮流和发展方向,不管认同不认同,掌声鲜花或口水谩骂,咱们其实都是受益者。QQ和360打架讨厌,但它们都是优秀的免费软件,给整个行业和国家做出了巨大的贡献,这一点是不能否认的。希望大家能支持和宣传2BizBox ERP软件,让全中国更多的企业可以从高质量的免费ERP软件中收益!
好了,总算可以进入正题了。今天的话题是软件界面要“好看”,更要“好用”,这两点很重要,缺一不可。好看不好看,或者好用不好用,都是比较抽象的概念,仁者见仁智者见智。但是,软件“以用为本”这一点我们都不否认。2BizBox项目在国内外很多人参与,语言不同、文化不同、习惯不同,连IDE工具都不同;要做到成千上万界面的美观一致和专业,需要做很多细致工作,开会、讨论、电话、邮件、skype…烦不胜烦。不过,说到底都是细活儿。其实做高质量软件的唯一秘密也就是 “细节”这仅此一点而已。
风格一致Same Style
2BizBox ERP中的界面成千上万不计其数,开发者众多,如何保证图形界面的布局风格一致?这需要有文档规定,还要开会、培训、测试、检查、评审等等。Windows是图形界面的鼻祖和大家,如下图,随便找一个Windows界面,仔细观察,你会有所收获:
- 界面边缘以及内部边距都很一致(一般都为5或10)。要体现在软件开发中也很简单。例如在使用Swing的FlowLayout进行布局,直接可以指定默认间距,避免不同开发者的设计风格出现差异:
1 public FlowLayout() {
2 this(CENTER, 5, 5);
3 }
4 public FlowLayout(int align) {
5 this(align, 5, 5);
6 }
- 对齐方式都很统一(左对齐)
- 通过带标题的Group对界面元素进行适当分组
此外,在2BizBox客户端开发中,对于所所有界面,都要遵循一些要求和惯例,这些要求有时候都很难用语言描述清楚,更多的是要靠开发者多思考和体会:
- 每个界面都有比较清晰的标题,尽量做到能够“见文生意”。
- 使用统一风格和尺寸的图标;所有界面有一致的颜色和尺寸风格;2BizBox ERP中的所有图标、颜色、字体等甚至都被统一封装到特别的类中,自己是不能随意使用各种颜色、字体、图标的,这样才能做到“风格一致”。
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 public static final Image BB2_FRAME_ICON = ClientUtil.getImage( " logoicon.gif " );
3 public static final Image COMPANY_NODE_ICON = ClientUtil.getImage( " company.png " );
4 public static final Icon CLOSED_STATUS_ICON = ClientUtil.getIcon( " closed_status.gif " );
5 public static final Icon RUN_ICON = ClientUtil.getIcon( " run.gif " );
6 public static final Icon STOP_ICON = ClientUtil.getIcon( " stop.png " );
7 public static final Icon ROOT_ICON = ClientUtil.getIcon( " root.png " );
8 public static final Icon CHART_ICON = ClientUtil.getIcon( " chart.png " );
9 public static final Icon REPLY_NOTICE_ICON = ClientUtil.getIcon( " notice_re.png " );
10 public static final Icon FORWARD_NOTICE_ICON = ClientUtil.getIcon( " notice_fw.png " );
11 public static final Icon PICTURE_ICON = ClientUtil.getIcon( " picture.png " );
12 public static final Icon CAPTURE_F4_ICON = ClientUtil.getIcon( " capturef4.png " );
public class FontStyle {
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 public static final String KEY_EN_FONT_SIZE = " PREFERENCES_EN_FONT_SIZE " ;
3 public static final String KEY_NATIVE_FONT_NAME = " PREFERENCES_NATIVE_FONT_NAME " ;
4 public static final String KEY_NATIVE_FONT_SIZE = " PREFERENCES_NATIVE_FONT_SIZE " ;
5
6 public static final String DEFAULT_EN_FONT_NAME = " Dialog " ;
7 public static final String DEFAULT_NATIVE_FONT_NAME = " Dialog " ;
8 public static final int DEFAULT_EN_FONT_SIZE = 11 ;
9 public static final int DEFAULT_NATIVE_FONT_SIZE = 12 ;
10 public static final int DEFAULT_LARGE_FONT_SIZE = 30 ;
public class ColorStore {
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 public static final Color BACKGROUND_ALL_UI = Color.white;
3 public static final Color BACKGROUND_UPDATE_UI = Color.red;
4 public static final Color BACKGROUND_HOMEPAGE = BACKGROUND_ALL_UI.darker();
5 public static final Color FOREGROUND_HIGHLIGHT_FIELD = Color.black;
6 public static final Color BACKGROUND_ADD_PANE = new Color( 0xCC , 0xCC , 0xCC );
- 有操作的界面要有“取消”或“关闭”按钮。
- 除主窗体外,基本不使用工具条和状态条。
- 慎用颜色和各种字体(包括字体大小和类型)。过多的颜色和字体会显得混乱,也会给用户一种不安的情绪。不过,对于一些需要提示用户注意的元素,又要坚定不移的用鲜明甚至刺激的颜色进行标示。这其中的平衡比较不好把握,不过“避免出错”比“好看”总是更重要的。2BizBox的早期版本风格非常朴素,甚至有点“灰头土脸”的。但谁说ERP或管理软件就应当“一脸古板”呢?经过反复尝试,2BizBox还是选择了能让人心情更加舒适愉悦情绪稳定的绿色和灰色作为主颜色,配合橙色、黄色、暗红色来突出一些界面元素,做到搭配合理。总之,界面风格就和穿衣服一样,不在乎花里胡哨,而在乎搭配和协调。
- 弹出消息要友好、清晰。2BizBox中的弹出消息分4个级别,包括询问、信息、警告、错误。
其中,严格慎用error错误级别的消息,除非碰到非常非常严重的情况,例如底层故障、无法继续操作等。过多的error错误信息,会给用户“系统容易崩溃”的感觉,让用户觉得恐慌,不踏实。软件虽然有会有各种异常,但是跟用户解释的时候却要显得“蛋定”,不要总拿“大红叉叉”的message吓唬用户。此外,弹出消息不光要提示发生了什么,还要尽量给出解决办法和后续推荐操作,甚至直接引导用户进行后续操作(如下图,提示设置零件图片FTP设置的提示消息)。
- 按钮要有文字。如果只有icon无文字,必须设置清晰可读的tooltip;
- 减少界面中的边框。有的软件喜欢用边框,大框套小框,最后框框一大堆,内容反而被弱化。边框本意仅仅是做好“组织分类”的作用,过多滥用反而喧宾夺主,造成用户眼花:
- 常用按钮的排列顺序要一致。2BizBox ERP中是大概按照“打印-刷新-编辑-添加-复制-快速查看-关闭”等顺序安排的。关闭按钮统一放在右下方,其他按钮放在左下方,依次横向排列。
- 有远程操作的界面,要有等待或进度条,并可以取消,因为谁也无法说清远程调用会消耗多少时间。执行结果要有明确提示:如失败提示,或成功后界面直接跳转。
- 尽量用内嵌的Tab窗口显示数据,而非独立的JFrame或JDialog,避免界面杂乱并占用资源。我们的经验发现,大量不关闭的JFrame或JDialog将占用大量操作系统资源,导致内存占用严重,系统变慢。而使用Swing轻量的组件如用内嵌Tab界面,则占用资源极少,基本上可以使劲new,毕竟他是轻量的(也就是Swing给Paint出来的),而不是重量的(操作系统的本地对等窗口对象)。除非有必要,才使用弹出对话框,因为模式的弹出对话框会阻断用户的其他交互。例如在模式对话框上填写了一堆数据,突然发现一个数据需要到其他模块差一下,此时会陷入严重的困境。使用对话框弹出必须屏幕居中,且要保持模式状态。个人始终认为,非模式的弹出对话框,是软件中最怪异的做法之一。
- 不要滥用图标。很多人喜欢用图标,感觉用了图标软件会更好看。按钮、菜单、tab、列表、树、下拉框甚至Label等等都大量使用图标。而且大多程序员自己不会设计图标,只是到处google或扣别人的图标,弄的软件界面七拼八凑,风格杂乱、花里胡哨、哗众取宠,界面反而失去了重点。就像女孩子穿衣服不是说把最好看的毛衣、外套、帽子、鞋子一股脑穿上就肯定好看。穿衣戴帽讲究的是“搭配”,Icon也是同样。Icon的作用是起到标示和图示的作用,增加软件的美观性和可理解性,但是不可过多滥用。
- 窗体比例协调。无论是Frame还是Dialog,长宽比例要协调,一般控制在5:3到3:5之内,超过2倍的比例一般都不太推荐。人的上半身和下半身的最佳比例也有一个范围,光靠上半身很长,估计也找不到女朋友不是?
- 界面布局要考虑易维护性、易理解性,而不是只考虑个人喜好甚至炫弄技巧。例如下图例子:用过多的按钮设计省份非常失败,加入增加一个省份则需要修改代码。“黑龙江”由于三个字被迫移动到下方,和“港澳台”一起,引起用户困惑。
减少点击Less Click
软件的一个重要任务就是方便操作,省时省力。所谓“简单、方便、快捷”,可不仅仅是口号。要做这一点,首先要从“减少鼠标点击”开始。鼠标点击动作能省一定要省,能少一定要少。能一目了然的信息,就不要拆的哲理那里、绕来绕去。软件业里面一个极端说法是“3次点击即可调出任意功能”,虽然比较难,但是足以说明“软件以用为本”的思想。以下举一些例子,可能会引来大家的共鸣或争议,不过欢迎大家积极探讨,毕竟软件界面设计没有完全的一定之规,而且也随着时代的变化而发展,有点类似服装设计。要不说我们程序员和服装设计师、建筑师是一类人呢!盖楼造衣服都有各自品牌或设计师特色,但都会遵守一定的基本规则,不会乱来。
- 一个界面上,除非特别必要才使用tab。为什么?减少点击。因为切换tab需要多一次鼠标点击。不过我们可以看到很多软件界面都特喜欢tab:没多少信息,还弄了一个大大的tab;tab上标签页很多,可点来点去,每个tab上东西却寥寥无几,让人恼火。程序员往往喜欢从自己的喜好,想当然的设计这样的界面,完全没有考虑使用者的感受,既不直观,也费时费力,没有体现“软件以用为本”的思想。
- 能一个界面显示完整的信息,就不要拆成多个界面。ERP里面很多单据信息复杂,关联信息众多,如何让用户清晰、一目了然所有的数据,是一个难题。不过,我们的原则是,宁可多现实一些数据,也不拆分成多个需要点击按钮分别呈现的界面。数据多,界面会显得繁杂一点,但是眼睛的移动速度总比鼠标再点击按钮查看新界面的速度更快。况且,通过不断的布局优化和组织重构,总是有办法让信息更加清晰。
- 界面信息饱满,重心稳定,头重脚轻、大面积空白。一个好的例子是2BizBox的“快速访问视图”。大家初次看到这个界面,一定有“密密麻麻”的感觉,其实这是经过精挑细选,把最常用的功能入口都统一组织放在了这个最方便醒目的位置,让用户可以快速进入一个常用的功能,减少点击次数,增加易用性。这就是为什么很多用户习惯了2BizBox后就会爱不释手。“漂亮”和“易用”那个更重要?这就像问找老婆“漂亮”和“善良”哪个更重要一样:如果无法兼得,咱宁可都选择后者。
- 能用复选框,就不用下拉框。为什么?因为多了一次点击。请问,选择一个“YES”、“NO”的选项,用checkbox点击几次,而用ComboBox又是点击几次?
- 能用列表,就不用下拉框。为什么?因为多了一次点击。List可以直接点击选择,而且所有选项可以一目了然,还可以做到多项选择。而下拉框只能单选,还要先点击一次下拉。当然,ComboBox比List有占空间小的优势。所以很多时候,界面设计是一种美观、易用的妥协结果。也许没有多少高深技术问题,但细节对于易用性和软件的品质却很重要。
- 菜单不能深,最多2层。为什么?减少点击次数。超过2层的菜单,功能被隐藏太深,组织结构太复杂,太难用,同时也增加了点击次数。举一个例子:一个大楼,进去一个主走廊,两侧是办公室,或可以再有分支走廊;如果分支走廊两侧还有进一步的“毛细走廊”,你可能直接就晕菜了,这样的迷宫大楼,你敢进么?2BizBox所有功能都集中在主界面的主菜单上,虽然功能众多,却保持两层的设计,简单方便。
- 统一的快捷键操作方式,减少鼠标操作。例如,所有tab内嵌窗体都可以通过ESC关闭,按F5刷新,等等。如果你键盘熟练,则会感觉很快很方便。
- 尽量不用右键菜单。为什么?减少点击。当年一个美国同事这样培训我们:右键菜单被称为“hidden functions”,是比较tricky的stuff,能不用尽量不用,我们印象很深刻。没错,这几年经常看到几近花甲的工厂老人在用2BizBox,他们一生搬零件或画图纸的手拿起鼠标来却可能显得笨拙颤抖,不要说右击菜单,就是单击和双击对他们都很难。对于他们来说,右键菜单这个东西绝对是够tricky的。可千万别说这些人蠢,ERP的用户就是这些制造业的劳苦大众,不都是程序员和游戏狂人,他们甚至整年少碰电脑。我们程序员的任务是让软件适应人,而不是让人适应软件。我们永远都不要嘲笑自己的用户。另外,右键菜单是把固有的功能“藏起来”,如果不动手,光靠眼睛看,是无法观察到这些功能的,违反了“一目了然”的原则。一个界面如果不能通过观察就可以大概猜测出其功能和用法,则是比较失败的。所以右键菜单应当慎用。
为了减少点击,2BizBox对功能的组织可谓费尽心机。在主界面上就有如下体现:
- 主菜单:罗列了所有模块、子模块的所有功能点,并保持了2层菜单结构。这里像一个功能字典,让初次接触2BizBox的用户可以滑动鼠标,快速了解2BizBox的模块和功能。隐藏较深的功能,也可以通过主菜单,快速进入任何功能入口。有人说菜单这个东西很土,有点过时了。不过无论采用什么技术,“易用性”永远不会过时。
- 模块栏:模块栏把2BizBox中所有的模块、子模块经过筛选和组织,直观的放在一起。同时,配合屏幕中间的模块关系流程图,能够更清晰的了解模块的组织结构和关系。
- 快速任务列表:当选中任意模块或子模块,右侧的“快速列表”都会直接过滤并显示当前选中模块的常用功能。“快速列表中”显示的都是经过精挑细选、用户最常用的功能,并通过几个经典易懂的图标来快速标示其“添加”、“修改”、“查询”的功能类别。直接点击,即可进入该功能界面。
- 快速访问视图:如果说“快速任务列表”无法直观的给出每个功能的查询操作参数,那么“快速访问视图”则可以解决这一问题。在这里,罗列了本模块最最常用的一些功能入口,并直接给出了该功能需要输入的各种参数。这样,用户可以一目了然的看到每个功能和参数,直接输入参数并点击按钮进入功能界面。
- 模块快捷按钮:在模块图上,每个模块节点的右边都有三个小图标,对应三个快捷按钮。这三个快捷按钮,是该模块最最最常用的三个功能,可以直接点击进入,进一步减少点击次数。
2BizBox ERP中文版(内部预览)
你可能会说,至于这么大动干戈的减少点击次数么?好,咱们举一个例子吧:假如你做的一个2BizBox界面会被1万人使用,或者说,2BizBox软件足够lucky,可以被100万人使用,而这些人每天都至少操作这个界面一次。如果你的界面设计增加了一次点击,按每次点击用时1秒,你知道这次设计每年会消耗掉多少时间吗?100万人*360天=3.6亿秒=10万小时=12500个工作日=568个工作月=近50工作年。如果按一个人一生工作35年计算,你的这个设计不亚于毁掉了一条半人命。这是在犯罪、在杀人,不是吗?