《資訊話題》
  細說「軟體工廠」概念（二）
    吳信輝
    （文續第2125期第198頁）
    處理複雜性
      在前一期（2125）的內容介紹中，我們對於軟體工廠概念，曾經
    提到過軟體開發的基本問題：軟體設計、軟體發展對於軟體開發人
    員來說，是非常複雜的一門學問；而造成軟體開發很複雜的原因，
    主要有兩個主要的因素，分別是：複雜性（complexity）與改變
    （change）。在此部份，我們將參酌『軟體工廠』一書的內容，再
    輔以相關資訊，在接下來的內容繼續說明【註一】。首先，我們先
    探討複雜性的問題。
    一、什麼是軟體複雜性問題
      軟體開發面臨到的第一個大問題，就是複雜性的問題；而複雜性
    度的問題是怎麼發生的，大略可以歸納為兩個原因：根本性的複雜
    性（inherent complexity）和附帶性的複雜性（accidental complexity
），
    說明如下：
    (一)根本性的複雜性
      從『軟體工廠』一書的原文中，是這麼定義根本性的複雜性的：
   　「只要軟體一產生，根本性的複雜性問題會開始存在。直觀的來看，
     我們可以將根本性的複雜性視為一個功能，這一個功能必須同時解
     析一個問題。而這一個問題的對象是誰？內容是什麼？其實就是一
     群軟體需求以及這一群軟體需求間的相互關係。」
　   筆者在此簡單的舉一個例子說明根本性的複雜性問題，例如：某家
     公司需要一個員工基本資料的管理系統，此時軟體的需求就開始出
     現；當軟體需求出現的時候，就代表軟體需要開始被設計出來，相
     關的軟體開發人員就要來分作系統分析等一連串的工作。例如：資
     料庫的設計：員工基本資料區分為幾個欄位來擺放適當的資訊；呈
     現介面的設計：要秀出哪一些欄位，哪一些欄位是機密性資料，需
     要隱藏的；資料編修介面的設計：可以修改哪那幾個欄位的資訊等
     等。而軟體開發人員就要根據這些需求，經過分析。為何需要分析
     呢？因為需求之中許多資料是要轉換成資訊的，這一些關係不是直
     接的，就好像我們從甲地要到乙地，直接走最近的路是最方便的，
     如果有人要求你必須先走到丙地，那絕對是需要多花費一些力氣的；
     此對應到我們的人際關係也是一樣的，以感情關係為例：兩個人之
     間的關係是最容易處理的，但是三個人就比較麻煩，牽涉到愈多人
     的關係就會變得更難以處理，這就是根本性的複雜性問題。
　   只要軟體需求一產生，這個複雜性問題就會隨之產生，所以我們稱
     它為根本性的複雜性問題。而根本性的複雜性問題是與軟體需求的
     程度息息相關的，以剛剛所舉的例子為例：當此公司對於員工基本
     資料管理系統之需求滿足的同時，一定會再產生新的需求，例如員
     工薪資管理系統、員工考勤系統等，此時，原有的資料庫必須再加
     入新的欄位資訊（薪水、上下班時間等），其間的關係也會變得更
     複雜。因此，軟體根本性的複雜性問題，與軟體的規模是正相關的，
     對於軟體的需求愈來愈多，軟體規模越大，則所需要的軟體功能也
     愈來愈複雜，根本性的複雜性問題也會愈大。
    (二)附帶性的複雜性
     附帶性的複雜性問題與根本性的複雜性問題不同，後者與軟體的需
     求有關，但是前者是解決方案（solution）的產物，也就是我們在
     軟體開發過程中，應用相關的輔助工具所衍生出來的後遺症。從原
     文中，我們再來分析其原意：
    「直觀地來看，我們可以將附帶性的複雜性視為一個功能，這一個
     功能必須同時組合一個解決方案。而這一個解決方案的對象是誰？
     內容是什麼？其實就是一群軟體需求以及這一群軟體需求間的相互
     關係。」
   　依據筆者的解讀，可以用筆者參加JavaTwo軟體開發者大會時所聽
     過的一段話來做解釋：大抵上開發Java程式的人，以開發工具來區
     分，可以區分為兩種，一種是神等級的人，另外一種就是非神等級
     的人（例如筆者）。前者所使用的開發工具是什麼呢？很簡單，記
     事本就可以了，或是Linux的Vi；而後者使用的開發工具種類比較多，
     從Ultraedit、Eclipse到JBuilder等等。沒有錯，後者的輔助輔助
     工具是多了很多，但是要學會用那麼多輔助工具，也是需要花費一
     段時間去學習。
