亚洲精品乱码久久久久蜜桃-97国产精品人妻无码久久久-加勒比中文字幕无码一区-中文字幕乱人伦高清视频-无码va在线观看

24小時咨詢電話:0571-88023217長春網站建設公司 10年專業網絡服務供應商

資訊中心

- 直擊網站建設第一現場,掌握全球化的消息 -

當前位置 : 首頁 > 資訊中心 > 【杭州網站設計】擁抱變化—— 可擴展性雜談

【杭州網站設計】擁抱變化—— 可擴展性雜談

分享 2011.06.15 瀏覽次數:10143次

杭州網站設計】擁抱變化—— 可擴展性雜談

     作為軟件開發人員最擔心的就是變化,因為一旦變化,意味著自己的開發任務加重, 輕則修改代碼,重則修改框架,如果不用做任何修改,則皆大歡喜,現實告訴我們,這是小概率事件,但比買彩票中大獎的概率還是大很多。于是各種討論開始,開發人員開始講述修改如何的大,進度如何緊張,架構師也在一旁不停的嘮叨這個修改點的重要性,以及對整個系統帶來的好處。

在業界曾經有一句很經典的話:“在軟件開發領域中,唯一的不變就是變化” 。一旦變化,就有人遭殃,不是開發人員,就是設計師或架構師。無論誰遭殃,都不得不擁抱變化。

擁抱變化是極限編程(eXtreme Programming)里面一個非常重要的概念,代表了敏捷陣營對于變化的一種態度,那就是不拒絕,而且還主動求變。本文不想探討敏捷方面的知識,如何去擁抱變化,而是想要探討程序的可擴展性,如何在編碼過程中,以最小的代價來應對程序未來的變化。

關于可擴展性, 其本身就是一個多方面的概念集合。有人說程序的可擴展性必須建立在對未來需求的準確把握上,也有人說程序的可擴展性必須建立在能夠對需求變化快速響應上。不論熟是熟非,其最終目的都是要求,能在需求發生變化的時候以最小的代價去應付變化。

可以從兩個緯度對可擴展性進行討論,一是設計可擴展性,二是編碼可擴展性,前者從宏觀上考慮,后者從微觀上考慮,當然編碼也是一種設計活動。本文重點論述編碼的可擴展性,對于設計可擴展性,是一個系統性工程,由于作者還沒有達到那個高度和境界,所以不敢瞎寫,本文基本上不做介紹。

《UNIX 編程藝術》一書中有一條關于擴展原則的描述:設計要著眼于未來,未來總比預想快。 關于設計可擴展性, 對于系統架構師或者系統工程師不僅僅要考慮在實現用戶需求的基礎上如何構建系統,還要考慮計算資源的可擴展、應用規模的可擴展,以及對技術換代的可擴展和性能等。

近期發生的干旱和水災,每次都能找到人為的因素。本文開頭提到的場景,如果進行代碼回溯,也能找到一些人為的因素。如果當時的編碼者在寫代碼時充分考慮了代碼可擴展性,在一定條件下,可以達到用最小的代價去應對變化。如果當時只是為了完成任務,交差,后續的維護者可能面對的不是擁抱變化,而是擁抱痛苦!

場景一:在某嵌入式電信級設備整框分布式環境中,有NEMI板(管理板),SWF板(業務板),STU板(業務板)和LC板(業務板),每塊板上都有CPU,運行著各自的程序。目前的架構僅僅對NEMI/SWF/STU板支持了HA(High Available)功能,在SWF卡上運行的某個業務,需要關注SWF卡的主備倒換事件。 運行在SWF卡上的程序可以收到來自NEMI和SWF卡的主備倒換事件,于是進行了如下編碼:

