設計
軟件的設計─每一位團隊成員都必須參與─這表示團隊整體對功能需求的了解程度。
軟件設計的第一要訣是:將全團隊中最好的想法組織起來,去滿足顧客內心最深處的需要。(帶領團隊做案例研討,帶領大家思考如何解決一切的疑難,讓每一件事都在該做的時候做好。)
法則十九:
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,分析了上面的四種狀態,那么我們來確定我們需要做成什么樣子的~首先,我們需要;
必填提醒狀態
填寫正確提醒狀態
錯誤填寫提醒狀態
還有就是鼠標移動到三種圖標上的浮動框詳細說明,因為我們不可能像淘寶那樣,一個控件占那么大位置,用戶界面還需要放更多的東西。
大致的任務交代清楚了,下一次再寫詳細的實現過程。