<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                第14章 中介者模式 14.1 進銷存管理是這個樣子的嗎 大家都來自五湖四海,都要生存,于是都找了個靠山——公司,就是給你發薪水的地方。公司要想盡辦法贏利賺錢,贏利方法則不盡相同,但是各個公司都有相同的三個環節:采購、銷售和庫存。這個怎么說呢?比如一個軟件公司,要開發軟件,就需要購買開發環境,如Windows操作系統、數據庫產品等,這就是采購;開發完產品還要把產品推銷出去;有產品就必然有庫存,軟件產品也有庫存,雖然不需要占用庫房空間,但也要占用光盤或硬盤,這也是庫存。再比如做咨詢服務的公司,它要采購什么?采購知識,采購經驗,這是這類企業的生存之本,銷售的也是知識和經驗,庫存同樣是知識和經驗。既然進銷存是如此重要,我們今天就來講講它的原理和設計,我相信很多人都已經開發過這種類型的軟件,基本上都形成了固定套路,不管是單機版還是網絡版,一般的做法都是通過數據庫來完成相關產品的管理,相對來說這還是比較簡單的項目,三個模塊的示意圖如圖14-1所示。 ![](https://box.kancloud.cn/2016-08-14_57b00363819d3.jpg) 圖14-1 進銷存示意圖 我們從這個示意圖上可以看出,三個模塊是相互依賴的。我們就以一個終端銷售商(以服務最終客戶為目標的企業,比如某某超市、某某商店等)為例,采購部門要采購IBM的電腦,它根據以下兩個要素來決定采購數量。 ● 銷售情況 銷售部門要反饋銷售情況,暢銷就多采購,滯銷就不采購。 ● 庫存情況 即使是暢銷產品,庫存都有1000臺了,每天才賣出去10臺,也就不需要再采購了! 銷售模塊是企業的贏利核心,對其他兩個模塊也有影響: ● 庫存情況 庫房有貨,才能銷售,空手套白狼是不行的。 ● 督促采購 在特殊情況下,比如一個企業客戶要一次性購買100臺電腦,庫存只有80臺,這時需要催促采購部門趕快采購! 同樣地,庫存管理也對其他兩個模塊有影響。庫房是有容積限制的,不可能無限大,所以就有了清倉處理,那就要求采購部門停止采購,同時銷售部門進行打折銷售。 從以上分析來看,這三個模塊都有自己的行為,并且與其他模塊之間的行為產生關聯,類似于我們辦公室的同事,大家各干各的活,但是彼此之間還是有交叉的,于是彼此之間就產生緊耦合,也就是一個團隊。我們先來實現這個進銷存,類圖如圖14-2所示。 ![](https://box.kancloud.cn/2016-08-14_57b0036396919.jpg) 圖14-2 簡單的進銷存類圖 Purchase負責采購管理,buyIBMComputer指定了采購IBM電腦,refuseBuyIBM是指不再采購IBM了,源代碼如代碼清單14-1所示。 代碼清單14-1 采購管理 public?class?Purchase?{ ?????//采購IBM電腦 ?????public?void?buyIBMcomputer(int?number){ ?????????????//訪問庫存 ?????????????Stock?stock?=?new?Stock(); ?????????????//訪問銷售 ?????????????Sale?sale?=?new?Sale(); ?????????????//電腦的銷售情況 ?????????????int?saleStatus?=?sale.getSaleStatus(); ?????????????if(saleStatus>80){??//銷售情況良好 ?????????????????????System.out.println("采購IBM電腦:"+number?+?"臺"); ?????????????????????stock.increase(number); ?????????????}else{??//銷售情況不好 ?????????????????????int?buyNumber?=?number/2;??//折半采購 ?????????????????????System.out.println("采購IBM電腦:"+buyNumber+?"臺"); ?????????????} ?????}?? ?????//不再采購IBM電腦 ?????public?void?refuseBuyIBM(){ ?????????????System.out.println("不再采購IBM電腦"); ?????} } Purchase定義了采購電腦的標準:如果銷售情況比較好,大于80分,你讓我采購多少我就采購多少;銷售情況不好,你讓我采購100臺,我就采購50臺,對折采購。電腦采購完畢,需要放到庫房中,因此要調用庫存的方法,增加庫存電腦數量。我們繼續來看庫房Stock類,如代碼清單14-2所示。 代碼清單14-2 庫存管理 public?class?Stock?{ ?????//剛開始有100臺電腦 ?????private?static?int?COMPUTER_NUMBER?=100; ?????//庫存增加 ?????public?void?increase(int?number){ ?????????????COMPUTER_NUMBER?=?COMPUTER_NUMBER?+?number; ?????????????System.out.println("庫存數量為:"+COMPUTER_NUMBER); ?????}?? ?????//庫存降低 ?????public?void?decrease(int?number){ ?????????????COMPUTER_NUMBER?=?COMPUTER_NUMBER?-?number; ?????????????System.out.println("庫存數量為:"+COMPUTER_NUMBER); ?????} ?????//獲得庫存數量 ?????public?int?getStockNumber(){ ?????????????return?COMPUTER_NUMBER; ?????} ?????//存貨壓力大了,就要通知采購人員不要采購,銷售人員要盡快銷售 ?????public?void?clearStock(){ ?????????????Purchase?purchase?=?new?Purchase(); ?????????????Sale?sale?=?new?Sale(); ?????????????System.out.println("清理存貨數量為:"+COMPUTER_NUMBER); ?????????????//要求折價銷售 ?????????????sale.offSale(); ?????????????//要求采購人員不要采購 ?????????????purchase.refuseBuyIBM(); ?????} } 庫房中的貨物數量肯定有增減,同時庫房還有一個容量顯示,達到一定的容量后就要求對一些商品進行折價處理,以騰出更多的空間容納新產品。于是就有了clearStock方法,既然是清倉處理肯定就要折價銷售了。于是在Sale類中就有了offSale方法,我們來看Sale源代碼,如代碼清單14-3所示。 代碼清單14-3 銷售管理 public?class?Sale?{ ?????//銷售IBM電腦 ?????public?void?sellIBMComputer(int?number){ ?????????????//訪問庫存 ?????????????Stock?stock?=?new?Stock(); ?????????????//訪問采購 ?????????????Purchase?purchase?=?new?Purchase(); ?????????????if(stock.getStockNumber()<number){??//庫存數量不夠銷售 ????????????????????purchase.buyIBMcomputer(number); ?????????????} System.out.println("銷售IBM電腦"+number+"臺"); ?????????????stock.decrease(number); ?????} ?????//反饋銷售情況,0~100之間變化,0代表根本就沒人賣,100代表非常暢銷,出一個賣一個 ?????public?int?getSaleStatus(){ ?????????????Random?rand?=?new?Random(System.currentTimeMillis()); ?????????????int?saleStatus?=?rand.nextInt(100); ?????????????System.out.println("IBM電腦的銷售情況為:"+saleStatus); ?????????????return?saleStatus; ?????} ?????//折價處理 ?????public?void?offSale(){ ?????????????//庫房有多少賣多少 ?????????????Stock?stock?=?new?Stock(); ?????????????System.out.println("折價銷售IBM電腦"+stock.getStockNumber()+"臺"); ?????} } Sale類中的getSaleStatus是獲得銷售情況,這個當然要出現在Sale類中了。記住要把恰當的類放到恰當的類中,銷售情況只有銷售人員才能反饋出來,通過百分制的機制衡量銷售情況。我們再來看場景類是怎么運行的,場景類如代碼清單14-4所示。 代碼清單14-4 場景類 public?class?Client?{ ?????public?static?void?main(String[]?args)?{ ?????????????//采購人員采購電腦 ?????????????System.out.println("------采購人員采購電腦--------"); ?????????????Purchase?purchase?=?new?Purchase(); ?????????????purchase.buyIBMcomputer(100);?????????????? ?????????????//銷售人員銷售電腦 ?????????????System.out.println("\n------銷售人員銷售電腦--------"); ?????????????Sale?sale?=?new?Sale(); ?????????????sale.sellIBMComputer(1);??????????? ?????????????//庫房管理人員管理庫存 ?????????????System.out.println("\n------庫房管理人員清庫處理--------"); ?????????????Stock?stock?=?new?Stock(); ?????????????stock.clearStock(); ?????} } 我們在場景類中模擬了三種人員的活動:采購人員采購電腦,銷售人員銷售電腦,庫管員管理庫存。運行結果如下所示: ------采購人員采購電腦-------- IBM電腦的銷售情況為:95 采購IBM電腦:100臺 庫存數量為:200 ------銷售人員銷售電腦-------- 銷售IBM電腦1臺 庫存數量為:199 ------庫房管理人員清庫處理-------- 清理存貨數量為:199 折價銷售IBM電腦199臺 不再采購IBM電腦 運行結果也是我們期望的,三個不同類型的參與者完成了各自的活動。你有沒有發現這三個類是彼此關聯的?每個類都與其他兩個類產生了關聯關系。迪米特法則認為“每個類只和朋友類交流”,這個朋友類并非越多越好,朋友類越多,耦合性越大,要想修改一個就得修改一片,這不是面向對象設計所期望的,況且這還是僅三個模塊的情況,屬于比較簡單的一個小項目。我們把進銷存擴展一下,如圖14-3所示。 ![](https://box.kancloud.cn/2016-08-14_57b00363b0b46.jpg) 圖14-3 擴展后的進銷存示意圖 這是一個蜘蛛網的結構,別說是編寫程序了,就是給人看估計也能讓一大批人昏倒!每個對象都需要和其他幾個對象交流,對象越多,每個對象要交流的成本也就越大了,只是維護這些對象的交流就能讓一大批程序員望而卻步!從這方面來說,我們已經發現設計的缺陷了,作為一個架構師,發現缺陷就要想辦法修改。 大家都學過網絡的基本知識,網絡拓撲有三種類型:總線型、環型、星型。星型網絡拓撲如圖14-4所示。 在星型網絡拓撲中,每個計算機通過交換機和其他計算機進行數據交換,各個計算機之間并沒有直接出現交互的情況。這種結構簡單,而且穩定,只要中間那個交換機不癱瘓,整個網絡就不會發生大的故障。公司和網吧一般都采用星型網絡。我們是不是可以把這種星型結構引入到我們的設計中呢?我們先畫一個示意圖,如圖14-5所示。 ![](https://box.kancloud.cn/2016-08-14_57b00363c7089.jpg) 圖14-4 星型網絡拓撲 ![](https://box.kancloud.cn/2016-08-14_57b00363db24f.jpg) 圖14-5 修改后的進銷存示意圖 加入了一個中介者作為三個模塊的交流核心,每個模塊之間不再相互交流,要交流就通過中介者進行。每個模塊只負責自己的業務邏輯,不屬于自己的則丟給中介者來處理,簡化了各模塊之間的耦合關系,類圖如圖14-6所示。 ![](https://box.kancloud.cn/2016-08-14_57b00363f00e4.jpg) 圖14-6 修改后的進銷存類圖 建立了兩個抽象類AbstractMediator和AbstractColeague,每個對象只是與中介者Mediator之間產生依賴,與其他對象之間沒有直接關系,AbstractMediator的作用是實現中介者的抽象定義,定義了一個抽象方法execute,如代碼清單14-5所示。 代碼清單14-5 抽象中介者 public?abstract?class?AbstractMediator?{ ?????protected?Purchase?purchase; ?????protected?Sale?sale; ?????protected?Stock?stock; ?????//構造函數 ?????public?AbstractMediator(){ ?????????????purchase?=?new?Purchase(this); ?????????????sale?=?new?Sale(this); ?????????????stock?=?new?Stock(this); ?????}?? ?????//中介者最重要的方法叫做事件方法,處理多個對象之間的關系 ?????public?abstract?void?execute(String?str,Object...objects); } 再來看具體的中介者,我們可以根據業務的要求產生多個中介者,并劃分各中介者的職責。具體中介者如代碼清單14-6所示。 代碼清單14-6 具體中介者 public?class?Mediator?extends?AbstractMediator?{ ?????//中介者最重要的方法 ?????public?void?execute(String?str,Object...objects){ ?????????????if(str.equals("purchase.buy")){?//采購電腦 ????????????????????this.buyComputer((Integer)objects[0]); ?????????????}else?if(str.equals("sale.sell")){?//銷售電腦 ????????????????????this.sellComputer((Integer)objects[0]); ?????????????}else?if(str.equals("sale.offsell")){?//折價銷售 ????????????????????this.offSell(); ?????????????}else?if(str.equals("stock.clear")){?//清倉處理 ????????????????????this.clearStock(); ?????????????} ?????} ?????//采購電腦 ?????private?void?buyComputer(int?number){ ?????????????int?saleStatus?=?super.sale.getSaleStatus(); ?????????????if(saleStatus>80){??//銷售情況良好 ????????????????????System.out.println("采購IBM電腦:"+number?+?"臺"); ????????????????????super.stock.increase(number); ?????????????}else{??//銷售情況不好 ????????????????????int?buyNumber?=?number/2;??//折半采購 ????????????????????System.out.println("采購IBM電腦:"+buyNumber+?"臺"); ?????????????} ?????} ?????//銷售電腦 ?????private?void?sellComputer(int?number){ ?????????????if(super.stock.getStockNumber()<number){??//庫存數量不夠銷售 ????????????????????super.purchase.buyIBMcomputer(number); ?????????????} ?????????????super.stock.decrease(number); ?????} ?????//折價銷售電腦 ?????private?void?offSell(){ ?????????????System.out.println("折價銷售IBM電腦"+stock.getStockNumber()+"臺"); ?????} ?????//清倉處理 ?????private?void?clearStock(){ ?????????????//要求清倉銷售 ?????????????super.sale.offSale(); ?????????????//要求采購人員不要采購 ?????????????super.purchase.refuseBuyIBM(); ?????} } 中介者Mediator定義了多個private方法,其目的是處理各個對象之間的依賴關系,就是說把原有一個對象要依賴多個對象的情況移到中介者的private方法中實現。在實際項目中,一般的做法是中介者按照職責進行劃分,每個中介者處理一個或多個類似的關聯請求。 由于要使用中介者,我們增加了一個抽象同事類,三個具體的實現類分別繼承該抽象類,如代碼清單14-7所示。 代碼清單14-7 抽象同事類 public?abstract?class?AbstractColleague?{ ?????protected?AbstractMediator?mediator; ?????public?AbstractColleague(AbstractMediator?_mediator){ ?????????????this.mediator?=?_mediator; ?????} } 采購Purchase類如代碼清單14-8所示。 代碼清單14-8 修改后的采購管理 public?class?Purchase?extends?AbstractColleague{ ?????public?Purchase(AbstractMediator?_mediator){ ?????????????super(_mediator); ?????} ?????//采購IBM電腦 ?????public?void?buyIBMcomputer(int?number){ ?????????????super.mediator.execute("purchase.buy",?number); ?????} ?????//不再采購IBM電腦 ?????public?void?refuseBuyIBM(){ ?????????????System.out.println("不再采購IBM電腦"); ?????} } 上述Purchase類簡化了很多,也清晰了很多,處理自己的職責,與外界有關系的事件處理則交給了中介者來完成。再來看Stock類,如代碼清單14-9所示。 代碼清單14-9 修改后的庫存管理 public?class?Stock?extends?AbstractColleague?{ ?????public?Stock(AbstractMediator?_mediator){ ?????????????super(_mediator); ?????} ?????//剛開始有100臺電腦 ?????private?static?int?COMPUTER_NUMBER?=100; ?????//庫存增加 ?????public?void?increase(int?number){ ?????????????COMPUTER_NUMBER?=?COMPUTER_NUMBER?+?number; ?????????????System.out.println("庫存數量為:"+COMPUTER_NUMBER); ?????} ?????//庫存降低 ?????public?void?decrease(int?number){ ?????????????COMPUTER_NUMBER?=?COMPUTER_NUMBER?-?number; ?????????????System.out.println("庫存數量為:"+COMPUTER_NUMBER); ?????} ?????//獲得庫存數量 ?????public?int?getStockNumber(){ ?????????????return?COMPUTER_NUMBER; ?????} ?????//存貨壓力大了,就要通知采購人員不要采購,銷售人員要盡快銷售 ?????public?void?clearStock(){ ?????????????System.out.println("清理存貨數量為:"+COMPUTER_NUMBER); ?????????????super.mediator.execute("stock.clear"); ?????} } 銷售管理Sale類如代碼清單14-10所示。 代碼清單14-10 修改后的銷售管理 public?class?Sale?extends?AbstractColleague?{ ?????public?Sale(AbstractMediator?_mediator){ ?????????????super(_mediator); ?????} ?????//銷售IBM電腦 ?????public?void?sellIBMComputer(int?number){ ?????????????super.mediator.execute("sale.sell",?number); ?????????????System.out.println("銷售IBM電腦"+number+"臺"); ?????} ?????//反饋銷售情況,0~100變化,0代表根本就沒人買,100代表非常暢銷,出一個賣一個 ?????public?int?getSaleStatus(){ ?????????????Random?rand?=?new?Random(System.currentTimeMillis()); ?????????????int?saleStatus?=?rand.nextInt(100); ?????????????System.out.println("IBM電腦的銷售情況為:"+saleStatus); ?????????????return?saleStatus; ?????} ?????//折價處理 ?????public?void?offSale(){ ?????????????super.mediator.execute("sale.offsell"); ?????} } 增加了中介者,場景類也需要小小的改動,如代碼清單14-11所示。 代碼清單14-11 修改后的場景類 public?class?Client?{ ?????public?static?void?main(String[]?args)?{ ?????????????AbstractMediator?mediator?=?new?Mediator(); ?????????????//采購人員采購電腦 ?????????????System.out.println("------采購人員采購電腦--------"); ?????????????Purchase?purchase?=?new?Purchase(mediator); ?????????????purchase.buyIBMcomputer(100);?????????????? ?????????????//銷售人員銷售電腦 ?????????????System.out.println("\n------銷售人員銷售電腦--------"); ?????????????Sale?sale?=?new?Sale(mediator); ?????????????sale.sellIBMComputer(1); ?????????????//庫房管理人員管理庫存 ?????????????System.out.println("\n------庫房管理人員清庫處理--------"); ?????????????Stock?stock?=?new?Stock(mediator); ?????????????stock.clearStock(); ?????} } 在場景類中增加了一個中介者,然后分別傳遞到三個同事類中,三個類都具有相同的特性:只負責處理自己的活動(行為),與自己無關的活動就丟給中介者處理,程序運行的結果是相同的。從項目設計上來看,加入了中介者,設計結構清晰了很多,而且類間的耦合性大大減少,代碼質量也有了很大的提升。 在多個對象依賴的情況下,通過加入中介者角色,取消了多個對象的關聯或依賴關系,減少了對象的耦合性。
                  <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>

                              哎呀哎呀视频在线观看