成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

對象的自治和行為的擴展與適配

開發 開發工具
在壞的設計中,數據往往是分散的,甚至是雜亂的,這就好像一群失去意識的猛獸,我們無法控制、協調以及管理它們。

在壞的設計中,數據往往是分散的,甚至是雜亂的,這就好像一群失去意識的猛獸,我們無法控制、協調以及管理它們。這種漫無頭緒的散亂數據,猶如猛獸的肆意妄為,會給系統帶來無盡的災難。隨著系統的演化,這種災難會逐漸蔓延至系統的各個角落。因此,在面向對象設計過程中,對數據分類是識別對象的一個前提。但是,僅僅封裝了數據的對象,如果沒有操作數據的行為,仍舊是沒有意識的死亡對象。

[[213601]]

我始終認為,對象在擁有自己數據的情況下,應該是自治的。這種“自治”類似于SOA中服務自治的概念,但由于對象應該保持足夠合理的細粒度,因此這種自治是有限度的自治;或者說它體現的是專家的自治。如果對象擁有足夠的數據信息,就必須樹立這些信息的權威,這些信息的處理就應該由對象自己來完成。如果它擁有的信息量不夠,或者根本不具備,則可以委派給其他對象。此時,行為即對象的意識,是對象能夠自治的前提。

對象自治依賴于面向對象設計的一個重要原則,即對象的數據與行為應該封裝在一起。Craig Larman提出的“信息專家模式”正是說明了這一點,該模式認為擁有信息的對象才是處理這些信息的專家。

對象自治是一個很有趣的概念,我們把對象擬人化,使得對象成為組成社區的基本元素。在這個社區里,每個對象的行動都應該由自己來控制。無論是完成某個操作,還是發出請求,或者響應事件,對象都應該有自己的判斷。判斷的合理性來自于它掌握的信息量,以及我們賦予它的意識的靈性。在構建軟件系統時,我們的目標就是要搭建這樣一個由自治對象組成的社區,而不是無序的混沌世界。每當我們在操作數據時,發現數據開始具有發散、混亂、模糊、蔓延等特征時,就是封裝數據的信號。不管這些數據的數量,還是大小,它都應該作為對象存在于系統,同時該對象應具備操作該數據的能力。