　   同樣的例子也發生在微軟的Visual Studio（VS）開發工具上，VS
     以它的拖拉設計工具自豪，但是以此為開發工具的軟體開發人員還
     是需要一段比較長的學習曲線才能適當的利用。
　    從另外一個層面來看，軟體輔助工具或是愈來愈高階的程式語言，
    主要目的都是希望可以將軟體開發的問題簡單化，但是筆者認為軟
    體開發是遵守物理學中的能量守橫定理的，當我們利用工具將問題
    給簡單化之後，其實就會在另外一面將被簡單化的部份，再複雜化
    回來，因此有些軟體開發人員，寧願使用他們原來的方法，也不願
    意使用這一些工具。以J2EE為例，他利用了許多的設計模式的觀點，
    因此產生下面幾樣的特性：
    1.軟體處理流程在實作的階段被分割為好幾個分散式的元件（component）
。
    2.這一些元件又利用介面（interface）來呈現不同性質的方法（method）
。
    3.再利用物件類別（class）來實作這些介面。
    4.再利用服務（system service）來初始化及註冊這一些元件的程
      序（instance，或是稱實例），以及管理他們狀態、資源的使用
      等內容。
    5.在呈現面部份，J2EE利用JSP技術、HTML的form、JavaScript、
      tag libraries以及servlets來呈現資訊給使用者觀看。
    6.利用資料存取物件、O/R Mapping等工具來管理資料的存取。
    7.上述的這些內容分佈在不同的技術與檔案上，例如利用HTML與XML
      檔案（例如：web.xml），SQL的DDL與DML檔案【註二】，資源設
      定檔（例如：xx.properities）。
    8.上述這些工具大部份需要輔助工具，例如：編譯器、介面產生器
      以及相關的lib檔案（例如：需要用到那一些JAR檔），產生部署
      時所需要的相關檔案，來進行部署。
      上面所說的這一些東西，只是J2EE非常非常簡單且概略性地描述
    而已，要做好一個Java的軟體開發者（或稱為Java Developer），
    可以選擇去上這些相關的課程。因此軟體輔助工具的發達，也代表
    我們要更依賴軟體，軟體架構的分工愈仔細，其實也就是代表我們
    在軟體開發的過程中，需要學習更多的東西。
      附帶性的複雜性問題產生的來源，可以分為兩類，第一類是特性
    去區域化（Feature Delocalization），有關於特性（feature）的
    定義請參閱【註三】；第二類是錯誤層級的抽象化（Working at the
    Wrong Level of Abstraction）。在本期中，我們將先討論特性去
    區域化的問題。
    1.特性去區域化
　    首先我們需要先定義區域化（localization）與去區域化
      （delocalization），依據筆者的解讀，簡單地說，就是解決該
      需求的程式碼是集中或是分散，集中於同一個地方或是相近的地
      方，我們就可以稱它為區域化，同理，如果是分散的，我們就稱
      它為去區域化。
　    在軟體工廠的原文中提到：「早期的物件導向觀念強調需要與解
      決方案的一對一的對應，這樣的結果造成過多的關係存在。」筆
      者先前曾經提過，關係越複雜就是代表軟體也會越來越複雜；另
      外，原文中也提到另一點發現：「問題特性是被需求所定義的，
      而解決方案特性是由實作所定義的，但是需求與實作，是兩個不
      同的觀念」。例如：問題特性幾乎都是區域化的，而解決方案特
      性在需求中，卻幾乎都是去區域化的。例如一個網路購物商品訂
      購的功能，可以放在一個分析物件類別中可以完成，但是在需求
      的定義中，網頁必須經過不同的分析類別，包括安全性處理類別、
      資料驗證類別與資料庫連接類別等。而解決方案特性幾乎都是區
      域化的，但是，問題特性在實作中，卻幾乎都是去區域化的。例
      如：一個商品訂購的網頁我們是把它視為一個集合，但是商品訂
      購功能卻需要不同網頁的集合，包括商品資訊的網頁以及購買者
      資訊的網頁。
