2008年1月10日
今天客户方服务器上突然有一个功能保存了,查看日志信息后发现,错误信息:
Could not instantiate class XXX from tuple at AliasToBeanConstructorResultTransformer...
Google了很久才发现有可能是HQL语句中别名的问题,具体原因未知,现在处理办法是,将下面的语句中的别名去掉:
StringBuffer hql = new StringBuffer("select new ContractItem(l, "
+ " pi.unitPrice, " + " pi.currencyType, " + "pi.currencyTypeDisplay," + " pi.units, "
+ " sum(pi.quantity + pi.adjQuantity), " + " pp, " + " pi.task) "
+ " from PurchasePlanItem pi " + " join pi.purchasePlan pp"
+ " join pi.priorList l " + " where l.supplierNo = ? "
+ " and pp.id in (");
具体是否可以解决,还要看一会儿的部署情况。
上篇文章中我简单阐述了军工企业信息化遇到的困境,而我们公司(西安融智软件有限公司www.xardmu.com)则主要是面向军工企业进行软件产品的研发和定制项目的开发的。
在产品实施和项目研发过程中,我们的前端技术人员需要做大量的浏览器兼容性的工作。痛苦至极啊~而且,即便完成了兼容性的修改,浏览器端的JS解析又变成了巨大的瓶颈!例如我们有一个项目为了提高用户使用的时的方便性,使用了EXTJS4,结果在IE6下性能极其低下。我们的P8是一个项目管理软件,需要使用到基于EXTJS的Gantt组件,但是此组件在IE6下十分不稳定,而且经常导致IE6崩溃。
介于上面的种种问题,我们开始寻找从浏览器上解决问题的方法,例如使用FireFox或者Chrome,因为军工企业都有域,所以通过域安装一款软件是十分容易的。经过权衡,我们决定使用Chrome做为我们软件的入口。
在企业内部署Chrome其实有三种方式:
1.直接使用Chrome的某一个版本,对此版本进行精简和简单的参数配置,或者内置一些自定义的插件,直接进行部署。
优点:技术门槛较低,只需要简单的精简安装文件和配置参数即可。
缺点:无法通过统一的策略管理局域网内所有的部署情况和策略。
2.使用Google提供的Chrome商业版,通过Google提供的商业版可以轻松定制自己企业内部的Chrome,并生成分发文件,同时可以通过配合域策略完成对局域网内的客户端的行为进行限制。
优点:此版本是11年放出的,一直和多个大型企业紧密合作,相信不久将会形成更加完善的方案,从而在企业级应用市场站稳脚跟。
缺点:需要在线安装。
3.使用Google的Chrome Frame,一个让披着IE外壳的Chrome,拥有Chrome的所有性能,只是披着IE的外壳而已。
优点:对于较老一些的企业,而且企业内部又拥有大量的IE时代产物的企业,绝对是一个好选择。
缺点:需要在线安装。原有软件代码需要修改,才能在用户浏览时使用Chrome模式。
看到痛苦了吧?都需要在线安装。看来下一步只能开始研究Chrome的源码,修改并编译属于自己的浏览器了。。。
最近在做项目的过程中,有些时候需要用Oracle的BLOB/CLOB类型存储一些很长的文章,一直不知道怎么来进行相关的检索,经过不懈的努力,终于能够解决这个问题了。查询语句如下:
select count(*) from 表名 where dbms_lob.instr(表名.列名, utl_raw.cast_to_raw(convert('关键词','utf8')), 1, 1) > 0;
需要注意的是,这个解决方案只能查询BLOB/CLOB中存储的是经过处理的字符串。
本方法在Oracle 10g上测试通过
转自http://commandos.blog.51cto.com/154976/128732
作为一个技术人员,谁不知道构架?
前一段时间公司找开发人员谈心,有位领导问一位开发人员,大致对话如下:
A:“你了解咱们现在产品的构架吗?能不能谈谈你对构架的看法?”
B:“… …”
A:“说说看吧~”
B:“我不懂构架!构架是什么?咱们现在的产品还有构架呢?”
作为一个有3年工作经验,2家公司经历的VC程序员来说,我觉得,这几年的积累是白做了!这样的思想永远都只能停留在写程序上~
一个产品没有构件,就如同一个人没有灵魂一样!他不是没有,只是你没有去思考,没有去发现他而已!
我记得袁洪刚说过,“一个伟大的产品背后一定有一个伟大构架师!”,我坚信这一点~产品好坏一方面决定于对现实问题的解决程度,另一方面是构架的好坏!
几年前,中国的软件公司里面很少出现构架师/架构师这样的角色,这几年开始有改观了,越来越多的人开始认识到很多错误的问题,其实从一开始就是错的。很多事情并没有谋定而后动。一味的追求简单,到最后变成了下线很简单了!
说自己不知道构架的开发人员有两种,新手和没有思想的新手,拼命的同时我们也应该停下脚步想想,抬起头看看天空。别总把经验的缺失都归结于时间的长短,更应该想想自己是否真的积累过。
Wazaabi 2.0 基于 Eclipse3.4/EMF/GEF 的动态界面设计和现实组件,依赖EMF进行界面描述,依赖GEF进行界面显示。
比较起XUI,XSWT,它的设计器更加的完善,功能比较1.0版本也有很大的提高,而且作者也提出了使用EMF进行数据绑定的思路和实现。
麻烦的是它本身只提供了Fill和Row两种布局,Button、Text、List、Label这些基本控件。还好作者的文档功底不错,简单几张图就把自己的设计思路描述的清清楚楚,高手所为,赞一个!
在它基础上可以很简单的进行扩展,而且比扩展VE要简单的多~这是我喜欢的!现在对它的使用本人还是处于观望态度,一方面等待它的持续更新,另一方面等待E4的激动人心的放出!
有兴趣的朋友可以看看http://www.wazaabi.org/index.php?title=Main_Page
明显第一种构架比第二种构架好很多,但是我们偏偏在第二种构架上面挣扎了半年的时间。
总是有各种各样的接口和推辞说业务太复杂,客户催的太紧,没办法把业务放到服务器上,成本太高了!已经是2009年了,10年前大家就意识到维护是关键,业务一定要封装,不能分散于客户端… …10年后的今天我们竟然还在挣扎!完全没有思想,完全没有设计,完全没有接口,完全没有OO… …!!!
项目告一段落我要拼命的重构,彻底抽离公共业务,彻底剥离特殊业务,我要OO,我要接口,我要设计,我甚至还要SOA!
我错了!我认错!可是为什么公司还有那么多的人还是不认错呢?做了10年的产品,10年前的东西竟然比10年后的东西还好用!做了10年还是死缠烂打在10年前的原型之上~他们比我更悲哀~
粗心大意,老犯错!
今天上午在调试EJB3调用WebService时一直遇到MySQL报出的这个问题。郁闷坏了,只是执行了一句update而已,就导致这样错误… …
经过半个小时排查,终于找到问题所在了。原因是分布式事务引起的。
场景描述:
EJB3操作A表-->调用WebService-->WebService操作B表
在操作A表的时候需要等待WebService的调用,如果没有异常,则可以提交事务,如果出现异常,则不能提交事务;
在操作B表的时候需要处理异常;
一个简单的分布式事务,一般情况下是没有问题的~但是由于我的粗心大意,做成了EJB3也在操作B表,这样就导致了表被锁死的情况出现~真是郁闷啊!
以前我们的产品重启RCP应用程序的时候都是找到本地路径的EXE程序,然后使用:
1Runtime runtime = Runtime.getRuntime();
2runtime.exec("cmd.exe /c " + excuteStr );
重新启动应用程序,太复杂,而且上次打开的参数都会丢失。
今天早上翻看了一下Eclipse的org.eclipse.update.ui CVS,找到了:
PlatformUI.getWorkbench().restart();
使用这个重新启动RCP应用程序,非常的方便,而且参数都在,即使在开发环境下也一样没有问题!
VE已经死亡很久了,整个Eclipse社区中,最悲壮的真的要属VE了。
伟大的目标,没落的贵族!记得去年在北京的时候,经常有朋友问我VE怎么安装。呵呵VE2.0开始安装真的很复杂,偌大的Eclipse-WIKI里面还真的没有写多少关于VE安装的内容。
去年下载过VE的源码,打算在VE的基础上做一个自己的设计工具,但是研究了很久,发现CVS上的源码都过于陈旧了,然后就再也没有关注过它了。
很久没有真正的关注过Eclipse了,今天上来看看,发现VE真的回来了!
现在VE的领导者是深圳的亚松(在西安有分公司,我还真想去试试... ...),而亚松最让我崇拜的大牛就是Yves YANG,呵呵,EclipseWord的大牛哦!
我在自己公司的产品里面也引入了建模的概念,下一步就是根据模型来生成界面,再下一步就是改造VE,让二次开发人员开发起来更容易更加简单。
祝福VE,希望有了亚松,VE会更好。
预告下一个系列文章:
企业信息系统建模的思考;
新VE源码分析;
我见过最好的软件界面绘制工具http://www.balsamiq.com/
真正能达到又快又好!
做人何惧艰险,豪情不变年复一年,做人有苦有甜,善恶分开两边,都为梦中的明天!
上面这段签名是抄老莫的,每读一次都会有不同的体会。
没有维护Blog已经有两个多月了,这两个月一直在北京出差,已经待了两个月了,还得再待一个月!每次出差离开西安总是感觉不舒服,而且从心里要好长时间才能适应,所以就一直没有维护Blog。
晚上和一位美女吃饭,聊天中突然聊到了这个问题,仔细想想为什么做什么都觉得没有意思?为什么会不适应外界环境的改变?为什么觉得一切都不爽?
是因为没有了激情,最近缺少了激情!缺少了创造的激情,缺少了生活的激情,缺少了工作的激情,缺少了写Blog的激情... ...
重拾激情,这才是重要的!做人何惧艰险!人生路上本来就充满了艰险,要勇敢面对,无论是失意还是快乐... ...何必在乎得失,终究一切都会过去!抓紧时间,去实现自己梦想!
老版本的Eclipse多国语言项目只维护到3.2.1版本,以后就再也没有维护了,我觉得主要的问题是,语言包太大,一个包中会有多种语言,对于RCP版本的产品汉化起来很不舒服,明明我只要中文,结果要加入N个语言进来,而且还是20M的包~
Eclipse的http://download.eclipse.org/eclipse/downloads/最近刚刚放出一个叫做Babel project的项目,这个项目就是在解决国际化的问题,这个项目旨在为每一个插件提供独立的单语言包,这样在做RCP项目的时候,可以根据需要,打不同的包就可以了~!
周五的下午测试了一下,汉化率绝对在99%以上,而且很多地方的汉化还是很到位的~再有哪些客户看不懂的地方的了~
只是有一个很小的麻烦,就是RCP原来的异常对话框中的内容,每一句后面都会有\n,莫非多国语言的时候\n被转义了?
希望可以得到改进!
Neil Bartlett的当下工作就是完成《OSGi in Practice》,今天他在Blog中已经放出了本书的一个预览版本(第二章)。一下是书的目录:
Introduction
First Steps in OSGi
Bundle Dependencies
Introduction to Services
Example: Mailbox Reader GUI
The Whiteboard Pattern
Declarative Services
The Extender Pattern
Integrating Third-party Libraries
Building Web Applications
从PDF的授权看是“署名的,非商业的,可流传的”,我估计这本书上市的时间应该很近了,而且官方的PDF版本也会同步推出的~
喜欢的朋友可以下下来看看,写的很详细,个人认为是本好书,而且此作者应该是Eclipse基金会的人,所以对OSGI的理解也不错有什么问题~
ps:连接地址:http://neilbartlett.name/blog/osgibook/
SQL文件中有Functions,Type,那么在sqlplus中要start直接执行SQL文件怎么办?例如:
CREATE OR REPLACE FUNCTION strcat(input varchar2 )
RETURN varchar2
PARALLEL_ENABLE AGGREGATE USING strcat_type;
将上面的Functions写入SQL文件中,然后在sqlplus中用start执行此文件,后果是此Functions并没有被创建到数据库中,在后面加上commit;也是没有用处的,提示的效果是SQL并没有结束,sqlplus并没有真正执行。
这怎么办?Google了老半天,也没有人写到这个问题,但是看看人家写Functions和我写的有一点点区别,修改一下!
CREATE OR REPLACE FUNCTION strcat(input varchar2 )
RETURN varchar2
PARALLEL_ENABLE AGGREGATE USING strcat_type;
/
在Functions最后一行加上一个/,再执行就OK了~看来sqlplus是把/作为一个Functions或者Type的结束符了!大家注意了!
Shell.open()非常重要!
今天在做SWT中显示OCX控件,照着Demo写的,但是不知道为什么每次执行到:Variant pVarResult = auto.invoke(dispIdMember, rgvarg);
JVM都会直接退出~error如下:
# # An unexpected error has been detected by HotSpot Virtual Machine: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x73d321b9, pid=3696, tid=2208 # # Java VM: Java HotSpot(TM) Client VM (1.5.0_04-b05 mixed mode, sharing) # Problematic frame: # C [MFC42.DLL+0x21b9] # # An error report file with more information is saved as hs_err_pid3696.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # [error occurred during error reporting, step 270, id 0xc0000005] |
寻便了网络也没有解决办法,刚开始以为是JVM版本的问题,于是换了3个版本都是同样的问题~真是郁闷!
最后通过和Demo代码的比较,发现Demo中有一句shell.open(),注释掉此句,Demo也是引起JVM退出!在代码中加入shell.open(),搞定!
原来这个open方法还有这么多的玄机啊,但是javadoc上却只字未提!
早上看到Google的人肉搜索的招聘广告,兴冲冲的发了邮件,申请,结果:
尊敬的朋友,
非常感谢您在4月1日积极参与谷歌人肉搜索志愿者招聘,这是谷歌于2008年4月1日"愚人节"推出的让大家"会心一笑 暂解烦忧"的小笑话,在此谨祝大家"愚人节"快乐,天天快乐。
如果您对谷歌公司招聘感兴趣,欢迎进一步登录我们的招聘网站寻找自己真正心仪的职位。http://www.google.cn/intl/zh-CN/jobs/
谷歌肉搜组
Dear Friends,
Thank you very much for your interest in the job positions of Google's "Grassroots search" volunteers on April 1. This is a joke that Google China does on April 1, 2008 to give you some light-hearted mood. Hope you laughed because of it :-). Here, we want to wish everyone "Happy April 1st day and Happy Everyday."
Google Grassroots Search Engineer and Product Group
晕~被欺骗了!写的跟真的一样的:
关于人肉搜索
什么是人肉搜索?
人肉搜索与刺青、美白、护肤、减肥等直接在人肉上施行的种种行为无关。顾名思义,人肉搜索就是利用现代信息科技,变传统的网络信息搜索为人找人,人问人,人碰人,人挤人、人挨人的关系型网络社区活动,变枯燥乏味的查询过程为一人提问、八方回应,一石激起千层浪,一声呼唤惊醒万颗真心的人性化搜索体验。人肉搜索不仅可以在最短时间内揭露某某门背后的真相,为某三某七找到大众认可的道德定位,还可以在网络无法触及的地方,探寻并发现最美丽的丛林少女,最感人的高山牧民,最神秘的荒漠洞窟,最浪漫的终极邂逅…… 人肉搜索追求的最高目标是:不求最好,但求最肉。
谷歌为什么要创建人肉搜索引擎?
谷歌自进入中国市场以来,一直致力于根据本地需求改进用户的搜索体验。谷歌很早就意识到,自发的、分散的、有意或无意的人肉搜索行为早在中国互联网诞生之初就存在并茁壮成长着。中国互联网界发生的几乎每一起重大事件,尤其是娱乐性事件,都有可能成为人肉搜索技术的试金石。为了丰富人民群众的业余文化生活,为了使广大网民在最短时间内赶超人肉搜索的世界水平,谷歌决定投入巨资打造亚太地区最大的人肉搜索引擎。
谷歌人肉搜索引擎有哪些特点?
- 规模最大:第一期工程拟招募人肉搜索志愿者2500万名,完成后将成为亚太地区最大的人肉搜索引擎。
- 创新最多:256项专利技术,1024篇相关论文,4096次用户调研,65536轮预览版测试。
- 领域最全:搜索范围涵盖娱乐、影视、体育、社会、名人、百姓、历史、地理、物种、太空等领域。
- 速度最快:平均查询响应时间32秒。
- 挖掘最深:曾在预览版测试中,用时128秒,成功定位了中国大陆生产的第一只自动冲水马桶。
人肉搜索招聘需求
人肉搜索志愿者管理专员
组织和领导以志愿者为核心的超大规模人肉搜索团队,整合来自数千万搜索志愿者的小道消息,从茫茫人海中发掘信息背后的奥秘。严格管理,制止人肉搜索过程中可能出现的扯皮、造假、谣传、起哄、攻讦、谩骂等不文明行为,创造合理、有序、创新、务实的人肉搜索新秩序。
能力要求:
- 博士以上学历
- 管理学、传播学或相关专业毕业
- 掌握五种以上方言
- 有八卦主义精神和凡事不着调作风者优先
请将您的中英文简历以文本或HTML的格式发至renrou-jobs@google.com, 并在邮件的标题中注明“人肉搜索志愿者管理专员”。邮件正文请使用中文,所有英文信息请以附件形式提交。
人肉搜索志愿者(兼职)
在业余时间为人肉搜索引擎奉献智慧、汗水和好心情。利用谷歌研发的人肉搜索平台,与其他数千万志愿者并肩工作,使用并行人肉计算的方式,对疑难问题坚持不动摇、不软弱、不抛弃、不放弃的肉骨茶原则,为广大网民提供第一手的,带有人情味儿的,具有震撼力和可传播性的搜索结果。
能力要求:
- 学历不限,专业任选
- 有强烈的好奇心和求知欲
- 对常人无法获取的信息有敏锐的感知能力和打破砂锅问到底的坚定信念
- 自备联网电脑一台,电话机一部,粉笔若干,餐巾纸一箱,《八卦人物风云榜》16开大字本一套共40册
请将您的中英文简历以文本或HTML的格式发至renrou-jobs@google.com, 并在邮件的标题中注明“人肉搜索志愿者(兼职)”。邮件正文请使用中文,所有英文信息请以附件形式提交。
致猎头公司:对于未签约的猎头公司提供的简历,谷歌将不支付任何费用。
此次RAP放出了draw2d_in_RAP的Demo,主要展示的是draw2D在RAP框架上的应用,还没有下载真正的Demo试用,但是从视频上看,好像是融合了flex来做图形展示和拖拽,有兴趣的朋友可以看看Demo的代码,然后告诉我~
上次e4放出的基于web的IDE就使用flash作为代码展示和编辑的编辑器,看来Eclipse社团也感觉到纯的js基本上不能完成任务了。
Demo下载地址:http://www.innoopract.com/fileadmin/user_upload/Bilder/Films/draw2d_640x480.mp4
关注过上一篇文章的朋友,基本都对最后说到的微软要支持SWT的开发提出了不少自己的看法。
下面我们再来看看来自cnBate.com的新闻:
Java程序员们可能会经常遇到Windows下的UI问题,Java程序总是和Windows的外观统一不起来,特别是Vista,难度更高.
而现在,微软微软宣布它将为Eclipse基金会提供了标准的widget工具,这意味着Java将与Windows Presentation Foundation实现互通,允许应用程序原生采用Windows VIsta的外观.
这也是微软未来开放计划的一部分,微软认为一个日益开放,透明的方式正在出现.之前,微软还成立了Linux的互操作性实验室,并与JBoss,Zend Technologies等公司实现了技术合作.
|
微软真的在开源,不但支持了Linux,而且还来关注SWT,而且还有微软最近在收购Yahoo!,它最近非常关注开源事业,也许他真的要搅局,也许他真的是想做些事情,也许几年之后微软摇身一变真的变成了一个开源斗士了!
微软更换了首席构架师,他的做事风格在改变,我想微软是在向开源界证明自己的实力,是想让人们相信自己,也许过几年微软还果真出了一个开源版本的windows了~
早上,习惯性的打开GoogleReader,看看世界的变化。发现Planet Eclipse上已经有参加EclipseCON2008的朋友把Eclipse4.0(简称e4)Demo地址以及一些截图放到Blog上了~我们就来欣赏一下Eclipse的巨大变化吧!
呵呵,是不是很可怕,一个基于web的开发工具?我在Eclipse的Wiki上已经看到这个截图的Demo了,但是还没有时间试用~
此次放出的e4的demo基本上都是swt的调整,比方说可以使用swt来做flex,使用swt来做DOJO~,从这些方面就可以看到Eclipse正在向基金会想想的那样为e4提供一个基于web应用的平台,我想这个平台应该就是RAP了~而且从Demo上看,e4将会大大的涉足到web应用领域中,期待他们为我们带来再一次的惊呼!!!
http://wiki.eclipse.org/E4/Running_the_demos (e4的demo)
还有一个令人振奋的消息,不知道是好事还是坏事-----微软已经决定进入Eclipse基金会,并打算开始资助SWT项目了。
Earlier this week, the teams and developers working on the various projects of Eclipse began an intense debate regarding the next steps in the future of Eclipse, all triggered by the announcement of the incubation project titled 'e4' on the Eclipse committer mailing-list:
The Eclipse Project PMC is announcing a new component, called E4, as part of the Eclipse Project Incubator.
Component Description:
During the Eclipse Project 3.4 release cycle, one of the important plan items was "Create the Eclipse 4.0 Plan". The intent of this work was to identify the most pressing issues that would impact the ongoing success of Eclipse, and come up with a plan to address them. The result was the design of a new platform "e4", which will be the basis for Eclipse 4.0.
The goal of the e4 component is to provide a public venue for the initial explorations that were done, leading up to the e4 design. We expect to continue to work in this area until we have reached consensus on how the full e4 effort will be structured.
The e4 moniker is a reference to Eclipse 4.0, which would be the next major release number for the classic Eclipse distribution and platform projects. The last three major Eclipse releases shared these version number relationships:
Callisto corresponded to the Eclipse platform v3.2,
Europa corresponded to the Eclipse platform v3.3, and the upcoming
Ganymede release corresponds to the Eclipse platform 3.4.
Historically it has been common practice for these plan documents to outline the thematic goals for a given release of what is commonly called the
Eclipse top-level project. Traditionally, the top-level project has encompassed the Eclipse platform, the Java development tools, the Plug-in development tools, and all other components of the commonly referred-to Eclipse 'classic' distribution (the Java and Eclipse Plug-in IDE). This plan format has been used since the 2.1 release of Eclipse, and each prior plan is available
on the Eclipse top-level project site. The e4 announcement is a somewhat different approach in that community involvement is being asked prior to the drafting of any plan.
Initially, the e4 project is little more than a community gathering point; a place to track early changes and ideas in code. The goal of opening this project now has been described by many of those involved as an effort to get community input and ideas at
EclipseCon 2008, and to then begin drafting a plan based on the community input after that point. Kevin McGuire, an Eclipse committer who primarily works on the Platform UI team, described e4 in this way:
We on the platform team care passionately about Eclipse. We know you do too. We want to see it live a long, healthy life. We want it to serve its community as best it can. When we can’t achieve that it makes us sad. It’s clear to us that for Eclipse as a platform to remain long lived, vibrant, and relevant, it must be able to change. But the weight of a zillion plug-ins, projects, and API means the path of least resistance is stagnation, and the effort to effect change given the current constraint system is becoming monumental.
Therefore, two things must happen:
- A new space must be carved out in which experimentation can happen, leading to change.
- New people must get involved, bringing with them their energy, ideas, requirements, knowledge, passion.
These two are intrinsically tied.
That is e4.
While there was some heated discussion over the format and approach of the initial project announcement, the e4 project is likely to become a central test-bed for the various transformations that Eclipse will go through to reach its next major milestone. In the past, major version number increments for Eclipse have represented significant changes for the Eclipse project. The transition to Eclipse 3.0 encompassed the move of Eclipse to the OSGi platform, the announcement and creation of Eclipse rich-client platform, and both a look-and-feel and performance overhaul. The expectation is that Eclipse 4.0 will also represent such a major shift.
InfoQ will continue to cover future Eclipse planning decisions as they become available.
EclipseCON2008 only 1 week left!
又一次开源界的盛会EclipseCON2008就要召开了~据我了解此次盛会将会吸引更多的开源厂商,领袖,开发者参与,其中就有来自微软的Sam Ramji(微软开源的Labs),关于OSGi的讨论依然是重头戏。
虽然Eclipse的RAP的发布也有半年多了,也在开源界引起了不小的反响,但是RAP还是没有得到广泛的应用,来自RAP的主力开发商Innoopract Informationssysteme GmbH的消息,此次EclipseCON2008大会也会给RAP带来更多的利好消息,毕竟关于RAP的讨论被安排在第二场,仅次于第一场OSGi的议题。
Eclipse4.0也被提上了讨论日程,在介绍中提到,Eclipse3.0主要在力推RCP平台,而Eclipse4.0将会将会带来一个全新的用户界面以及新的用户体验,将带领Eclipse进入到WEB应用中,我想在Eclipse4.0的时候RAP应用,将变成Eclipse的主推平台了。
还有很多关于其他项目的讨论,但是我一直关注的VE的消息,好像还是不被人们注意,可见VE基本上已经死亡,而且我认为可以算是Eclipse基金会中比较失败的一个项目了!
预祝此次大会硕果累累,祝Eclipse越走越好!
预言了两天,终于决定在我们的RCP客户端中增加执行JRuby的功能。说是预言其实也没有什么好预言的,JRuby早有耳闻,Ruby也一直在学习。其实要解决的问题只有一个---解决Java实例如何给JRuby,然后有JRuby操作,其实不难,JRbuy官方的WIKI上有一个例子,但是那个例子有太多硬编码的问题,稍稍改造,将硬编码的内容抽取到JRuby中,就好了~
我想说的其实是在RCP中加入JRuby的作用是:
实施人员只需要写脚本就可以随意操作界面上的任意东西;
使产品更进一步达到零二次开发的阶段;
使用JRuby来开发SWT的界面,还是有比较复杂,在熟悉SWT开发和JRuby的情况下画一个比较复杂的界面时候就会非常复杂!这里还是建议使用类似于XSWT等XML界面描述语言,然后配合脚本完成功能。
下面给出一个可以在运行JRuby的SWTShell:
package com.glnpu.jruby; import java.util.ArrayList; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.jruby.Ruby; import org.jruby.javasupport.JavaEmbedUtils; import org.jruby.runtime.builtin.IRubyObject; public class RunJRUBY extends Shell { private RunJRUBY run; private Text text; /** * Launch the application * @param args */ public static void main(String args[]) { try { Display display = Display.getDefault(); RunJRUBY shell = new RunJRUBY(display, SWT.SHELL_TRIM); shell.open(); shell.layout(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } catch (Exception e) { e.printStackTrace(); } } /** * Create the shell * @param display * @param style */ public RunJRUBY(Display display, int style) { super(display, style); run = this; createContents(); } /** * Create contents of the window */ protected void createContents() { setText("SWT Application"); setSize(500, 375); text = new Text(this, SWT.V_SCROLL | SWT.BORDER | SWT.WRAP | SWT.H_SCROLL); text.setBounds(0, 0, 492, 312); final Button button = new Button(this, SWT.NONE); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { Ruby runtime = Ruby.getDefaultInstance(); try { //允许传对象,作为参数给JRuby IRubyObject rootRubyObject = JavaEmbedUtils.newRuntimeAdapter().eval( runtime, text.getText() ); JavaEmbedUtils.invokeMethod( runtime, rootRubyObject, "run", new Object[] {run}, null ); //不传对象,直接运行JRbuy //runtime.evalScriptlet(text.getText()); } catch (Exception e1) { System.err.println(e1.toString()); e1.printStackTrace(); } } }); button.setText("button"); button.setBounds(335, 326, 48, 22); // } @Override protected void checkSubclass() { // Disable the check that prevents subclassing of SWT components } } |
下面是可以执行的JRuby代码:
require 'java' module SWTTest include_package 'org.eclipse.swt' include_package 'org.eclipse.swt.layout' include_package 'org.eclipse.swt.widgets' include_package 'org.eclipse.swt.events' end class TestDialog < SWTTest::Dialog @shell @parentShell def initialize shell super(shell, SWTTest::SWT::NONE) @parentShell = shell open end def open createContents() @shell.open(); @shell.layout(); end def createContents @shell = SWTTest::Shell.new(@parentShell, SWTTest::SWT::DIALOG_TRIM | SWTTest::SWT::APPLICATION_MODAL) @shell.setSize(500, 375); @shell.setText("SWT Dialog"); button = SWTTest::Button.new(@shell, SWTTest::SWT::PUSH) button.setText("Test Button 1") button.setBounds(147, 116, 48, 22); end end class TestMain def run shell TestDialog.new shell end end TestMain.new |
在JRuby代码的最下面有一个TestMain的类,主要是用于调用的~这一点是和其他的写法不同的!
至于它有多强大,就看大家怎么用了~而且java和JRuby是运行在同一个JVM之上的,它可以使用此JVM下的所有对象!
不要用年终考评来订立学习目标,要利用年终考评来记录个人的成长。
要让每一位程序设计师都明白,写出零错误程序是很不容易的,所以应该多花功夫用各种方法做最彻底的测试。
纠正程序设计师以为加除错码会花太多时间的观念,应该训练程序设计师第一个反应是考虑加上除错码是否有道理,第二是考虑加除错码是否符合项目的目标与工作的优先级。
不要让凡事不能的态度阻碍了创新。
不要让程序设计师以为使用者并不在乎软件的质量。
不要给使用者次品,宁愿延期交货,务必追求质量完美。
程序设计师必须经常以使用者的观点来看自己写的程序,程序设计师必须能体会使用者的感受。
在包装盒里的每一件东西,都是产品的一部分。
将程序的可共享性当作优先考虑的目标之一,否则程序设计师将经常做重复的工作。
从您的每件工作中创造最大的资源,不管是利用现有的杠杆,或是创造新的杠杆。
如果进度发生落后,那表示有个地方出错了。您应该找出问题,并加以解决,不要一味要求组员加班,在问题没有解决之前,加班是没有用的。
别误信加班等于增加生产能力,长期的加班只会伤害生产能力,对项目没有帮助。
周末是属于组员私人的时间,不是公司的。公司不应该以打败竞争对手为理由,要求员工周末加班。
强调思考的重要性,而不是长时间工作。
训练开发小组懂得在正常工作时间内掌握好工作的效率,不要让他们超时工作,因为超时工作只是浪费时间的假面具。
与程序设计师共同研拟出一份每日活动的时间表,把无法预期的临时公务变成固定时间处理的事情,并且把程序开发的工作放在最优先的地位,不要让其他次要的事情干扰到写程序。
主管应该把自己视为团队中的一分子,与其他人平等,而不是高高在上。
用看程序的方式找错,是既懒惰又无效率的方法;
随时睁大雪亮的眼睛,看看是不是有个悬而未决的问题,一定要有个人(或是由主管自己)来负责研究到底哪里出错,也许这种研究既花时间又无聊,但总比灾难发生之后再来花好几个星期收拾残局要好得多。 |
问了错的问题,而导致错的答案,训练自己问出正确的问题!
如果您能很清楚告诉别人,您想要的究竟是什么,这样别人才能给您真正需要的帮助,而不是做一些似是而非的虚工。 |
勉强自己接下不可能完成的任务,实在是以长痛代替短痛的做法,而且长痛的是整个团队,该拒绝的时候绝对不能含糊;
不要为了讨好别人而伤害双方的工作进程,您永远要根据自己的目标,做适当的决策。
必须保护项目不受外界的左右,尤其是当这种操控来自特权人物之手。
副产品对公司或产品都没有策略上的价值,充其量只是一种消费者回馈。
不值得开发的功能就不要做。
软件产品的开发,不能只为了有趣、挑战性,或是够有个性够令人眩目。
遵循标准重于一切,特别是关于使用者界面的部分。
确定您所要求的报告真的值得属下暂停工作,花那么多时间去写。
请注意定期会议的价值,确定它值得每个人放下手上的工作。
召开任何会议之前,请确定本次会议的目的是什么,达成这个目的的条件是什么,然后,务必达到开会的目的。
不要利用进程表来驱使项目的进行,这对小组的士气伤害太大了。
让日程表维持适度的紧迫,但又是可以做到的,好让组员振奋、不松懈,专心致力于项目的推进。
绝对不要草率定出不可能的期限,导致组员为了赶进度而损害产品的质量。
把长期的大项目,分成几个完整而独立的小项目,各小项目必须有一个主题。
为了保持创意的活力和团队士气,必须让每一个小项目都有令人兴奋的结果。
不要让程序设计师的学习停滞不前,要让程序设计师有机会磨练不同领域的技术,培养十八般武艺样样精通的组员。
训练新进程序设计师时,先培养他对整个公司所有项目都有价值的技术,然后才培养本项目独有的技术。
不要舍不得放您最优秀的程序设计师到别的项目去。如果他在您的项目已经没有新的东西可学,为了公司和他个人的前途,您应该把他推荐到别的项目,让他的成长永不间断。
确定每位组员、每两个月都有一项技术上进步。
一发现某处需要改进,就立即采取更正的行动。
首先还是先看一下书评。
下面是来自china-pub的书评:
作者详细描述了他在美国领导项目的各种实际的策略方法,教您如何开发高质量的软件,而且绝不延误。本书是为每一位从事研发工作的朋友而写,相信您在读过本书之后,一定急于推荐给您的主管、同事和您的朋友。 |
卓越的领导者从不同的角度看世界。若是公司被大火烧得精光,他非但不为丢饭碗惊慌,反而利用火焰来烧烤一顿大餐。当每个人都摇头离去,卓越的领导者仍有充分的信心保持乐观,对每件事都从正面角度来思考。就因为凡事都看光明面,卓越的领导者并不把失败当失败,反将其当作学习克服障碍的经验。正因如此,卓越的领导者乐意尝试各种稀奇古怪的想法,并从中获得重大的突破,即使不成功,他只把这次经验当成获得信息的方式之一。这种领导人不一定要有经验,而是需要强烈的进取心和明确的理想,能够将理想与他人沟通,鼓舞他人共同追寻理想的能力,再加上一点机会,这就是能将理想实现的卓越领导者。
每当有人完成了一项新的功能或特色,就发个e -mail 给大家。
例如:
“我已完成Faxmangler 的搜寻与取代功能。Frank” 主管应该看一下结果,然后回一个: “我检查过F a x m a n g l e r的搜寻与取代,不太顺畅,请再修改。Hubie” 或是: “很好,继续加油!Hubie” 想想看,如果大家经常收送这类正面的e - m a i l,一定会觉得充满干劲,这和可恨的进度报告多么不同!程序设计师会很乐意看见这类的好消息,当自己送出完成工作的信息时,也会很有成就感;没有人会觉得这是很讨厌的报告。 |
每当进度快要落后了,就到我的办公室私下讨论原因,我们一起开动脑筋寻求解决之道。
例如:
当某位程序设计师觉得自己可能要落后了,我会和他谈,研究将来如何避免这种事情。是我们在制定进程时疏漏了某一个重要环节吗?或是时间表定得太乐观了?是不是有个错虫( b u g )在作祟,害得程序很难写或无法测试?不论问题是什么,我们一定想办法解决掉,并且预防它将来再发生。 |
尽可能减少项目中小组彼此间的依赖。
目标越是明确,达成目标的过程就会越有效率。
建立最适当的程序设计优先考虑顺序,并且让所有的程序设计师确实遵守。
排出一个优先级表: - 体积大小(size)
- 速度(speed)
- 坚固性(robustness)
- 安全性(safety)
- 可测试性(testability)
- 容易维护(maintainability)
- 简洁(simplicity)
- 再用性(reusability)
- 可移植性(portability)
|
一旦您掌握了这个概念,把它应用在项目上,您可以大声说自己确实是在聪明地工作,而不是辛苦地工。
一发现Bug就立即清除掉,别拖延。
作者给出的提示:
错虫愈晚清除,时间花得愈多。 在开发的过程就立即除虫,可以让您早些学到经验,然后就不会再犯同样的错误;相反地,如果到了项目后期才发现,您可能已经犯过多次同样的错误而不自知。 发现错虫而立即除错是一种缓冲器,提醒那些讲求快速而不够谨慎的程序设计师,以后多加小心。 若能保持没有任何错虫,您就能比较准确估出项目的完成时间。 要求错虫随时发现随时改,等于是在开发过程中引进一个小小的质量管理机制,多方的防微杜渐,保护产品的正确性。 |
学习前人的经验;
好方法要让大家分享;
项目只要有偏差,就需要调整,绝对不可以放任自流!
定期暂停手边的工作,然后往前思考,随时做必要的修正,以避免未来的大障碍。
有什么事情是我今天能做,而且可以帮助项目在未来几个月内顺利进行的? |
总结本书中的54条法则得到:
- 建议一只和谐的团队;
- 给团队一个明确的目标,让大家都知道这个目标并把它印入脑海;
- 让品保人员明白自己不仅仅是为了Bug而加入团队的;
- 建立合适的检查点和里程碑,并利用检查点和里程碑检验团队的健康度;
- 不要害怕延误,要不断的修正方法但不要过度的修正目标;
- 努力让团队中成员产生共鸣;
希望大家共勉!
法则二十七:
Be like the doctors 用医生的方法
当病人已经药石罔效时,医生通常会对病情有所保留,避免病人太过悲观或恐惧,并且尽量鼓励病人保持希望,最好能让病人有个期望完成的目标。
医生绝对不会斩钉截铁地断言什么医疗行为一定会有什么样的结果,反而是以
一种自在且充满信心的口吻说:“试试看吧,一切都还没有确定呢。
另外一件应该向医生学习的事情是,即使是再小再简单的医疗行为,都带着几分风险,所以医生会说:“当然,任何情况都是有可能的,治愈率再高我都不能跟你说百分之百没问题。
法则二十八:
Remember the triangle:features, resources, times 软件开发金三角:特色、资源和时间
作为一位软件开发的领导人,你得集中注意力在三件事情:资源(人和钱)、特色(产品与其品质)和时间。这三件事是软件开发的核心,其他的都是外围。
资源、特色和时间是三角形的三个边,任何一边的变化,都会影响到另外一边或两边。所以如果时间落后了,去看你的三角形,看看对特色和资源的影响;当有人谈到可以增加什么功能特色时,你得立刻谈起时间和资源,以显得你思虑周
详反应敏捷。所以,管理者的第一要务是把这个三角形放在心里,随时利用这个模式来思考问题,你会发现答案都在这个三角形内。
法则二十九:
Don't know what you don't know 不懂别装懂
法则三十:
Don't go dark 建立适当的检查点
法则三十一:
Beware of a guy in a room 留心没有检查点的组员
法则三十二:
If you build it, it will ship 软件要经常建构,就能顺利推出
法则三十三:
Get a known state and stay there 掌握实际情况
法则三十四:
Use ZD milestones 零缺点里程碑
零缺点不代表软件中没有错虫,也不表示没有遗漏的功能,而是指团队的成品达到了事先规划的品质水准,也经过测试验证,就是零缺点里程碑。
法则三十五:
Nobody reaches the ZD milestone until everybody does 所有组员一起到达零缺点里程碑
法则三十六:
Every milestone deserves a no-blame postmortem 完成每个里程碑后,心平气和地检讨
法则三十七:
Stick to both the letter and the spirit of the milestones 把握里程碑的实质意义与精神
法则三十八:
Get a handle on "normal" 培养正常的团队运作
法则三十九:
A handful of milestones is a handful 里程碑不宜太多,才好掌握
法则四十:
Every little milestone has a meaning (story) all its own 每一个里程碑应有专属的宗旨
法则四十一:
Look for the natural milestones 寻找自然出现的里程碑
以下是六种自然出现的里程碑:
1. 产品设计趋于稳定。
2. 中间产品被明确定义。
3. 团队真正了解要花多少时间和努力才能完成目标(通常这会发生很多次,而且多半是进度落后的时候)。
4. 产品设计被删减,或是资源增加,或是进度延误,
或是三者同时发生。
5. 开发活动停止。
6. 产品进入除错或稳定阶段。
法则四十二:
When you slip, don't fall 如果滑了一跤,别就此倒地不起
- 进度落后与道德无关,请切记!
- 不要隐瞒事实。
- 化阻力为助力,利用进度落后来激发效率。
进度落后不是问题,被进度落后吓倒才是问题。进度落后并不代表产品的难度太高而无法开发。但是如果进度已经落后却未被察觉,那表示组员们不思考、不观察、不讨论,此时组织可说是濒临瓦解了。
善用你的迟延,这是最能看出你领导能力的时候,此时也是组员最脆弱也最需要你的时候,在这个时候组员最能把你的话听进去,此时组员的学习能力最强。如果你在办公室内激动得大喊大叫,指天骂地,那就错失了赢得组员的心的大好机会。你必须说:“O K,进度落后了,让我们来看看问题出在那里?⋯⋯今天下午五点在会议室,我们要检讨每一个细节,问题一定要设法解决!”当组员了解到你不是企图卸责或算帐,而是真诚地想解决问题,就会乐意把一切开诚布公地摊开来谈,大家一起研究问题,从各种角度去设法克服问题。“进度落后”反而变成大家宝贵的成长经验。
法则四十三:
Don't trade a bad date for an equally bad date 不要因为进度落后而更改最后期限
进度落后的程度是与计划的不确定性成正比。
法则四十四:
After a slip, hit the next milestone, no matter what延误了这个里程碑,就一定要如期到达下一个里程碑
我们必须明白,每一次的延误,就是你和团队信心的一次受挫,所以,延误这个里程碑时,最好的补救办法就是无论如何绝不延误下一个里程碑。团队必须挽回对自己的信心和对理想的承诺;因此,下一个任务必须准时完成的意义更重大,团队需要重建信心。
法则四十五:
A good slip is a net positive 把延误当作宝贵的学习机会
法则四十六:
See the forest 见树亦见林
如果本项目有六个模块,各有9 0 %的部分已经完成,那么你已经完成了5 4 %。每个模块完成了九成,听起来是个挺不错的成绩,但不能当成整个项目完成了百分之九十,它们之间不是相加的关系。你必须“见树亦见林”。如果任何一个模块完成比率是零,那么整个项目的完成率也是零。
法则四十七:
The world changes, so should you 世界在变,所以你也得跟着改变
虽然你想做些改变,你未必有勇气实行。
伟大的软件必定只有一个中心思想,至于品质能够实现到什么程度,依赖领导者能否带领团队融合无数个小而重要的改变。如果你能在混乱中辨识出对项目最有意义的改变,并且引导团队去适应它,将它融入团队的精神中,将来就会在产品中表现出这项改变,呈现在顾客眼前。
法则四十八:
Violate at least one sacred cow 关怀多于要求
法则四十九:
Beta is not the time to change Beta测试版不是修改功能的时候
法则五十:
The Beta is for spin development Beta测试是暖身活动
法则五十一:
Triage ruthlessly 急救术
法则五十二:
Don't shake the Jell-0 小心保持软件的稳定
法则五十三:
Compete with the superior story 伟大的软件应该有一个伟大的故事
法则五十四:
Create a winning image 建立赢家形象
我讨论的进度条主要是JFace的进度条,RCP已经提供了完善的Job组件,为什么还要用JFace的进度条呢?原因是我要在登陆界面上做进度处理,也就是使用Eclipse3.3提供的AbstractSplashHandler特性,可以将原有的启动画面替换成为一个登陆界面,启动这个登陆界面时,Eclipse的Platform此时还没有启动,所以不能使用RCP本身的Job组件了。
由于是一个检测服务器是否联通的测试,所以并不知道测试的真实时间,所以就是要使用“傻瓜进度条”了,也就是反复走的进度条陈刚的代码如下:
button.addSelectionListener(new SelectionAdapter() { private boolean stopFlag;// 停止标志 private void go() { for (int i = 0; i < 10; i++) {// 循环10次,每次间隔一秒 System.out.println("第" + (i + 1) + "个任务执行完毕"); if (stopFlag) {// 监控是否要让停止后台任务 System.out.println("被中断了"); return; } try { Thread.sleep(1000); } catch (Throwable t) {} } stopFlag = true;// 执行完毕后把标志位设为停止,好通知给进度框 System.out.println("全部任务执行完毕"); } public void widgetSelected(SelectionEvent e) { stopFlag = false;// 每次都设初值为false new Thread() {// 把后台任务放到一个新开线程里执行 public void run() { go(); } }.start(); showProgressDialog();// 打开一个进度框 } private void showProgressDialog() { IRunnableWithProgress runnable = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { monitor.beginTask("正在执行中......", 30); int i = 0; while (true) { // 监听是否单击了进度框的“取消”按钮,stopFlag则是监听后台任务是否停止 if (monitor.isCanceled() || stopFlag) { stopFlag = true; // 单击了“取消”按钮要设标志位为停止,好通知后台任务中断执行 break;// 中断处理 } // i到30后清零。并将进度条重新来过 if ((++i) == 30) { i = 0; monitor.beginTask("正在执行中......", 30); } // 进度条每前进一步体息一会,不用太长或太短,时间可任意设。 try { Thread.sleep(99); } catch (Throwable t) {} monitor.worked(1);// 进度条前进一步 } monitor.done();// 进度条前进到完成 } }; try { new ProgressMonitorDialog(s).run(true, true, runnable); } catch (Exception e) { e.printStackTrace(); } } }); |
主要是使用两个线程交替使用,第一个线程处理业务,第二个线程监控第一个线程查看它是否结束,如果结束或者被点击cancele则停止进度条的进程,如果一直没有关闭的指令,则反复开始---累加---结束---开始---累加---结束。
我们几乎是把陈刚的代码原原本本的抄袭了一下,仅仅是替换了go()中的内容,但是发现一个问题
new ProgressMonitorDialog(s).run(true, true, runnable);
使用此句的话,JFace的线程永远不会启动;
替换为
new ProgressMonitorDialog(s).run(false, true, runnable);
使用此句的话,JFace的线程可以启动,运行正常,但是cancele不能响应,UI界面完全卡死!
第一个参数的名字fork~乍看去,什么意思都没有,但是看看API才发现内藏很大的玄机,如果为true则此线程为一个非UI线程,大家知道非UI线程是不会阻塞UI的;如果为false则此线程为一个UI线程,大家也知道UI线程如果使用不当很容易阻塞UI的。
关键的问题是我们和陈刚的代码几乎一摸一样他的进度条就启动,我的进度条就不启动!为什么?(这点至今不明白!)
详查API发现如果fork为false的时候还是另有洞天的:
This implementation of IRunnableContext#run(boolean, boolean, IRunnableWithProgress) runs the given IRunnableWithProgress using the progress monitor for this progress dialog and blocks until the runnable has been run, regardless of the value of fork . The dialog is opened before the runnable is run, and closed after it completes. It is recommended that fork is set to true in most cases. If fork is set to false , the runnable will run in the UI thread and it is the runnable's responsibility to call Display.readAndDispatch() to ensure UI responsiveness. |
API中说的很明白,如果fork为false时需要在线程中调用Display.readAndDispatch()方法,以避免UI被阻塞!
大家如果在JFace的开发中如果使用了进度条,发现UI被阻塞的话,就想想我哦!!!呵呵只用在进程中调用一下Display.readAndDispatch()就解决了!
设计
软件的设计─每一位团队成员都必须参与─这表示团队整体对功能需求的了解程度。
软件设计的第一要诀是:将全团队中最好的想法组织起来,去满足顾客内心最深处的需要。(带领团队做案例研讨,带领大家思考如何解决一切的疑难,让每一件事都在该做的时候做好。)
法则十九:
Go for greatness 追求卓越
法则二十:
State your theme 设定主题
重点是产品的功能特色不能像是一袋子随便抓过来的东西,应该把与主题无关的东西都删掉,而且你的目标也必须符合统一性(unity of purpose)才行,这一点是与主题互为一体的两面。将资金投注在这个目标上,让所有的人都完全明白这个目标,并且为这个目标努力,做得到这些的话,你的产品就会完全包含这个目标。
法则二十一:
Minimize dependencies 不要倚赖不确定的事
法则二十二:
Propitiate the gods 平息顾客的愠怒
法则二十三:
Portability is for canoes. 软件的可移植性
法则二十四:
Design time at design time 在设计时将时间因素考虑在内
开发
法则二十五:
Don't accept dictation 拒绝不合理的命令
千万不要一味的唯命是从,在必要的时候拒绝!敢于拒绝!
如果在上位者不让真正执行任务的人来估计所需的进度,那就是专制。
开发进度表应该由下而上来拟定,每一个人负责自己的工作,也负责设定它的时间表,负责准时完成工作。责任和充分授权是一体的两面,二者兼备才能拟出合理的开发计划。一种非常有趣的进度估算方法!
法则二十六:
Now go play 把工作当作游戏吧
法则六:
Watch the ratio 注意人员的组成比例
“基本原则是开发人员和品保人员的比例不超过2:1”这个是作者为我们提出的建议,而在SUN这个比例被修改为1:1,甚至是1:2,可见在项目中品保人员比开发人员更加重要!
“其实真正负责软件如期完成的是品保人员。当进度落后时,我们第一个要看的是品保人员:人数够不够?有没有充分授权?有没有确实参与设计?进度上能不能跟开发人员配合良好?能不能一有问题出现就立刻提出警告?品保人员和开发人员的理念一致吗?是不是跟开发人员过度亲密而放水?”
“一个健全的软件开发团队一定要符合上述的人数比例原则,平均每一位品保人员所支援的开发人员不超过两位。”能做到吗?至少在我们公司这个,基本上,很难!
法则七:
Use feature teams 运用特色监督小组
融入任务(I d e n t i t y) 充分的授权和责任感,使人具有控制权和影响力,愈能使自己与任务融为一体。
建立共识(C o n s e n s u s) 共识是特色监督小组的气氛。
地位平等(B a l a n c e) 由于特色监督小组的每一位成员都是不同的背景、专长,不同的工作角色和不同的观念,没有谁比谁优越的情形,所以每个人的地位都是平等的。
权威是来自学识,而非职位。
在一个理想的项目中,基本上有两种角色存在:创造者(c r e a t o r)和推动者(f ac i l i t a t o r)。创造者是一些专业人员,例如开发程序、行销、软件品保和文件撰写;而推动者则负责凝聚团队共识和维持最佳的开发环境。
法则八:
Use program managers 项目经理的职责
项目经理是软件开发团队的一份子,他的职责是:
• 领导大家定义出一个成功的产品。
• 引导大家对产品注入深切的期望和信念。
• 带领团队将理想实现,变成可预见的产品诞生。
项目经理应该要有技术的背景,而且必须在两种层面非常专精:一是对开发产品所使用的技术很熟悉,二是拥有建构软件的技术领导能力。项目经理必须精于哄骗、驱策、鼓励、要求他的团队做出最好的软件和表现出最好的工作效能,他清楚知道软件制作过程中每一项的投入和产出细节,他必须懂得用最好的方式定义产品和维持健全的技术。最后,项目经理还必须是团队的发言人,面对媒体、客户、以及整个组织。
项目经理是软件开发的核心人物。
你想了解这个团队?看看他们的软件就知道了,反之亦然。
团队精神:
1. 一群人同心协力,集合大家的脑力,共同创造一项智能财产。
2. 个人的创造力是一种神奇的东西,源自于潜在的人类心智潜能,它被情感丰富,而被技术束缚。
3. 一群人全心全意地贡献自己的创造力,结合成巨大的力量。结合的创造力由于这一群人的互动关系、彼此激荡,而更加复杂。
4. 这种复杂的情况之下,领导变成像是人际互动的交响乐指挥,辅助并疏导各种微妙的人际沟通。
5. 在团体中的沟通和互动是正确而健康时,能够使这一群人的力量完全结合,会产生相加相乘的效果,抵销互斥。沟通顺畅能使思想在团队中充分交流传达。
6. 团队工作的品质比时程更重要,而作品的伟大是需要对“团队精神”特别加强,才能达成。“团队精神”可视为个别成员精神的平均值,而个人的精神( p s y c h e)则是使他能感觉、能思考、能推论的内在力量。
7. 倘若忽视了“团队精神”,则只会有平庸的成果。
法则九:
Be an authority , not an authority figure 要权威,不要霸权
权威的目的是让每一位团队成员都有自己的专业权威,和团队的专业自信,这才是管理者真正的权威。
竞争
创新无处不在,绝对不可以停滞不前!
如果你无法时时掌握时代的脉搏,如果你怠于响应周围迅速而剧烈的变化,特别是竞争者的行动,如果你不能持续地创新原有的技术,永远保持领先,那么别人马上就会趁虚而入,取代你而成为市场上的优胜者,掳获顾客的心和他们的荷包。
确定了你的情况之后,应该先考虑采取标准步法。
标准步法:
法则十:
Alone? A market without a competitor ain't 没有竞争对手?未必是好事
(注:任何人都有敌人!)
法则十一:
Dead beat? Break out of a feature shoot-out 竞争者紧追不舍?推出创新的功能特色(注:想法设法的压制你的敌人!)
法则十二:
Behind? Ship more often with new stuffs 落后竞争对手?加大投入,更快推出新版本(注:沉下心来,夺回领地!)
法则十三:
Ahead? Don't ever look back 领先竞争对手?不要回头(注:挑战自己,战胜自己!)
准时地、经常地推出新产品是软件开发产业中最大的金科玉律。
法则十四:
Take the Oxygen along 保持新鲜
快速变迁的节奏是信息社会的常态,你必须快速前进,否则就落伍了。
顾客
想方设法的让顾客迷恋上你的产品!
法则十五:
Enrapture the customer 给顾客惊喜
顾客最低的希望是你能够理解他所感受到的痛苦经验。
法则十六:
Find the sweet spot 寻找靶心
法则十七:
It's a relationship, not a sale 与顾客建立关系,而不是卖产品
法则十八:
Cycle rapidly 加速产品推出的周期
带过项目的朋友一定都看过或者听说过这本书吧,其实这本书是来自“微软管理经典著作”之中的一本,其他两本是《微软项目:求生法则》、《微软研发:制胜策略》这三本书我会精读细读的(虽然我不带项目~),从中取其精华写成笔记与大家分享。
首先看一下《微软团队:成功秘诀》分别在china-pub和豆瓣上的书评把:
china-pub
本书叙述了吉姆.麦卡锡带领微软Visual C++开发团队的故事,告诉读者如何构建一个优秀的软件开发团队,如何在一段时间内成功地开发一个软件,而且此后不断地完成新版,并一直受到市场的肯定。他将自己思考的结晶和种种惨痛的教训归纳出54条言简意赅的法则,从产品设计、程序开发到成功的营销,无所不包,在微软,本书是每一位项目经理的必读圣经。 |
豆瓣
作为一位经验丰富的老手,作者将自己思考的结晶和种种惨痛的教训归纳出54条言简意赅的法则,从产品设计、程序开发与构建、准时推出产品,到成功的营销,无所不包。您将会发现本书就像软件开发本身一样迷人有趣。本书是为软件设计者、开发人员、营销人员、技术主管,以及所有亟欲一窥软件开发奥秘的人士所写的。
|
法则一:
Establish a shared vision 建立一个共同的目标
在团队总建立共同的目标是非常重要的,团队中的成员只有当有了共同的目标之后才能有归属感,才能对憧憬中的产品产生荣誉感,才能在管理中更好的调动各个成员的积极性,从而将团队推向正轨,让产品如期发布!
“团队中每一位成员都必须非常清楚我们要做什么、成品会是什么模样、基本的产品策略是什么、什么时候必须完成。凡是与共同目标相冲突的看法都必须转化成一致,而不是把它消音。和谐的共识是绝对必要的,否则软件不可能做得好,很多事会复杂化而难以收拾。”
所谓目标是共同的希望,对未来的事情所描绘出来的景象,比方说作者在给VC++项目组开会时候的描述“Visual C++是最伟大、最值得骄傲的产品,你们难道不这么认为吗?我知道我们可以如期完成它,而且用它来给对手一个迎头痛击,不只我一个人这么想吧?我们将创造微软的明日世界,我们会大有作为的,不是吗?”其实他已经给VC++了一个很好的目标,他让成员们觉得,我们都是在伟大事情,一但在团队中形成了荣誉感,你会发现你的团队将会空前的团结!
法则二:
Get their heads into the game 使大家主动投入
“如果每个人都在认真思考如何使团队更有效率,这个团队自然就比较容易表现出高效率,反之亦然。”让每一个人都参与进来,需要管理者能够调动每一个人的积极性~让大家都主动的去思考问题,为产品主动的出谋划策。
需要管理者去倾听每一个愿意说的成员的言论或者主意,需要判断的这些言论或者主意的能力,面对好的想法,也许它不切实际,但是也不要一棒子打死,而是要进行诱导,让他下次可以提出更好的更切实际的想法来。
鼓励创新而非抹杀它!
为什么组员会怠于思考或是不敢说出想法?
• 因为他们认为没有人会重视他的想法。
• 因为他们认为该由别人告诉他该做什么事。
• 因为他们认为这样做没有什么好处,只会使老板皱眉头罢了。
• 管理者只管发号施令而已。
法则三:
Create a multi-release technologyplan 建立开发多版本的技术规划
授权共决,其实就是全民参与,无论是对待成员的新想法还是对待项目的技术规范时都使用全民参与。(这样好吗?安全吗?)
法则四:
Don't flip the bozo bit 别做笨蛋
软件产业中最重要的事情是“让大家思考!”。
“在微软我们把这种人叫作b o z o,意思是笨蛋。永远没有人会注意笨蛋的所作所为,即使他真的有贡献,他也不会有任何份量。笨蛋当然是不可信任的,你对笨蛋惟一的期望是但愿他不要搞砸事情。
在我的部门里,这种德行是不允许的。我要每一个人都全心全力地投入,每个人都得有贡献,每一个人都可以侃侃而谈我们的产品─如何在市场上竞争、何时出新版本等等,而且每个人对产品的看法都一致,不会众说纷云。
将自己的意见强行加诸于他人者,其实是笨蛋。”
需要随时防范组员出现“江郎才尽”病!
法则五:
Use scouts 刺探敌情
必须有一个人或者有一些人去观察未来的发展趋势,预言新技术。这个角色是非常重要的!
“这次他们学乖了,事先派了两位最优秀的组员担任“侦察员”,做了一次彻底的技术调查和完善的规划,终于在危机爆发之前将之化解。”
““侦察员”就是为科技的改变而准备的,如果你决定永远停着不动,那你不需要“侦察员”。”软件公司中如果没有这个角色还叫软件公司吗?
VE在Eclipse的众多项目中沉寂了一年的时间,现在终于有动作了!至少是计划已经放出了~真是让人欣慰啊!
我每天都要看Eclipse的各大新闻组,VE虽然说是沉寂了一年,但是新闻组里面还是比较热闹的,每天都有一两篇问题更新。
Visual Editor Project 2007-2008 Roadmap
Project focus
In general, the main theme is to get the project back on track and in good shape.
From a goals perspective, we have the following alternatives:
-
- focus exclusively on Swing, SWT and RCP and do it extremely well; deprecate everything else.
- continue to provide a more generic editing framework, and supporting visual editing of non-java target such as GWT, HTML, Groovy, XForms, Web pages, EXSWT, etc.
My head tells me to go with (1) and my heart with (2).
Release Timeline
- VE 1.3.0 Milestone 1:
- Q1 2008, have a stable working VE based on Europa
- VE 1.3.0 Milestone 2: Q2 2008
- Investigate performance enhancements (single VM)
- Fix major bugs
- Add support for non Java visual target (Groovy contribution, XForms)
- VE 1.3.0 Release: Q2 2008
- VE 1.3.1 : maintenance for 1.3.0 Q3 2008
- VE 1.3.2 : maintenance for 1.3.0 Q4 2008
- VE 1.4.0 Milestone 1: Q2 2008
- Work on Ganymede compatibility
- VE 1.4.0 Milestone 2: Q3 2008
- VE 1.4.0 Milestone 3: Q3 2008
- VE 1.4.0 Release: Q4 2008
Retrieved from "http://wiki.eclipse.org/VE/Roadmap"
我最期待的还是VE对于生成XML文件的扩展~加油啊~VE!
有朋友在blog中给我留言,说找到RAP的官方地址,现在我就在此公布一下,有兴趣的朋友可以去看看Demo。
官方首页
http://www.eclipse.org/rap/
Demo地址
http://www.eclipse.org/rap/demos.php 此页面提供3个Demo,其中的SWT的官方Demo的RAP实现在RAP的发行包中,自己下载下来,自己RUN起来就能看到了;
RAP开发领头公司
Innoopract 从开发人员列表和官方网站的支持力度上,此公司最强!(好像是家德国公司!) 1&1 CAS
I impleted my File upload/download system with rap internal Browser + servlet.
upload dialog:
public class FileUploadDialog extends TitleAreaDialog {
private Browser browser;
public FileUploadDialog(Shell parentShell) {
super(parentShell);
}
/**
* Create contents of the dialog
* @param parent
*/
@Override
protected Control createDialogArea(Composite parent) {
Composite area = (Composite) super.createDialogArea(parent);
Composite container = new Composite(area, SWT.NONE);
container.setLayout(new FillLayout());
container.setLayoutData(new GridData(GridData.FILL_BOTH));
browser = new Browser(container, SWT.NONE);
String url = "http://"+RWT.getRequest().getServerName()+":"+RWT.getRequest().getServerPort()+"/web/fileupload.jsp";
String html = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><html><head><title>upload file</title></head><body>"+
"<form action=\""+url+"\" enctype=\"MULTIPART/FORM-DATA\" method=\"post\"><br />File Name:</br><input type=\"file\""+
" name=\"filename\"/><br><input type=\"submit\" value=\"upload\"/></form></body></html> ";
browser.setText(html);
setMessage("select a local file");
return area;
}
/**
* Return the initial size of the dialog
*/
@Override
protected Point getInitialSize() {
return new Point(382, 280);
}
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText("upload file");
}
}
file upload sevlet:
public class FileUploadServlet extends HttpServlet {
private static final long serialVersionUID = -7245361228773015964L;
private String uploadPath = "/upload/"; // server file repository
private String tempPath = "/upload/tmp/"; //temp file folder
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
try {
DiskFileUpload fu = new DiskFileUpload();
// max file size fu.setSizeMax(-1);
// buffer size
fu.setSizeThreshold(4096);
// temp path
fu.setRepositoryPath(tempPath);
// get all uploa file
List fileItems = fu.parseRequest(request);
Iterator i = fileItems.iterator();
while (i.hasNext()) {
FileItem fi = (FileItem) i.next();
// get the upload file name
String fileName = fi.getName();
String sep = System.getProperty("file.separator");
int index = fileName.lastIndexOf(sep);
if(index >-1){
fileName = fileName.substring(fileName.lastIndexOf(sep));
}
fi.write(new File(uploadPath + fileName));
response.getWriter().println(fileName+"upload success");
}
} catch (Exception e) {
//do something?
e.printStackTrace();
}
}
public void init() throws ServletException {
if (!new File(uploadPath).isDirectory())
new File(uploadPath).mkdirs();
if (!new File(tempPath).isDirectory())
new File(tempPath).mkdirs();
}
}
registe servlet:
public class HttpServiceTracker extends ServiceTracker {
public HttpServiceTracker(BundleContext context) {
super(context, HttpService.class.getName(), null);
}
public Object addingService(ServiceReference reference) {
final HttpService httpService = (HttpService) context
.getService(reference);
try {
//regist file upload servlet
HttpContext commonContext = new BundleEntryHttpContext(context
.getBundle(), fileFolder);
httpService.registerResources(fileContext, "/", commonContext);
Servlet adaptedJspServlet = new ContextPathServletAdaptor(
new FileUploadServlet(),
fileContext);
httpService.registerServlet(fileContext + "/fileupload.file",
adaptedJspServlet, null, commonContext);
} catch (Exception e) {
e.printStackTrace();
}
return httpService;
}
public void removedService(ServiceReference reference, Object service) {
final HttpService httpService = (HttpService) service;
httpService.unregister(fileContext);
httpService.unregister(fileContext + "/fileupload.jsp");
super.removedService(reference, service);
}
}
start servlet:
add these code to the bundle start up method.
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
httpServiceTracker = new HttpServiceTracker(context);
httpServiceTracker.open();
System.out.println("IM resource servlet started...");
}
这个实现是在RAP中使用Browser+servlet实现的文件上传功能;
其实在RAP的cvs上已经放出了org.eclipse.rwt.widgets.upload,专用于上传的组件,测试了一下,效果还不错,有进度条提示;不过在IE6下,有点难看了,在FF3下不能使用;
Eclipse-RAP项目真的可以算是Eclipse-RCP开发者的福音,一套软件的开发成本,两套软件的特性~对于正在寻求C/S向B/S转移的公司来说,可以算是一个福音了。
公司最近正在做调整,打算将原有7大软件产品,在B/S上重新打造一番~前景很不错,市场价值非常大~我们所关心的并不是市场价值究竟有多大(有上面的大领导撑着,我们不用担心),我们关心的是,如何打破原有的B/S开发模式,让程序员们能高速的开发出需要系统,而且这些系统又能遵守共同的特点,原有的B/S开发模式只可能让程序员原来越不OO了,很有可能陷入JS的陷阱中。
我们把目光转移到了GWT上,他确实可以让JAVA开发人员只专注的写JAVA就可以了,一切都是它的事情了~但是最麻烦的事情,就是速度问题,编译的时候很慢,而且还提出了模块的概念,不好理解,放弃它的另一个最重要的原因是它并不是一个框架,只是一个工具集而已。
然后,我们发现了RAP-Rich Ajax Platform,从它的首页上并看不出什么特别,但是深入Demo,才真的发现别有洞天啊~原来一切来的都是那么简单~~~~它其实就是依照与Eclipse-RCP的基础运行时做了一套自己的基础运行时RAP,换句话说就是原本开发好的RCP项目,可以在仅增加一个扩展点的基础上,平滑的过度到RAP上,立即从一个C/S程序变成了一个B/S程序~真的很令人震惊!今天早上和同事配合,将我们几个月前做的4个插件,用了一早上的时间迁移到RAP上,几乎原有功能完全保留!
如果你也是用RCP做开发的话,建议你可以试试RAP,它会给你一想不到的体验!
需要注意的是,RAP是去年10月份才正式发布的1.0版本,所以还是有很多东西是没有,还是需要一段时间的等待,特别是在1.1发布后,几乎支持所有SWT的特性了~
为了深入的讨论RAP,我已经开放了Eclipse-RAP分类,慢慢会有更多的关于RAP的文章出现,努力丰富一下RAP的中文文档!