例如在報表系統中,我們試圖將構建好的報表整體導出為Excel文件。我們為導出功能定義了專門的接口ExcelTableExporter,它接收一個報表對象和工作薄對象,導出報表到Excel文件中:

  1. public interface ExcelTableExporter { 
  2.     public void export(ReportTable table, WritableWorkbook workbook); 

這一接口的定義并無不妥之處。然而,當我們在實現export()接口方法時,事情開始變得難以控制。我們需要在export()方法中遍歷整個報表,獲得報表的行頭、列頭以及數據單元格,然后計算它們的坐標,獲得它們的格式,再寫入到Excel單元格中。顯然,ExcelTableExporter要做的事情太多了,而它所要處理的報表數據也開始變得發散而混亂。

雖然我們對報表進行了合理的分解與封裝,但坐標依舊是散亂的,格式也沒有和報表對象封裝在一起。組成報表的元素對象僅僅擁有展現的數據值,卻不知道自己該放在哪個位置,又該以什么面貌展現。換言之,這些組成報表的對象都不具備充分的自主意識,使得操作它們的ExcelTableExporter心力憔悴。它需要觀察每個報表元素對象的數據,元素之間的依賴關系,考慮如何計算它們的坐標,獲得符合客戶要求的格式。

簡言之,職責的控制權應該是擁有相關數據的報表對象,而不應該是ExcelTableExporter。

如果我們將這種展現和導出報表的功能看做是將報表數據繪制在Excel畫布上,那么ExcelTableExporter就好似一位不太高明的畫師,奔忙于全局的掌控與細節的刻畫,卻因為能力不夠而無法二者兼顧。

如果我們讓這些組成報表的元素對象擁有繪制自身的能力,境況是否煥然一新呢?此時,ExcelTableExporter只需要取出元素對象,放在Excel畫布上,它們自己就知道該往哪兒去,該怎么繪制,根本不用ExcelTableExporter來操心。

根據單一職責原則(SRP),報表元素對象與報表直接相關,本身不應該承擔繪制的責任,但放在導出報表這個場景來看,卻又是合乎情理的。而且,與繪制相關的數據本身就與報表數據直接相關,例如報表元素的坐標,就依賴于報表數據的個數,以決定它占用的行數和列數。報表的格式同樣設置在報表元數據中。不過,從抽象的角度來看,我們應該為其定義不同的接口,這也符合接口隔離原則(ISP)。同時,我們還需要考慮繪制行為的擴展。

例如,在未來我們可能需要考慮將報表繪制為HTML網頁。因此,我們可以定義一個繪制元素的接口:

  1. public interface DrawingElement { 
  2.     public void draw(ReportCanvas canvas); 
  3.     public object getElement(); 

draw()方法負責將報表元素繪制到ReportCanvas對象中。ReportCanvas體現了“畫布”的隱喻,作為載體用來添加繪制出來的報表元素。

  1. public interface ReportCanvas { 
  2.     public void addElement(DrawingElement element); 

對于Excel而言,實現draw()方法就是在內部創建單元格對象。如果使用開源項目jxl來完成excel文件的生成,則該單元格對象可以是Label對象,也可以是jxl.write.Number對象。不過,ReportCanvas是不關心這些的,它只需要能夠添加DrawingElement即可。這里就體現出了抽象DrawingElement的好處。

當報表元素對象在實現該接口時,如果是針對Excel的導出,就可以把諸如Label和Number這樣的單元格對象封裝到實現類中。例如報表中的行頭對象就可以實現DrawingElement接口:

  1. public class RowHeaderExcelElement implements DrawingElment{ 
  2.     private object cell; 
  3.  
  4.     @Override 
  5.     public void draw(ReportCanvas canvas) { 
  6.         canvas.addElement(this); 
  7.     } 
  8.  
  9.     @Override 
  10.     public object getElement() { 
  11.         if (isNumber()) { 
  12.             cell = createNumberCell(); 
  13.         } else { 
  14.             cell = createLabelCell();  
  15.         } 
  16.         return cell; 
  17.     } 

這里的RowHeaderExcelElement類就體現了“自治”思想,因為它自己知道該如何將自己擁有的數據繪制到ReportCanvas。

而從功能擴展的角度講,如果將來需要支持Html,就可以定義新的RowHeaderHtmlElement類實現DrawingElement接口。

因為引入了DrawingElement接口,報表元素對象就將繪制元素對象的數據與行為都封裝了起來,使其成為了自治的對象。由于報表元素對象自身具備繪制功能,使得ExcelTableExporter的工作變得輕松自如,只需發出繪制的請求即可:

  1. for (DrawingElement element : table.getReportUnits()) { 
  2.     element.draw(canvas); 

通過合理地將職責進行轉移,盡可能站在每個對象自身的角度進行合理的職責分配,從原則上實現各個對象的“自治”,就能夠各司其職,避免出現一個龐大的無所不能的“上帝”對象。

【本文為51CTO專欄作者“張逸”原創稿件,轉載請聯系原作者】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2009-03-16 09:16:13

行為擴展WCF.NET

2024-05-28 09:49:42

Python對象函數

2009-11-06 14:08:06

WCF行為擴展

2009-09-04 14:00:22

上網行為管理網絡應用

2011-10-27 12:04:44

流量監控上網行為管理

2010-02-26 10:46:12

WCF行為擴展

2009-06-30 11:27:25

JSP include

2009-11-23 09:34:05

WPF本質

2023-06-28 07:54:44

數據治理數據分析

2016-01-31 17:45:31

2022-11-27 23:37:33

Agent對象存儲

2009-04-21 09:00:10

IT業工作調整失業

2022-09-02 09:06:58

惡意擴展Chrome

2022-03-11 11:51:16

自動駕駛智能技術

2013-01-14 16:10:06

2018-04-02 13:42:36

大數據數據泄露監管

2010-05-12 11:50:29

2017-05-16 09:25:46

混合云容量功能

2009-08-28 13:57:29

virtual ove擴展點

2020-09-18 07:00:00

實體框架開發工具
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 蜜桃在线视频 | 国产日韩一区二区 | 三级在线观看 | 国产aaaaav久久久一区二区 | www.国产91| 久久精品一区 | 成人免费视频网站在线看 | 国产成人一区二区三区久久久 | 久久不卡视频 | 日本欧美国产在线观看 | 激情综合五月 | 我要看黄色录像一级片 | 亚洲永久字幕 | 日本中出视频 | 视频一区二区三区中文字幕 | 99久久久国产精品免费消防器 | 秋霞影院一区二区 | 久久中文一区二区 | 欧美一区二区三区在线观看视频 | 麻豆久久久久 | 福利精品在线观看 | 午夜欧美一区二区三区在线播放 | 精品91av| 一区二区三区四区免费在线观看 | 一区二区精品 | 四虎影院新地址 | 亚洲喷水 | 久久久人 | 日本免费在线看 | 国外成人在线视频 | 欧美一区二区综合 | 91在线观看免费 | 精品一区电影 | 欧美日韩福利视频 | 亚洲精品国产综合区久久久久久久 | 亚洲成人av | 亚洲一区二区精品 | 免费视频一区二区三区在线观看 | 日韩视频在线观看一区二区 | 精品国产一区二区三区性色 | 男女羞羞视频免费看 |