设计
软件的设计─每一位团队成员都必须参与─这表示团队整体对功能需求的了解程度。
软件设计的第一要诀是:将全团队中最好的想法组织起来,去满足顾客内心最深处的需要。(带领团队做案例研讨,带领大家思考如何解决一切的疑难,让每一件事都在该做的时候做好。)
法则十九:
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的中文文档!
2007年10月份eclipse放出RAP-Rich Ajax Platform,这么长的时间过去,它的影响力还是不够~为什么,因为它的文档太少,资源太少,知道的人更少~
昨天,把玩了一下RAP,被它的思想震惊了~它是把Eclipse-RCP的思想带入了B/S的开发,它提供的不仅仅是Ajax的内容,更多的是提供了一个框架,一个可以同Eclipse-RCP框架互换的框架~
中规中矩开发好的RCP程序,可以在几乎不用改动任何代码的基础上增加2项配置,一个类以及一个底层框架,就可以完全过度到B/S上~
我们的项目,用了半个小时改造完成的~
RCP+RAP也许是一个新的方向~
摘要: 上次贴了几张图片出来显摆,这次彻底公布代码~大家看看原理就好,有兴趣的朋友可以和我联系,把SWT里面的控件都封装一下,做一套验证框架出来~
1package com.glnpu.dmp.controls;
2
3import org.eclipse.swt.SWT;
4imp... 阅读全文
为什么要打造仿淘宝注册的Text呢,不为什么,因为它好看!呵呵,这个不算理由,其实最重要的原因是因为最近在开发过程中,发现验证是个最麻烦的事情,虽然Eclipse和JFace为我们已经提供了比较好用的“高级”对话框和向导页了,对于简单的应用,他们两个用起来是非常简单,如果要验证的东西非常多,而且还有交叉验证(我自己起的名字,就是填了A就不再验证BCD的错在了,或者填了C就要验证AD存在)处理起来了就麻烦了,前两天以为新同事接手一端代码,发现里面竟然有20+个监听器,验证逻辑复杂的要死~为了解决这个问题。再结合B/S的开发经验,我认为,完全没有必要当用户把所有的必填项全都填了以后再把OK按键打开,不然永远置灰~大家做过的哪个B/S程序是这样的?不都是他爱填填,不爱填拉到,点确定的时候我告诉,或者是,我以上来就告诉你哪些必填,不填的,点击确定继续提醒!
OK,闲话少说,先看看淘宝的注册吧~我一直认为淘宝的注册界面是国内客户体验度最好的~
首先界面一打开就是这样的提示,在input框的左下脚又一个蓝色的小箭头,代表此文本框必填;
当获得焦点以后改变,后面的提示框高亮,着重提醒用户;
如果没有填,必填项,提交的时候的提示;
填写正确的提示;
OK,分析了上面的四种状态,那么我们来确定我们需要做成什么样子的~首先,我们需要;
必填提醒状态
填写正确提醒状态
错误填写提醒状态
还有就是鼠标移动到三种图标上的浮动框详细说明,因为我们不可能像淘宝那样,一个控件占那么大位置,用户界面还需要放更多的东西。
大致的任务交代清楚了,下一次再写详细的实现过程。