2006年11月25日

          剛剛看到有個(gè)哥們兒講他的客戶讓他很郁悶,我有點(diǎn)想法,整理如下:

          首先,我覺(jué)得開(kāi)發(fā)人員遇到這樣的郁悶是因?yàn)榭刂菩枨笞兏Ψ驔](méi)有做足。原因有幾點(diǎn):
          1.涉及需求變更的東西不應(yīng)該由最終使用的用戶和一線開(kāi)發(fā)人員來(lái)溝通,這樣的溝通費(fèi)時(shí)費(fèi)力而且不具有權(quán)威性。
          2.開(kāi)發(fā)人員直接向客戶匯報(bào)的工作量往往比實(shí)際工作量要低,而且低的比較多。原因很簡(jiǎn)單:客戶問(wèn)開(kāi)發(fā)人員一個(gè)功能是否困難的時(shí)候,一般技術(shù)人員往往只考慮了單項(xiàng)功能的復(fù)雜度,而可能對(duì)這個(gè)需求變更對(duì)整個(gè)系統(tǒng)的工作量估計(jì)不足(比如美工的工作量、該功能引發(fā)的管理功能的工作量、測(cè)試工作量等等)。
          這種情況會(huì)對(duì)項(xiàng)目產(chǎn)生多個(gè)負(fù)面影響:a.向客戶提供一個(gè)低于實(shí)際值的工作量,導(dǎo)致客戶期望高,而實(shí)際無(wú)法按時(shí)完成導(dǎo)致客戶失望大,降低用戶滿意度。b.因?yàn)榭蛻魪拈_(kāi)發(fā)人員口中聽(tīng)到的工作量總是比從項(xiàng)目經(jīng)理口中聽(tīng)到的工作量低,造成客戶對(duì)項(xiàng)目組內(nèi)部不一致,溝通不足的感覺(jué)。c.因?yàn)榭蛻魪拈_(kāi)發(fā)人員口中聽(tīng)到的工作量總是比從項(xiàng)目經(jīng)理口中聽(tīng)到的工作量低,引誘客戶喜歡直接向開(kāi)發(fā)人員提出需求變更,造成惡性循環(huán),直接導(dǎo)致了項(xiàng)目組沒(méi)法按時(shí)拿到獎(jiǎng)金,士氣下降。

          所以對(duì)于客戶提出的需求變更,一般技術(shù)人員最好的處理方式是:委婉的告訴客戶,這個(gè)問(wèn)題需要項(xiàng)目經(jīng)理來(lái)評(píng)估。哪怕用戶用挑釁、教訓(xùn)的語(yǔ)氣和你講這個(gè)功能如何簡(jiǎn)單,如何如何就可以實(shí)現(xiàn),你都不能告訴他是否可以接受這個(gè)變更,更不能說(shuō)實(shí)現(xiàn)需要多長(zhǎng)時(shí)間。
          拒絕了客戶之后并不是大功告成,你最好能夠早于客戶通知自己的項(xiàng)目經(jīng)理,客戶想進(jìn)行怎樣的需求變更,你自己對(duì)工作量的評(píng)估是怎么樣的。這樣可以給項(xiàng)目經(jīng)理一個(gè)準(zhǔn)備時(shí)間,來(lái)完善的考慮需求變更的影響。

          對(duì)于項(xiàng)目經(jīng)理,尤其是從開(kāi)發(fā)一線轉(zhuǎn)向做項(xiàng)目經(jīng)理的兄弟,應(yīng)該主動(dòng)的從項(xiàng)目全局來(lái)考慮一個(gè)變更的影響,而不是單純從技術(shù)角度考慮。最好能按照公司的規(guī)范和制度以及項(xiàng)目實(shí)際情況為自己積累一份check list,以免在考慮需求變更時(shí)遺漏一些事項(xiàng)。作為開(kāi)發(fā)方更要強(qiáng)化對(duì)于需求變更的控制。
          控制需求變更最理想的辦法當(dāng)然是由客戶方、開(kāi)發(fā)方的項(xiàng)目經(jīng)理和需求顧問(wèn)共同組織CCB(變更控制委員會(huì))
          ,文檔化所有需求變更,雙方簽字然后歸檔需求變更。不過(guò)這樣比較難以實(shí)現(xiàn)。但是最起碼的要求是,必須由客戶方項(xiàng)目經(jīng)理(也就是甲方最終用戶需要把需求變更匯總報(bào)告給甲方項(xiàng)目經(jīng)理)向開(kāi)發(fā)方項(xiàng)目經(jīng)理提出需求變更,開(kāi)發(fā)方項(xiàng)目經(jīng)理評(píng)估工作量,并文檔化需求變更,在與客戶方負(fù)責(zé)人充分溝通后,使用正式方式將溝通結(jié)果(最好是打印出來(lái)給甲方簽字,最起碼是要求回執(zhí)的電子郵件)通知客戶。必要的時(shí)候需要業(yè)務(wù)人員協(xié)助,比如要求簽署附加合同或者新開(kāi)一個(gè)項(xiàng)目等等。

          從我做項(xiàng)目幾年的經(jīng)驗(yàn)來(lái)看,蠻不講理的客戶不是沒(méi)有,但是是極少數(shù),大多數(shù)客戶,尤其是客戶方項(xiàng)目經(jīng)理都是通情達(dá)理的人。所以,只要你言之有理,對(duì)方都有可能接納。

          posted @ 2006-12-05 17:07 iceboundrock 閱讀(1905) | 評(píng)論 (12)編輯 收藏

          C++ C#/java 有很多區(qū)別,其中最大的區(qū)別當(dāng)數(shù)對(duì)內(nèi)存的管理。

          C++ 中,類的使用者決定了類的實(shí)例內(nèi)存會(huì)如何分配,分配在堆上還是棧上。我們先看一段例子程序:

          ?

          #include "stdio.h"

          ?

          class Demo{

          public :

          ??? int i;

          ??? char* objName;

          ??? Demo(){

          ??????? objName = "Default object.";

          ??????? printf("%s, objName = %s\r\n", "Enter Demo default ctor. method.", objName);

          ???????

          ??????? i = 1000;

          ??? }

          ?

          ??? Demo(int ival, char* name){

          ??????? printf("%s,i = %d, objName = %s\r\n", "Enter Demo(int ival) ctor method", ival, name);

          ??????? i = ival;

          ??????? objName = name;

          ??? }

          ?

          ??? Demo(const Demo& d){

          ??????? printf("%s\r\n", "Enter Demo copy ctor method.");

          ??????? i = d.i;

          ??????? objName = "copied d";

          ??? }

          ?

          ??? ~Demo(){

          ??????? printf("%s, i = %d, objName = %s\r\n", "Enter Demo dector. method" , i, objName);

          ??? }

          };

          ?

          Demo& testMethod0(){

          ??? printf("%s\r\n", "Enter testMethod0.");

          ??? Demo d(0, "d in testMethod0");

          ??? printf("%s\r\n", "Exit testMethod0.");

          ??? return d;

          }

          ?

          Demo testMethod1(){

          ??? printf("%s\r\n", "Enter testMethod1.");

          ??? Demo d(1, "d in testMethod1");

          ??? printf("%s\r\n", "Exit testMethod1.");

          ??? return d;

          }

          ?

          Demo* testMethod2(){

          ??? printf("%s\r\n", "Enter testMethod2.");

          ??? Demo *d = new Demo(2, "d in testMethod2");

          ??? printf("%s\r\n", "Exit testMethod2.");

          ??? return d;

          }

          ?

          int main(int argc, _TCHAR* argv[])

          {

          ??? Demo d;

          ??? d = testMethod1();

          ?

          ??? Demo& d1 = testMethod0();

          ?

          ??? Demo d2(999, "d1");

          ?

          ??? Demo* d3 = testMethod2();

          ?

          ??? printf("d.i = %d\r\n", d.i);

          ??? printf("d1.i = %d\r\n", d1.i);

          ??? printf("d2.i = %d\r\n", d2.i);

          ??? printf("d3.i = %d\r\n", d3->i);

          ?

          ??? delete d3;

          ??? return 0;

          }

          ?

          Output

          Enter Demo default ctor. method., objName = Default object.

          Enter testMethod1.

          Enter Demo(int ival) ctor method,i = 1, objName = d in testMethod1

          Exit testMethod1.

          Enter Demo copy ctor method.

          Enter Demo dector. method, i = 1, objName = d in testMethod1

          Enter Demo dector. method, i = 1, objName = copied d

          Enter testMethod0.

          Enter Demo(int ival) ctor method,i = 0, objName = d in testMethod0

          Exit testMethod0.

          Enter Demo dector. method, i = 0, objName = d in testMethod0

          Enter Demo(int ival) ctor method,i = 999, objName = d1

          Enter testMethod2

          Enter Demo(int ival) ctor method,i = 2, objName = d in testMethod2

          Exit testMethod2.

          d.i = 1

          d1.i = -2

          d2.i = 999

          d3.i = 2

          Enter Demo dector. method, i = 2, objName = d in testMethod2

          Enter Demo dector. method, i = 999, objName = d1

          Enter Demo dector. method, i = 1, objName = copied d

          ?

          C# 不同,在 C++ 中,對(duì)象聲明的時(shí)候就已經(jīng)執(zhí)行了構(gòu)造函數(shù),比如上面例子的 main 函數(shù)中的第一行, Demo d ,從屏幕上的輸出來(lái)看,這個(gè)時(shí)候 Demo class 的默認(rèn)構(gòu)造函數(shù)會(huì)被調(diào)用。

          接下來(lái)的一行代碼調(diào)用,引出了很有趣的情況,當(dāng)然也隱藏著不小的問(wèn)題。這行代碼造成了一次構(gòu)造函數(shù)調(diào)用,一次拷貝構(gòu)造函數(shù)調(diào)用和兩次析構(gòu)函數(shù)調(diào)用。讓我們來(lái)具體分析一下:第一次調(diào)用構(gòu)造函數(shù)很容易理解,因?yàn)樵?/span> testMethod1 中我們聲明了 Demo d(0) ,退出 testMethod1 ,函數(shù)的返回值要賦值給變量 d2 ,這個(gè)時(shí)候, d2 被拷貝構(gòu)造函數(shù)重新構(gòu)造了一次。接著 testMethod1 中構(gòu)造的局部變量被析構(gòu),然后,居然拷貝構(gòu)造函數(shù)構(gòu)造的對(duì)象也被析構(gòu)?等等,看完所有輸出,我們發(fā)現(xiàn), objName = copied d 的對(duì)象被析構(gòu)兩次,而 objName = Default obj 的對(duì)象被構(gòu)造出之后沒(méi)有被析構(gòu),這里隱藏了很嚴(yán)重的問(wèn)題,有可能導(dǎo)致內(nèi)存泄漏、句柄不能被正確關(guān)閉等等。另外,拷貝構(gòu)造函數(shù)的執(zhí)行可能導(dǎo)致潛在的效率問(wèn)題,考慮一個(gè)包含巨大矩陣的對(duì)象, copy 這個(gè)對(duì)象會(huì)怎么樣?

          ?

          接下來(lái)的一行代碼, testMethod0 返回一個(gè)對(duì)象的引用,當(dāng)然不會(huì)導(dǎo)致拷貝構(gòu)造函數(shù)被調(diào)用,但是,這樣也是有問(wèn)題的,在函數(shù)中聲明的局部變量在函數(shù)執(zhí)行完成的時(shí)候會(huì)被析構(gòu),那么直接返回局部變量就可能會(huì)出現(xiàn)問(wèn)題。 testMethod0 退出以后,他內(nèi)部的 Demo 對(duì)象就會(huì)自動(dòng)析構(gòu),外面對(duì)它的引用當(dāng)然也無(wú)法指向正確的對(duì)象了,所以后面程序打印 d.i 的時(shí)候,輸出了一個(gè)莫名其妙的 -2 。

          ?

          效率最好的方法當(dāng)數(shù)返回指針了,它不會(huì)導(dǎo)致對(duì)象復(fù)制,如果使用得當(dāng),也不會(huì)導(dǎo)致內(nèi)存泄漏或者句柄泄漏。 testMethod2 演示了這種情況,當(dāng)然,你需要手工刪除在 testMethod2 中創(chuàng)建的對(duì)象。

          ?

          ?

          posted @ 2006-11-25 16:08 iceboundrock 閱讀(643) | 評(píng)論 (1)編輯 收藏


          posts - 10, comments - 15, trackbacks - 0, articles - 0

          Copyright © iceboundrock

          主站蜘蛛池模板: 临朐县| 赤城县| 来宾市| 镶黄旗| 江达县| 南川市| 韩城市| 安吉县| 安多县| 界首市| 筠连县| 廊坊市| 金门县| 汝州市| 炉霍县| 吉首市| 孝昌县| 湛江市| 思南县| 襄城县| 通河县| 泰安市| 紫金县| 铁岭市| 报价| 浦县| 宁国市| 新绛县| 南木林县| 横山县| 博兴县| 郴州市| 平乡县| 临桂县| 黄骅市| 南城县| 南川市| 巍山| 宁化县| 丰原市| 杭锦旗|