熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

使用設計模式改善程序結構

2013-11-23 19:46:24  來源: Java高級技術 

  設計模式是對特定問題經過無數次經驗總結後提出的能夠解決它的優雅的方案但是如果想要真正使設計模式發揮最大作用僅僅知道設計模式是什麼以及它是如何實現的是很不夠的因為那樣就不能使你對於設計模式有真正的理解也就不能夠在自己的設計中正確恰當的使用設計模式本文試圖從另一個角度(設計模式的意圖動機)來看待設計模式通過這種新的思路設計模式會變得非常貼近你的設計過程並且能夠指導簡化你的設計最終將會導出一個優秀的解決方案
  
  
  
  介紹
  
  
  
  在進行項目的開發活動中有一些設計在項目剛剛開始工作的很好但是隨著項目的進展發現需要對已有的代碼進行修改或者擴展導致這樣做的原因主要有新的功能需求的需要以及對系統進一步理解在這個時候我們往往會發現進行這項工作比較困難即使能完成也要付出很大的代價此時一個必須要做的工作就是要對現有的代碼進行重構(refactoring)通過重構使得我們接下來的工作變得相對容易
  
  
  
  重構就是在不改變軟件系統代碼的外部行為的前提下改善它的內部結構重構的目標就是使代碼結構更加合理富有彈性能夠適應新的需求新的變化對於特定問題給出優美解決方案的設計模式往往會成為重構的目標而且一旦我們能夠識別出能夠解決我們問題的設計模式將會大大簡化我們的工作因為我們可以重用別人已經做過的工作但是在我們的原始設計和最終可能會適用於我們的設計模式間的過渡並不是平滑的而是有一個間隙這樣的結果就是即使我們已經知道了很多的設計模式面對我們的實際問題我們也沒有一個有效的方法去判斷哪一個設計模式適用於我們的系統我們應該去怎樣應用它
  
  
  
  造成上述問題的原因往往是由於過於注重設計模式所給出的解決方案這個結果而對於設計模式的意圖以及它產生的動機卻忽略了然而正是設計模式的意圖動機促使人們給出了一個解決一類問題的方案這個結果設計模式的動機意圖體現了該模式的形成思路所以更加貼近我們的實際問題從而會有效的指導我們的重構歷程本文將通過一個實例來展示這個過程
  
  
  
  在本文中對例子進行了簡化這樣做是為了突出問題的實質並且會使我們的思路更加清晰思路本身才是最重要最根本的簡化了的例子不會降低我們所展示的思路方法的適用性
  
  
  
  問題描述
  
  
  
  一個完善的軟件系統必須要對出現的錯誤進行相應的處理只有這樣才能使系統足夠的健壯我准備以軟件系統中對於錯誤的處理為例來展示我所使用的思路方法
  
  
  
  在一個分布式的網管系統中一個操作往往不會一定成功常常會因為這樣或者那樣的原因失敗此時我們就要根據失敗的原因相應的處理使錯誤的影響局限在最小的范圍內最好能夠恢復而不影響系統的正常運行還有一點很重要那就是在對錯誤進行處理的同時一定不要忘記通知系統的管理者因為只有管理者才有能力對錯誤進行進一步的分析從而查找出錯誤的根源從根本上解決錯誤
  
  
  
  下面我就從錯誤處理的通告管理者部分入手開始我們的旅程假定一個在一個分布式環境中訪問數據庫的操作那麼就有可能因為通信的原因或者數據庫本身的原因失敗此時我們要通過用戶界面來通知管理者發生的錯誤簡化了的代碼示例如下
  
  
  
  
  
  /* 錯誤碼定義 */
  
  class ErrorConstant
  
  {
  
  public static final int ERROR_DBACCESS = ;
  
  public static final int ERROR_COMMUNICATION = ;
  
  }
  
  
  
  /* 省略了用戶界面中的其他的功能 */
  
  class GUISys
  
  {
  
  public void announceError(int errCode) {
  
  
  
  switch(errCode) {
  
  
  
  case ErrorConstantERROR_DBACCESS:
  
  /* 通告管理者數據庫訪問錯誤的發生*/
  
  break;
  
  
  
  case ErrorConstantERROR_COMMUNICATION:
  
  /* 通告管理者通信錯誤的發生*/
  
  break;
  
  
  
  }
  
  }
  
  }
  
  
  
  
  
  開始這段代碼工作的很好能夠完成我們需要的功能但是這段代碼缺少相應的彈性很難適應需求的變化
  
  
  
  問題分析
  
  
  
  熟悉面向對象的讀者很快就會發現上面的代碼是典型的結構化的方法結構化的方法是以具體的功能為核心來組織程序的結構它的封裝度僅為即僅有對於特定的功能的封裝(函數)這使得結構化的方法很難適應需求的變化面向對象的方法正是在這一點上優於結構化的方法在面向對象領域是以對象來組成程序結構的一個對象有自己的職責通過對象間的交互來完成系統的功能這使得它的封裝度至少為即封裝了為完成自己職責的方法和數據另外面向對象的方法還支持更高層次的封裝比如通過對於不同的具體對象的共同的概念行為進行描述我們可以達到級的封裝度- 抽象的類(在Java中就是接口)封裝的層次越高抽象的層次就越高使得設計代碼有越高的彈性越容易適應變化
  
  
  
  考慮對上一節中的代碼如果在系統的開發過程中發現需要對一種新的錯誤進行處理比如用戶認證錯誤我們該如何做使得我們的系統能夠增加對於此項功能的需求呢?一種比較簡單直接的做法就是在增加一條用來處理此項錯誤的case語句是的這種方法的確能夠工作但是這樣做是要付出代價的
  
  
  
  首先隨著系統的進一步開發可能會出現更多的錯誤類型那麼就會導致對於錯誤的處理部分代碼冗長不利於維護其次也是最根本的一點修改已經能夠工作的代碼很容易引入錯誤並且在很多的情況下錯誤都是在不經意下引入的對於這種類型的錯誤很難定位有調查表明我們在開發過程中用於修正錯誤的時間並不多大部分的時間是在調試發現錯誤在面向對象領域有一個很著名的原則OCP(OpenClosed Principle)它的核心含意是一個好的設計應該能夠容納新的功能需求的增加但是增加的方式不是通過修改又有的模塊(類)而是通過增加新的模塊(類)來完成的如果一個設計能夠遵循OCP那麼就能夠有效的避免上述的問題
  
  
  
  要是一個設計能夠符合OCP原則就要求我們在進行設計時不能簡單的以功能為核心要實現OCP的關鍵是抽象抽象表征了一個固定的行為但是對於這個行為可以有很多個不同的具體實現方法通過抽象我們就可以用一個固定的抽象的概念來代替哪些容易變化的數量眾多的具體的概念並且使得原來依賴於哪些容易變化的概念的模塊依賴於這個固定的抽象的概念這樣的結果就是系統新的需求的增加僅僅會引起具體的概念的增加而不會影響依賴於具體概念的抽象體的其他模塊在實現的層面上抽象體是通過抽象類來描述的在Java中是接口(interface)關於OCP的更詳細描述請參見參考文獻[]
  
  
  
  既然知道了問題的本質以及相應的解決方法下面就來改善我們的代碼結構
  
  
  
  初步方案
  
  
  
  讓我們重新審視代碼看看該如何進行抽象在錯誤處理中需要處理不同類型的錯誤每個具體的錯誤具有特定於自己本身的一些信息但是它們在概念層面上又是一致的比如都可以通過特定的方法接口獲取自已內部的錯誤信息每一個錯誤都有自己的處理方法由此可以得到一個初步的方案可以定義一個抽象的錯誤基類在這個基類裡面定義一些在概念上適用於所有不同的具體錯誤的方法每個具體的錯誤可以有自己的不同的對於這些方法的實現代碼示例如下
  
  
  
  interface ErrorBase
  
  {
  
  public void handle()
  
  public String getInfo();
  
  }
  
  
  
  class DBAccessError implements ErrorBase
  
  {
  
  public void handle() {
  
  /* 進行關於數據庫訪問錯誤的處理 */
  
  }
  
  
  
  public String getInfo() {
  
  /* 構造返回關於數據庫訪問錯誤的信息 */
  
  }
  
  }
  
  
  
  class CommunicationError implements ErrorBase
  
  {
  
  public void handle() {
  
  /* 進行關於通信錯誤的處理 */
  
  }
  
  
  
  public String getInfo() {
  
  /* 構造返回關於通信錯誤的信息 */
  
  }
  
  }
  
  
  
  
  
  這樣我們就可以在錯誤發生處構造一個實際的錯誤對象並以ErrorBase引用它然後交給給錯誤處理模塊此時錯誤處理模塊就僅僅知道一個類型ErrorBase而無需知道每一個具體的錯誤類型這樣就可以使用統一的方式來處理錯誤了代碼示例如下
  
  
  
  class GUISys
  
  {
  
  public void announceError(ErrorBase error) {
  
  /* 使用一致的方式處理錯誤 */
  
  er
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27432.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.