　    這樣的狀況我們可以用圖示的方法來說明，請參閱【圖一】，
      【圖一】是一個特性去區域化示意圖，代表一個網路購物商城應
      用系統的概念圖，圓形代表的是需求，方塊代表的是解決方案，
      我們將需求與解決方案區分為兩個區域，以Order的功能需求為例，
      可以看到它在解決方案中是被分散到不同的實作分類裡面，而以
      分散式元件的解決方案為例，我們也可以看到也是被分散到不同
      的需求分類中，因此，這樣的系統是非常複雜的。如果這一個系
      統的問題再沒有經過一個比較完善的定義過程的話，也就是需求
      沒有經過比較好的分析的話，那麼問題特性將更不會被區域化，
      也就是代表這一個系統會更加的複雜。
    　這樣的系統通常會產生兩個問題，第一是未來系統的可描繪能力
      的問題（Traceability Problem），第二個問題是未來系統重建
      的問題（Reconstruction Problem），分別說明如下：
    (1)系統的可描繪能力問題：
　     這一類的問題通常發生於實作問題特性的解決方案特性沒有清楚
       的設定，例如一個問卷系統，使用JavaBean來處理不同的JSP頁
       面的邏輯，但是在原始碼中因為並沒有詳細的說明每一個JavaBean
       的使用目的，當這一個問卷系統的某項功能需要重新設計的時候，
       整個系統的更改會變得非常地困難，因為，我們不會詳細知道，
       如果某個功能改變後，是不是也會連帶的影響到其它的功能。以
       J2EE為例，要我們單單從相關程式碼中去瞭解系統，也是相當困
       難的一件事情，因此詳細的解決方案特性的描述，是非常重要的。
    (2)系統重建問題：
　     我們再以問卷系統來說明，如果沒有解決方案特性沒有被清楚的
       描述，或是有關軟體設計的相關資訊都已經遺失的話，在系統重
       建時，也會遇到同樣的狀況，就好像生物的複製技術，要複製的
       個體的基因如果是殘缺不全的，那麼複製出來的複製品也一定會
       是殘缺不全的。
      關於特性去區域化的問題，我們可以得到以下的結論：過於強調
    一對一的問題解決方式問題需求必須轉變分析方法，務必使問題特
    性與解決方案特性可以盡量的區域化，以減少整個軟體系統的複雜
    程度，有關於這方面的討論，讀者也可以參閱【註四】，在下（2201）
    期中，我們將繼續探討錯誤層級的抽象化等議題。（待續）
    參考資料：
    【註一】：本文的內容參酌“Software Factories”一書，有興趣
              的讀者可以直接購買該書參考，該書相關資訊如下：
              Jack Greenfield, Keith Short, “Software Factories,
              ”Addison-Wesley, 2004.
    【註二】：這兩個名詞是資料庫的名詞，基本定義如後：DDL：data
              definition language，資料定義語言，簡單來說，就是
              用來定義資料庫與刪除資料庫的語法。DML：data 
manipulation
              language，資料操作語言，對資料進行查詢（select）、
              新增（insert）、修改（update）與刪除（delete）。
              可以參考下列網址：
              http://www.tomjewett.com/dbdesign/dbdesign.php?
page=ddldml.php&imgsize=medium
    【註三】：特性（feature）的定義，什麼是feature？本文利用軟
              體工廠原文中的解釋以及其參考資料，特性是一個代名
              詞，代表的是軟體需求中對於功能性與非功能性需求的
              邏輯，詳細資料可以參閱：J. Bosch, “Design and Use
              of Software Architectures: Adopting and evolving a
              product-line approach”, Addison-Wesley, 2000.
    【註四】：有關於處理複雜度，大陸的程序員雜誌也在2005年4月份
              的內容中有提到，大陸某網友的Blog中有摘錄相關內容，
              有興趣的讀者可前往該Blog參考，參考網址：
http://blog.csdn.net/magus_yang/archive/2004/08/12/72656.aspx
