<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                第21章 組合模式 21.1 公司的人事架構是這樣的嗎 各位讀者,大家在上學的時候應該都學過“數據結構”這門課程吧,還記得其中有一節叫“二叉樹”吧,我們上學那會兒這一章節是必考內容,左子樹,右子樹,什么先序遍歷、后序遍歷,重點就是二叉樹的遍歷,我還記得當時老師就說,考試的時候一定有二叉樹的構建和遍歷,現在想起來還是覺得老師是正確的,樹狀結構在實際中應用非常廣泛,想想看你最常使用的XML格式是不是就是一個樹形結構。 咱就先說個最常見的例子,公司的人事管理就是一個典型的樹狀結構,想想看你公司的組織架構是不是如圖21-1所示。 ![](https://box.kancloud.cn/2016-08-14_57b00367136b8.jpg) 圖21-1 普遍的組織架構 從最高的老大,往下一層一層的管理,最后到我們這層小兵……很典型的樹狀結構(說明一下,這不是二叉樹,有關二叉樹的定義可以翻翻以前的教科書),我們今天的任務就是要把這個樹狀結構實現出來,并且還要把它遍歷一遍,就類似于閱讀你公司的人員花名冊。 從該樹狀結構上分析,有兩種不同性質的節點:有分支的節點(如研發部經理)和無分支的節點(如員工A、員工D等),我們增加一點學術術語上去,總經理叫做根節點(是不是想到XML中的那個根節點root,那就對了),類似研發部經理有分支的節點叫做樹枝節點,類似員工A的無分支的節點叫做樹葉節點,都很形象,三個類型的節點,那是不是定義三個類就可以?好,我們按照這個思路走下去,先看我們自己設計的類圖,如圖21-2所示。 ![](https://box.kancloud.cn/2016-08-14_57b003672b4d1.jpg) 圖21-2 最容易想到的組織架構類圖 這個類圖是初學者最容易想到的類圖(首先聲明,這個類圖是有缺陷的,如果你已經看明白這個類圖的缺陷了,該段落就可以一目十行地看下去,我們是循序漸進地講課,一步一個腳印),非常簡單,我們來看一下如何實現,先看最高級別的根節點接口,如代碼清單21-1所示。 代碼清單21-1 根節點接口 public?interface?IRoot?{ ?????//得到總經理的信息 ?????public?String?getInfo(); ?????//總經理下邊要有小兵,那要能增加小兵,比如研發部總經理,這是個樹枝節點 ?????public?void?add(IBranch?branch); ?????//那要能增加樹葉節點 ?????public?void?add(ILeaf?leaf); ?????//既然能增加,那還要能夠遍歷,不可能總經理不知道他手下有哪些人 ?????public?ArrayList?getSubordinateInfo();????? } 這個根節點的對象就是我們的總經理,其具體實現如代碼清單21-2所示。 代碼清單21-2 根節點的實現 public?class?Root?implements?IRoot?{ ?????//保存根節點下的樹枝節點和樹葉節點,Subordinate的意思是下級 ?????private?ArrayList?subordinateList?=?new?ArrayList(); ?????//根節點的名稱 ?????private?String?name?=?""; ?????//根節點的職位 ?????private?String?position?=?""; ?????//根節點的薪水 ?????private?int?salary?=?0; ?????//通過構造函數傳遞進來總經理的信息 ?????public?Root(String?name,String?position,int?salary){ ?????????????this.name?=?name; ?????????????this.position?=?position; ?????????????this.salary?=?salary; ?????} ?????//增加樹枝節點 ?????public?void?add(IBranch?branch)?{ ?????????????this.subordinateList.add(branch); ?????} ?????//增加葉子節點,比如秘書,直接隸屬于總經理 ?????public?void?add(ILeaf?leaf)?{ ?????????????this.subordinateList.add(leaf); ?????} ?????//得到自己的信息 ?????public?String?getInfo()?{ ?????????????String?info?=?""; ?????????????info?=?"名稱:"+?this.name;; ?????????????info?=?info?+?"\t職位:"?+?this.position; ?????????????info?=?info?+?"\t薪水:?"?+?this.salary; ?????????????return?info; ?????} ?????//得到下級的信息 ?????public?ArrayList?getSubordinateInfo()?{ ?????????????return?this.subordinateList; ?????} } 很簡單,通過構造函數傳入參數,然后獲得信息,可以增加子樹枝節點(部門經理)和葉子節點(秘書)。我們再來看其他有分支的節點接口,如代碼清單21-3所示。 代碼清單21-3 其他有分支的節點接口 public?interface?IBranch?{ ?????//獲得信息 ?????public?String?getInfo(); ?????//增加數據節點,例如研發部下設的研發一組 ?????public?void?add(IBranch?branch); ?????//增加葉子節點 ?????public?void?add(ILeaf?leaf); ?????//獲得下級信息 ?????public?ArrayList?getSubordinateInfo(); } 有了接口,就應該有實現,其具體的實現類,如代碼清單21-4所示。 代碼清單21-4 分支的節點實現 public?class?Branch?implements?IBranch?{ ?????//存儲子節點的信息 ?????private?ArrayList?subordinateList?=?new?ArrayList(); ?????//樹枝節點的名稱 ?????private?String?name=""; ?????//樹枝節點的職位 ?????private?String?position?=?""; ?????//樹枝節點的薪水 ?????private?int?salary?=?0; ?????//通過構造函數傳遞樹枝節點的參數 ?????public?Branch(String?name,String?position,int?salary){ ?????????????this.name?=?name; ?????????????this.position?=?position; ?????????????this.salary?=?salary; ?????} ?????//增加一個子樹枝節點 ?????public?void?add(IBranch?branch)?{ ?????????????this.subordinateList.add(branch); ?????} ?????//增加一個葉子節點 ?????public?void?add(ILeaf?leaf)?{ ?????????????this.subordinateList.add(leaf); ?????} ?????//獲得自己樹枝節點的信息 ?????public?String?getInfo()?{ ?????????????String?info?=?""; ?????????????info?=?"名稱:"?+?this.name; ?????????????info?=?info?+?"\t職位:"+?this.position; ?????????????info?=?info?+?"\t薪水:"+this.salary; ?????????????return?info; ?????} ?????//獲得下級的信息 ?????public?ArrayList?getSubordinateInfo()?{ ?????????????return?this.subordinateList; ?????} } 不管是總經理還是部門經理都是有子節點的存在,最終的子節點就是葉子節點,其接口如代碼清單21-5所示。 代碼清單21-5 葉子節點的接口 public?interface?ILeaf?{????? ?????//獲得自己的信息 ?????public?String?getInfo(); } 葉子節點的接口簡單,實現也非常容易,如代碼清單21-6所示。 代碼清單21-6 葉子節點的實現 public?class?Leaf?implements?ILeaf?{ ?????//葉子叫什么名字 ?????private?String?name?=?""; ?????//葉子的職位 ?????private?String?position?=?""; ?????//葉子的薪水 ?????private?int?salary=0; ?????//通過構造函數傳遞信息 ?????public?Leaf(String?name,String?position,int?salary){ ?????????????this.name?=?name; ?????????????this.position?=?position; ?????????????this.salary?=?salary; ?????} ?????//最小的小兵只能獲得自己的信息了 ?????public?String?getInfo()?{ ?????????????String?info?=?""; ?????????????info?=?"名稱:"?+?this.name; ?????????????info?=?info?+?"\t職位:"+?this.position; ?????????????info?=?info?+?"\t薪水:"+this.salary; ?????????????return?info; ?????} } 好了,所有的根節點、樹枝節點和葉子節點都已經實現了,從總經理、部門經理到最終的員工都已經實現,然后的工作就是組裝成一個樹狀結構并遍歷這棵樹,通過什么來完成呢?通過場景類Client完成,如代碼清單21-7所示。 代碼清單21-7 場景類 public?class?Client?{ ?????public?static?void?main(String[]?args)?{ ?????????????//首先產生了一個根節點 ?????????????IRoot?ceo?=?new?Root("王大麻子","總經理",100000); ?????????????//產生三個部門經理,也就是樹枝節點 ?????????????IBranch?developDep?=?new?Branch("劉大瘸子","研發部門經理",10000); ?????????????IBranch?salesDep?=?new?Branch("馬二拐子","銷售部門經理",20000); ?????????????IBranch?financeDep?=?new?Branch("趙三駝子","財務部經理",30000); ?????????????//再把三個小組長產生出來 ?????????????IBranch?firstDevGroup?=?new?Branch("楊三乜斜","開發一組組長",5000); ?????????????IBranch?secondDevGroup?=?new?Branch("吳大棒槌","開發二組組長",6000); ?????????????//剩下的就是我們這些小兵了,就是路人甲、路人乙 ?????????????ILeaf?a?=?new?Leaf("a","開發人員",2000); ?????????????ILeaf?b?=?new?Leaf("b","開發人員",2000); ?????????????ILeaf?c?=?new?Leaf("c","開發人員",2000); ?????????????ILeaf?d?=?new?Leaf("d","開發人員",2000); ?????????????ILeaf?e?=?new?Leaf("e","開發人員",2000); ?????????????ILeaf?f?=?new?Leaf("f","開發人員",2000); ?????????????ILeaf?g?=?new?Leaf("g","開發人員",2000); ?????????????ILeaf?h?=?new?Leaf("h","銷售人員",5000); ?????????????ILeaf?i?=?new?Leaf("i","銷售人員",4000); ?????????????ILeaf?j?=?new?Leaf("j","財務人員",5000); ?????????????ILeaf?k?=?new?Leaf("k","CEO秘書",8000); ?????????????ILeaf?zhengLaoLiu?=?new?Leaf("鄭老六","研發部副總",20000); ?????????????//該產生的人都產生出來了,然后我們怎么組裝這棵樹 ?????????????//首先是定義總經理下有三個部門經理 ?????????????ceo.add(developDep); ?????????????ceo.add(salesDep); ?????????????ceo.add(financeDep); ?????????????//總經理下還有一個秘書 ?????????????ceo.add(k); ?????????????//定義研發部門下的結構 ?????????????developDep.add(firstDevGroup); ?????????????developDep.add(secondDevGroup); ?????????????//研發部經理下還有一個副總 ?????????????developDep.add(zhengLaoLiu); ?????????????//看看開發兩個開發小組下有什么 ?????????????firstDevGroup.add(a); ?????????????firstDevGroup.add(b); ?????????????firstDevGroup.add(c); ?????????????secondDevGroup.add(d); ?????????????secondDevGroup.add(e); ?????????????secondDevGroup.add(f); ?????????????//再看銷售部下的人員情況 ?????????????salesDep.add(h); ?????????????salesDep.add(i); ?????????????//最后一個財務 ?????????????financeDep.add(j); ?????????????//打印寫完的樹狀結構 ?????????????System.out.println(ceo.getInfo()); ?????????????//打印出來整個樹形 ?????????????getAllSubordinateInfo(ceo.getSubordinateInfo()); ?????} ?????//遍歷所有的樹枝節點,打印出信息 ?????private?static?void?getAllSubordinateInfo(ArrayList?subordinateList){ ?????????????int?length?=?subordinateList.size(); ?????????????//定義一個ArrayList長度,不要在for循環中每次計算 ?????????????for(int?m=0;m<length;m++){?? ??????????????????Object?s?=?subordinateList.get(m); ??????????????????if(s?instanceof?Leaf){??//是個葉子節點,也就是員工 ??????????????????????????ILeaf?employee?=?(ILeaf)s; ??????????????????????????System.out.println(((Leaf)?s).getInfo()); ??????????????????}else{ ??????????????????????????IBranch?branch?=?(IBranch)s; ??????????????????????????System.out.println(branch.getInfo()); ??????????????????????????//再遞歸調用 ??????????????????????????getAllSubordinateInfo(branch.getSubordinateInfo()); ??????????????????} ?????????????} ?????} } 這個程序比較長,如果在我們的項目中有這樣的程序,肯定是要被拉出來做典型的,你寫一大坨的程序給誰呀,以后還要維護,程序要短小精悍!幸運的是,我們這是作為案例來講解,而且就是指出這樣組裝這棵樹是有問題的,等會我們深入講解,先看運行結果: ? | 名稱:王大麻子 |  職位:總經理 |  薪水: 100000 | |-----|-----|-----| | 名稱:劉大瘸子 |  職位:研發部門經理 |  薪水:10000 | | 名稱:楊三乜斜 |  職位:開發一組組長 |  薪水:5000 | | 名稱:a |  職位:開發人員 |  薪水:2000 | | 名稱:b |  職位:開發人員 |  薪水:2000 | | 名稱:c |  職位:開發人員 |  薪水:2000 | | 名稱:吳大棒槌 |  職位:開發二組組長 |  薪水:6000 | | 名稱:d |  職位:開發人員 |  薪水:2000 | | 名稱:e |  職位:開發人員 |  薪水:2000 | | 名稱:f |  職位:開發人員 |  薪水:2000 | | 名稱:鄭老六 |  職位:研發部副總 |  薪水:20000 | | 名稱:馬二拐子 |  職位:銷售部門經理 |  薪水:20000 | | 名稱:h |  職位:銷售人員 |  薪水:5000 | | 名稱:i |  職位:銷售人員 |  薪水:4000 | | 名稱:趙三駝子 |  職位:財務部經理 |  薪水:30000 | | 名稱:j |  職位:財務人員 |  薪水:5000 | | 名稱:k |  職位:CEO秘書 |  薪水:8000 | 和我們期望的結果一樣,一棵完整的樹就生成了,而且我們還能夠遍歷。不錯,不錯,但是看類圖或程序的時候,你有沒有發覺有問題?getInfo每個接口都有,為什么不能抽象出來?Root類和Branch類有什么差別?根節點本身就是樹枝節點的一種,為什么要定義成兩個接口兩個類?如果我要加一個任職期限,你是不是每個類都需要修改?如果我要后序遍歷(從員工找到他的上級領導)能做到嗎?——徹底暈菜了! 問題很多,我們一個一個解決,先說抽象的問題。我們確實可以把IBranch和IRoot合并成一個接口,確認無疑的事我們先做,那我們就修改一下類圖,如圖21-3所示。 仔細看看這個類圖,還能不能發現點問題。想想看接口的作用是什么?定義一類事物所具有的共性,那ILeaf和IBranch是不是也有共性呢?有,getInfo方法!我們是不是要把這個共性也封裝起來呢?是的,是的,提煉事物的共同點,然后封裝之,這是我們作為設計專家的拿手好戲,修改后的類圖如圖21-4所示。 ![](https://box.kancloud.cn/2016-08-14_57b00367457b1.jpg) 圖21-3 整合根節點和樹枝節點后的類圖 ![](https://box.kancloud.cn/2016-08-14_57b003675cfa6.jpg) 圖21-4 修改后的類圖 類圖上增加了一個ICorp接口,它是公司所有人員信息的接口類,不管你是經理還是員工,你都有名字、職位、薪水,這個定義成一個接口沒有錯,但是你可能對于ILeaf接口持懷疑狀態,空接口有何意義呀?有意義!它是每個樹枝節點的代表,系統擴容的時候你就會發現它是多么“棟梁”。我們先來看新增加的接口ICorp,如代碼清單21-8所示。 代碼清單21-8 公司人員接口 public?interface?ICorp?{ ?????//每個員工都有信息,你想隱藏,門兒都沒有! ?????public?String?getInfo(); } 接口很簡單,只有一個方法,就是獲得員工的信息,樹葉節點是最基層的構件,我們先來看看它的接口,空接口,如代碼清單21-9所示。 代碼清單21-9 樹葉接口 public?interface?ILeaf?extends?ICorp?{ } 樹葉接口的實現類,如代碼清單21-10所示。 代碼清單21-10 樹葉接口 public?class?Leaf?implements?ILeaf?{ ?????//小兵也有名稱 ?????private?String?name?=?""; ?????//小兵也有職位 ?????private?String?position?=?""; ?????//小兵也有薪水,否則誰給你干 ?????private?int?salary?=?0; ?????//通過一個構造函數傳遞小兵的信息 ?????public?Leaf(String?name,String?position,int?salary){ ?????????????this.name?=?name; ?????????????this.position?=?position; ?????????????this.salary?=?salary; ?????} ?????//獲得小兵的信息 ?????public?String?getInfo()?{ ?????????????String?info?=?""; ?????????????info?=?"姓名:"?+?this.name; ?????????????info?=?info?+?"\t職位:"+?this.position; ?????????????info?=?info?+?"\t薪水:"?+?this.salary; ?????????????return?info; ?????} } 小兵就只有這些信息了,我們是具體干活的,我們是管理不了其他同事的,我們來看看那些經理和小組長是怎么實現的,也就是IBranch接口,如代碼清單21-11所示。 代碼清單21-11 樹枝接口 public?interface?IBranch?extends?ICorp?{????? ?????//能夠增加小兵(樹葉節點)或者是經理(樹枝節點) ?????public?void?addSubordinate(ICorp?corp); ?????//我還要能夠獲得下屬的信息 ?????public?ArrayList<ICorp>?getSubordinate(); ?????/*本來還應該有一個方法delSubordinate(ICorp?corp),刪除下屬 ??????*?這個方法我們沒有用到就不寫進來了 ??????*/ } 接口也很簡單,其實現類也不可能太復雜,如代碼清單21-12所示。 代碼清單21-12 樹枝實現類 public?class?Branch?implements?IBranch?{ ?????//領導也是人,也有名字 ?????private?String?name?=?""; ?????//領導和領導不同,也是職位區別 ?????private?String?position?=?""; ?????//領導也是拿薪水的 ?????private?int?salary?=?0; ?????//領導下邊有哪些下級領導和小兵 ?????ArrayList<ICorp>?subordinateList?=?new?ArrayList<ICorp>(); ?????//通過構造函數傳遞領導的信息 ?????public?Branch(String?name,String?position,int?salary){ ?????????????this.name?=?name; ?????????????this.position?=?position; ?????????????this.salary?=?salary; ?????} ?????//增加一個下屬,可能是小頭目,也可能是個小兵 ?????public?void?addSubordinate(ICorp?corp)?{ ?????????????this.subordinateList.add(corp); ?????} ?????//我有哪些下屬 ?????public?ArrayList<ICorp>?getSubordinate()?{ ?????????????return?this.subordinateList; ?????} ?????//領導也是人,他也有信息 ?????public?String?getInfo()?{ ?????????????String?info?=?""; ?????????????info?=?"姓名:"?+?this.name; ?????????????info?=?info?+?"\t職位:"+?this.position; ?????????????info?=?info?+?"\t薪水:"?+?this.salary; ?????????????return?info; ?????} } 實現類也很簡單,不多說,程序寫得好不好,就看別人怎么調用了,我們看場景類Client,如代碼清單21-13所示。 代碼清單21-13 場景類a public?class?Client?{ ?????public?static?void?main(String[]?args)?{ ?????????????//首先是組裝一個組織結構出來 ?????????????Branch?ceo?=?compositeCorpTree(); ?????????????//首先把CEO的信息打印出來 ?????????????System.out.println(ceo.getInfo()); ?????????????//然后是所有員工信息 ?????????????System.out.println(getTreeInfo(ceo)); ?????} ?????//把整個樹組裝出來 ?????public?static?Branch?compositeCorpTree(){ ?????????????//首先產生總經理CEO ?????????????Branch?root?=?new?Branch("王大麻子","總經理",100000); ?????????????//把三個部門經理產生出來 ?????????????Branch?developDep?=?new?Branch("劉大瘸子","研發部門經理",10000); ?????????????Branch?salesDep?=?new?Branch("馬二拐子","銷售部門經理",20000); ?????????????Branch?financeDep?=?new?Branch("趙三駝子","財務部經理",30000); ?????????????//再把三個小組長產生出來 ?????????????Branch?firstDevGroup?=?new?Branch("楊三乜斜","開發一組組長",5000); ?????????????Branch?secondDevGroup?=?new?Branch("吳大棒槌","開發二組組長",6000); ?????????????//把所有的小兵都產生出來 ?????????????Leaf?a?=?new?Leaf("a","開發人員",2000); ?????????????Leaf?b?=?new?Leaf("b","開發人員",2000); ?????????????Leaf?c?=?new?Leaf("c","開發人員",2000); ?????????????Leaf?d?=?new?Leaf("d","開發人員",2000); ?????????????Leaf?e?=?new?Leaf("e","開發人員",2000); ?????????????Leaf?f?=?new?Leaf("f","開發人員",2000); ?????????????Leaf?g?=?new?Leaf("g","開發人員",2000); ?????????????Leaf?h?=?new?Leaf("h","銷售人員",5000); ?????????????Leaf?i?=?new?Leaf("i","銷售人員",4000); ?????????????Leaf?j?=?new?Leaf("j","財務人員",5000); ?????????????Leaf?k?=?new?Leaf("k","CEO秘書",8000); ?????????????Leaf?zhengLaoLiu?=?new?Leaf("鄭老六","研發部副經理",20000); ?????????????//開始組裝 ?????????????//CEO下有三個部門經理和一個秘書 ?????????????root.addSubordinate(k); ?????????????root.addSubordinate(developDep); ?????????????root.addSubordinate(salesDep); ?????????????root.addSubordinate(financeDep); ?????????????//研發部經理 ?????????????developDep.addSubordinate(zhengLaoLiu); ?????????????developDep.addSubordinate(firstDevGroup); ?????????????developDep.addSubordinate(secondDevGroup); ?????????????//看看兩個開發小組下有什么 ?????????????firstDevGroup.addSubordinate(a); ?????????????firstDevGroup.addSubordinate(b); ?????????????firstDevGroup.addSubordinate(c); ?????????????secondDevGroup.addSubordinate(d); ?????????????secondDevGroup.addSubordinate(e); ?????????????secondDevGroup.addSubordinate(f); ?????????????//再看銷售部下的人員情況 ?????????????salesDep.addSubordinate(h); ?????????????salesDep.addSubordinate(i); ?????????????//最后一個財務 ?????????????financeDep.addSubordinate(j); ?????????????return?root; ?????} ?????//遍歷整棵樹,只要給我根節點,我就能遍歷出所有的節點 ?????public?static?String?getTreeInfo(Branch?root){ ?????????????ArrayList<ICorp>?subordinateList?=?root.getSubordinate(); ?????????????String?info?=?""; ?????????????for(ICorp?s?:subordinateList){ ?????????????????????if(s?instanceof?Leaf){?//是員工就直接獲得信息 ?????????????????????????????info?=?info?+?s.getInfo()+"\n"; ?????????????????????}else{?//是個小頭目 ?????????????????????????????info?=?info?+?s.getInfo()?+"\n"+?getTreeInfo((Branch)s); ?????????????????????} ?????????????} ?????????????return?info; ?????} } 運行結果完全相同,不再贅述。通過這樣構件,一個非常清晰的樹狀人員資源管理圖出現了,那我們的程序是否還可以優化?可以!你看Leaf和Branch中都有getInfo信息,是不是可以抽象?好,我們抽象一下,如圖21-5所示。 ![](https://box.kancloud.cn/2016-08-14_57b00367711ee.jpg) 圖21-5 精簡的類圖 你一看這個圖,樂了。能不樂嘛,減少很多工作量了,接口沒有了,改成抽象類了,IBranch接口也沒有了,直接把方法放到了實現類中了,太精簡了!而且場景類只認定抽象類Corp就成,那我們首先來看抽象類ICorp,如代碼清單21-14所示。 代碼清單21-14 抽象公司職員類 public?abstract?class?Corp?{ ?????//公司每個人都有名稱 ?????private?String?name?=?""; ?????//公司每個人都職位 ?????private?String?position?=?""; ?????//公司每個人都有薪水 ?????private?int?salary?=0;????? ?????public?Corp(String?_name,String?_position,int?_salary){ ?????????????this.name?=?_name; ?????????????this.position?=?_position; ?????????????this.salary?=?_salary; ?????} ?????//獲得員工信息 ?????public?String?getInfo(){ ?????????????String?info?=?""; ?????????????info?=?"姓名:"?+?this.name; ?????????????info?=?info?+?"\t職位:"+?this.position; ?????????????info?=?info?+?"\t薪水:"?+?this.salary; ?????????????return?info; ?????} } 抽象類嘛,就應該抽象出一些共性的東西出來,然后看兩個具體的實現類,樹葉節點如代碼清單21-15所示。 代碼清單21-15 樹葉節點 public?class?Leaf?extends?Corp?{ ?????//就寫一個構造函數,這個是必需的 ?????public?Leaf(String?_name,String?_position,int?_salary){ ?????????????super(_name,_position,_salary); ?????} } 這個精簡得比較多,幾行代碼就完成了,確實就應該這樣,下面是小頭目的實現類,如代碼清單21-16所示。 代碼清單21-16 樹枝節點 public?class?Branch?extends?Corp?{ ?????//領導下邊有哪些下級領導和小兵 ?????ArrayList<Corp>?subordinateList?=?new?ArrayList<Corp>(); ?????//構造函數是必需的 ?????public?Branch(String?_name,String?_position,int?_salary){ ?????????????super(_name,_position,_salary); ?????} ?????//增加一個下屬,可能是小頭目,也可能是個小兵 ?????public?void?addSubordinate(Corp?corp)?{ ?????????????this.subordinateList.add(corp); ?????} ?????//我有哪些下屬 ?????public?ArrayList<Corp>?getSubordinate()?{ ?????????????return?this.subordinateList; ?????} } 場景類中構建樹形結構,并進行遍歷。組裝沒有變化,遍歷組織機構數稍有變化,如代碼清單21-17所示。 代碼清單21-17 稍稍修改的場景類 public?class?Client?{ ?????//遍歷整棵樹,只要給我根節點,我就能遍歷出所有的節點 ?????public?static?String?getTreeInfo(Branch?root){ ?????????????ArrayList<Corp>?subordinateList?=?root.getSubordinate(); ?????????????String?info?=?""; ?????????????for(Corp?s?:subordinateList){ ????????????????????if(s?instanceof?Leaf){?//是員工就直接獲得信息 ???????????????????????????info?=?info?+?s.getInfo()+"\n"; ????????????????????}else{?//是個小頭目 ???????????????????????????info?=?info+s.getInfo()+"\n"+?getTreeInfo((Branch)s); ????????????????????} ?????????????} ?????????????return?info; ?????} } 場景類中main方法沒有變動,請參考代碼清單21-7所示,不再贅述。遍歷組織機構樹的getTreeInfo稍有修改,就是把用到ICorp接口的地方修改為Corp抽象類,僅僅修改了粗體部分,其他保持不變,運行結果相同。這就是組合模式。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看