view plaincopy to clipboardprint?01.void processSwitchEvent(GenMsg *pMsg)   02.{   03.    一些合法性判斷語句   04.    if(NEMI_SWITCH_EVENT == pMsg->getSwitchEventGrp())   05.    {   06.        MSG_INFO(“Received NEMI Switch Event……”);   07.        return ;   08.    }   09.    //process SWF Switch Event   10.    業務處理代碼   11.}  void processSwitchEvent(GenMsg *pMsg)
{
    一些合法性判斷語句
    if(NEMI_SWITCH_EVENT == pMsg->getSwitchEventGrp())
    {
        MSG_INFO(“Received NEMI Switch Event……”);
        return ;
    }
    //process SWF Switch Event
    業務處理代碼
}

可能開發人員在進行if條件語句編碼時,可能還考慮了另外一種寫法:

view plaincopy to clipboardprint?
01.void processSwitchEvent(GenMsg *pMsg)  
02.{  
03.    一些合法性判斷語句  
04.    if(SWF_SWITCH_EVENT == pMsg->getSwitchEventGrp())  
05.    {  
06.        MSG_INFO(“Received SWF Switch Event……”);  
07.        業務處理代碼  
08.    }  
09.} 
void processSwitchEvent(GenMsg *pMsg)
{
    一些合法性判斷語句
    if(SWF_SWITCH_EVENT == pMsg->getSwitchEventGrp())
    {
        MSG_INFO(“Received SWF Switch Event……”);
        業務處理代碼
    }
}

在最初的需求中,上下兩種寫法都是合適的,但是不是都合理呢?如果一旦需求發生變更,SWF卡上的另外一個業務需要關注STU板的倒換事件,那么STU板的倒換事件也會被廣播到SWF卡上,最糟糕的是,這兩個業務都訂閱了倒換事件(通過消息里面的內容來判斷是哪塊板發生了倒換),那么上下兩種寫法的區別就體現出來了,一個能正確運行,而另外一個會把STU的倒換事件當作SWF的倒換事件。不難看出,下面一種寫法更具有可擴展性,達到了以最小的代價去應對變化。正是這樣小的修改,往往會被忽略,隱藏一個很深的bug,導致花大量的時間去定位。

對于上述的場景,大家編碼時常會碰到,覺得這樣寫也合適,那樣寫也合適。雖然在一定條件下都很合適,但不一定都合理,那么此時就需要從其他方面加以考慮,如可擴展性,可維護性,可測試性等方面,從而確定哪種寫法更合理。

場景二:假定存在如下一個消息類,最初類中只有一個成員變量,消息類的定義和實現如下:

view plaincopy to clipboardprint?
01.class FsmFileTransferRequest : public GenMsgHdr  
02.{  
03.    public:  
04.        FsmFileTransferRequest (void)  
05.        {  
06.            memset (&mFileTransferReq, 0, sizeof(mFileTransferReq));  
07.            setMsgType (MTYPE_REQUEST);  
08.            setMsgTypeQual (MQUAL_FSM_FILE_TRANSFER_REQUEST);  
09.            setPayloadLen (sizeof(mFileTransferReq));  
10.        }  
11.   
12.        //  get/set operation  
13.        ……  
14.    private:  
15.        SysPkg::FileTransferRequest    mFileTransferReq;  
16.}; 
class FsmFileTransferRequest : public GenMsgHdr
{
    public:
        FsmFileTransferRequest (void)
        {
            memset (&mFileTransferReq, 0, sizeof(mFileTransferReq));
            setMsgType (MTYPE_REQUEST);
            setMsgTypeQual (MQUAL_FSM_FILE_TRANSFER_REQUEST);
            setPayloadLen (sizeof(mFileTransferReq));
        }
 
        //  get/set operation
        ……
    private:
        SysPkg::FileTransferRequest    mFileTransferReq;
};

對于該消息長度,基類提供了兩種接口,一個接口是 setPayloadLen (),另外一個接口是 setMsgLen (),該接口是更高一級的封裝,為所傳入參數減去基類消息的長度,最終結果還是消息的凈荷長度。也許有人會說,基類就不應該提供兩套函數,讓人迷惑,出錯在所難免。

由于場景變化或者需求變更,需要在該類中添加其他的成員變量,維護者可能是這個系統中的另外一個模塊的開發者(自己所負責的模塊中,構造函數里都是用消息總長度函數,默認其他開發者跟他一樣),添加了成員變量和實現后,忘記修改消息的凈荷長度,編譯并運行,結果與預想的大相徑庭,于是開始不停的打斷點調試,不斷的在懷疑消息是不是丟了,或者沒有用修改的代碼進行編譯,總之,一切該懷疑的都在腦海中閃現了一遍。

或者,意識到要修改消息凈荷長度,于是修改成:

view plaincopy to clipboardprint?
01.setPayloadLen (sizeof(mFileTransferReq)+sizeof(mSuccessfulFlag)); 
setPayloadLen (sizeof(mFileTransferReq)+sizeof(mSuccessfulFlag));

如果只是一兩個成員變量,還能忍受。需求一再變更,又增加了幾個成員變量,繼續修改,setPayloadLen()里面的代碼會越來越長,只是代碼寫的難看而已。

如果類的實現者,在編寫代碼時,考慮一下可擴展性,采用消息的總長度函數,那么不論怎么添加成員變量,都不用修改消息長度,一勞永逸。如果確認這個消息不會被擴展,采用 setPayloadLen()也是合理的。

通過以上兩個例子可以發現,如果在編碼時,充分考慮了編碼可擴展性,即使需求發生變更,有時也可以達到事半功倍的效果。關鍵問題是如何識別出這樣的場景,這個只能靠經驗了,沒有捷徑可走!

 

最新網站案例

洞悉市場趨勢演變讓傳播回歸社會

    免費獲取網站建設與網絡推廣方案報價

    • 關于我們

      杭州帷拓科技有限公司,是一家新型的全案網絡開發公司,作為以互聯網高端網站建設、APP開發、小程序開發為核心的專業網絡技術服務供應商,帷拓科技致力于全面分析市場環境、衡量與預測市場需求、整合區別于行業競爭對手的絕對優勢,結合品牌理念深度挖掘項目優勢和產品價值,提升客戶品牌認知、認可度。

    • 我們的客戶

      帷拓科技歷經十年沉淀,與國內外上千家客戶達成合作關系,其中穩定合作的公司有:浙江華為、浙江移動、浙江5G產業聯盟、浙江省社科院、綠城足球俱樂部、娃哈哈雙語學校、健康中國杭州峰會、科雷機電等,帷拓科技始終堅持“帷有專業,才能拓展無限”的服務理念,堅持“認真堅持細節”的優質服務理念,不斷完善自身,成就企業,最終實現共贏。

    • 我們的業務

      帷拓科技主營業務范圍包含互聯網高端網站建設、APP開發、小程序開發、商城網站建設、公眾號運營以及數字營銷等,涵蓋了服務、房產、數碼、服裝、物流貿易等行業,根據品牌現狀,為每個客戶量身定制項目整體服務方案,以敏銳的市場洞察力、創新的市場策劃能力,全面把握市場變化,為客戶實現從企業到消費者的價值轉換。

    Designerpart Designagentur
    Designerpart Designagentur
    Designerpart Designagentur
    Designerpart Designagentur
    Designerpart Designagentur
    Designerpart Designagentur
    主站蜘蛛池模板: 亚洲熟女久久色| 国产精品人成电影在线观看 | 国产亚洲欧美日韩精品一区二区| 国产成人无码18禁午夜福利网址| 久久久久国精品产熟女久色| 天天做av天天爱天天爽| 夜夜爱夜鲁夜鲁很鲁| 国产中文字幕乱人伦在线观看| 男女性杂交内射妇女bbwxz| 国产一区| 亚洲 欧美 中文 日韩aⅴ| 国产成人无码精品午夜福利a| 亚洲精品动漫免费二区| 在线观看一区二区三区国产免费| 老子影院无码午夜伦不卡| 人人玩人人添人人澡免费| 久久久无码人妻精品无码| 亚洲 欧洲 无码 在线观看| 在线天堂资源www在线中文| 99热精这里只有精品| 午夜爽爽爽男女免费观看hd| 99久久无码一区人妻| 成年免费视频黄网站在线观看| 亚洲性色av一区二区三区| 无码任你躁久久久久久| 国产精品一区二区av片| 亚洲男同gv在线观看| 亚洲性啪啪无码av天堂| 国产色婷婷亚洲99精品小说| 亚洲精品av无码喷奶水糖心| 狠狠综合久久狠狠88亚洲| 西西人体444www大胆无码视频| 亚洲精品无码专区在线| 久久久一本精品99久久精品88| 亚洲婷婷开心色四房播播| 日本久久久久久久久久加勒比| 夜夜爽日日澡人人添| а天堂8中文最新版在线官网| 动漫无遮挡h纯肉亚洲资源大片| 被粗大的?巴捣出白浆江澄| 久久久噜噜噜久久免费|