JavaExplore

          一切像霧像雨又像風(fēng)
          posts - 19, comments - 45, trackbacks - 0, articles - 0

          2006年9月12日

               摘要: 3 數(shù)據(jù)源處理 JFreeChart 中的數(shù)據(jù)源是DataSet接口類型。該接口有三個(gè)主要的子類接口:CategoryDataset、PieDataset、SeriesDataset CategoryDataset 接口的實(shí)現(xiàn)類基本上都維護(hù)了一...  閱讀全文

          posted @ 2006-09-12 23:36 JavaExplore 閱讀(6550) | 評(píng)論 (15)編輯 收藏

          1、策略:常用于算法族,將算法從依賴的環(huán)境中抽象出來(lái)形成
          2、狀態(tài):和策略非常接近,使用于有明顯狀態(tài)變化的時(shí)候
          3、命令:命令的發(fā)起與執(zhí)行解藕,命令類可以獨(dú)立演化,有助于做redo undo操作以及記錄所執(zhí)行的命令
          4、解釋:用于文法的解析
          5、迭代子:java中有現(xiàn)成的實(shí)現(xiàn),iterator
          6、觀察者:常見(jiàn),類似與模型視圖的關(guān)系,java中提供了oberver類和observable接口
          7、調(diào)停者:處理混亂的類交互,抽象出中間類,將類間的交互都通過(guò)這個(gè)類完成
          8、模版:將擁有同一父類的多個(gè)具體子類的共同操作提取出來(lái)形成抽象模版類
          ???????? 原則:具體的私有屬性應(yīng)該放到具體類中,抽象類中調(diào)用屬性通過(guò)屬性方法而不是直接調(diào)用屬性
          ?????????????? 將私有屬性放到具體的類中,才能方便對(duì)父類進(jìn)行多個(gè)實(shí)現(xiàn)。
          ???????? 將行為看作劃分類的標(biāo)準(zhǔn),以前我都是將數(shù)據(jù)模型看作劃分類的思想,以后應(yīng)該重新審視行為在類中的重要作用,特別是在的繼承等級(jí)中。

          posted @ 2006-09-12 23:33 JavaExplore 閱讀(381) | 評(píng)論 (0)編輯 收藏

          2006年9月1日

          1 簡(jiǎn)介

          JFreeChart SourceForge.net 上的一個(gè)開(kāi)源項(xiàng)目,它的源碼和 API 都可以免費(fèi)獲得。 JFreeChart 的功能非常強(qiáng)大,可以實(shí)現(xiàn)餅圖 ( 二維和三維 ) ,  柱狀圖  ( 水平 , 垂直 ), 線圖 , 點(diǎn)圖 , 時(shí)序圖 , 甘特圖 股票行情圖 , 混和圖 溫度計(jì)圖 刻度圖等常用商用圖表,   圖形可以導(dǎo)出成 PNG JPEG 格式,同時(shí)還可以與 PDF EXCEL 關(guān)聯(lián),支持對(duì)圖形的放大、縮小,支持常見(jiàn)圖形的 3D 顯示。

          2 圖形 對(duì)象的處理

          2 1 JFreeChart對(duì)象

          JFreeChart 可以生成很多圖形對(duì)象,它的工廠類提供了 33 個(gè)工廠方法用于生成不同的圖形對(duì)象(具體的工廠方法可以參見(jiàn) JFreeChart API 手冊(cè)或者源碼中的 ChartFactory )。              JFreechart 對(duì)圖形對(duì)象的抽象具體化。圖形對(duì)象( JFreeChart ),由 Title( 主標(biāo)題 ) , SubTitle (子標(biāo)題 ) , Plot (圖形的繪制結(jié)構(gòu))等幾個(gè)主要對(duì)象組成。各個(gè)組成部分如下圖所示:

          這是一個(gè) JFreeChart 對(duì)象,上面的“ chart 標(biāo)題”是 Title 對(duì)象,中間區(qū)域是 Plot 對(duì)象(包括繪圖區(qū)域和坐標(biāo)軸區(qū)域),下面的區(qū)域是 LegendTitle 對(duì)象,是一種 SubTitle 對(duì)象。

          每個(gè) JFreeChart 對(duì)象只能有 1 個(gè) Title 對(duì)象, 1 個(gè) Plot 對(duì)象,可以有多個(gè) SubTitle 對(duì)象。 JFreeChart 對(duì)象可以進(jìn)行的操作有:背景的設(shè)置(背景顏色、背景圖片、透明度等)、邊框的設(shè)置(是否可見(jiàn)、筆畫(huà)、 Paint 等)、渲染方式的設(shè)置、標(biāo)題對(duì)象的設(shè)置、子標(biāo)題對(duì)象的增刪查操作。(本文中的所有操作都不提供代碼級(jí)的介紹,可參見(jiàn) API 手冊(cè)或者源碼)

          2 2 主標(biāo)題對(duì)象

          主標(biāo)題對(duì)象是 TextTitle 類型,可以進(jìn)行的操作有:背景設(shè)置、字體設(shè)置(字體類型、顏色、內(nèi)容、對(duì)齊方式等操作)、 tooltip 設(shè)置、 URL 設(shè)置。

          2 3 Plot 對(duì)象

          Plot 對(duì)象是圖形的繪制結(jié)構(gòu)對(duì)象。 JFreeChart 中含有很多不同的 Plot 對(duì)象,每一種圖形對(duì)象中的 Plot 對(duì)象都在實(shí)例化的時(shí)候創(chuàng)建。所有的 Plot 共有的操作有:背景設(shè)置(背景顏色、背景圖片、透明度等)、前景透明度設(shè)置、無(wú)數(shù)據(jù)存在情況的設(shè)置(顯示的字符內(nèi)容、顯示的字體、顯示的 Paint )、放大縮小比例的設(shè)置,大部分 Plot 對(duì)象還有設(shè)置 Datset 、設(shè)置 Renderer 對(duì)象操作。

          JFreeChart 中有 18 Plot 抽象類的具體實(shí)現(xiàn)類。 Plot 的具體實(shí)現(xiàn)類主要由以下重要對(duì)象組成: Renderer 對(duì)象(圖形的繪制單元——繪圖域) Datset (圖形的數(shù)據(jù)源), DomainAxis (區(qū)域軸,相當(dāng)于 x 軸), RangeAxis (范圍軸,相當(dāng)于 y 軸)。不同的 Plot 對(duì)象組成方式不盡相同,有的不含有 Renderer 對(duì)象,比如 CompassPlot ContourPlot MultiplePiePlot 、 PiePlot 等,有的不含有 DomainAxis RangeAxis 對(duì)象,另外除了 FastScatterPlot 類都含有 Datset 對(duì)象, FastScatterPlot 使用 float 的二維數(shù)組充當(dāng)數(shù)據(jù)源。尤其說(shuō)明一點(diǎn),餅狀圖相關(guān)的 Plot 對(duì)象( MultiplePiePlot PiePlot PiePlot3D 、 RingPlot )中都不含有 Renderer 對(duì)象、 DomainAxis 對(duì)象、 RangeAxis 對(duì)象。

          一般來(lái)說(shuō), Datset 對(duì)象存儲(chǔ)數(shù)據(jù)模型, Renderer 對(duì)象存儲(chǔ)顯示模型, Plot 對(duì)象根據(jù) Datset 對(duì)象、 Renderer 對(duì)象完成畫(huà)圖操作。

          仍以上面的圖形講解 Plot 對(duì)象的組成。

             上圖的中間區(qū)域是是一個(gè) XYPlot 對(duì)象。其中的折線部分即是圖形的繪制單元 Renderer 對(duì)象。 X 軸是 DomainAxis , y 軸是 RangeAxis ,其中 Datset 對(duì)象屬于數(shù)據(jù)模型范疇,是 UI 不可見(jiàn)對(duì)象。該圖中的 plot 背景色、網(wǎng)格線的各種設(shè)置可以通過(guò) XYPlot 對(duì)象本身完成。

                 下面講解 Renderer 對(duì)象、 Axis 對(duì)象( X 軸、 y 軸都屬于 Axis 對(duì)象), Datset 對(duì)象在后續(xù)章節(jié)中專門講解。

          2 31 Renderer對(duì)象

          Renderer 對(duì)象是圖形的繪制單元。 JFreeChart 提供了兩個(gè)接口 CategoryItemRenderer XYItemRenderer 1 個(gè)抽象類 AbstractRenderer 供具體的 Renderer 類實(shí)現(xiàn),給出了將近 50 種具體實(shí)現(xiàn)類。

          一般來(lái)說(shuō) Renderer 對(duì)象可進(jìn)行的操作有:對(duì) item label (下圖中的柱狀圖上的紅色數(shù)字即為 item label 的示例)的默認(rèn)設(shè)置( item label 的產(chǎn)生方式、是否可見(jiàn)、字體、 Paint 、正反向 item label 的位置設(shè)置等)、繪制圖形的邊框默認(rèn)設(shè)置( Paint 、筆畫(huà)、是否可見(jiàn)等)、繪制圖形的默認(rèn)設(shè)置(形狀、筆畫(huà)、是否可見(jiàn)、對(duì)應(yīng)的圖例中是否可見(jiàn)等,折線圖還有線條是否可見(jiàn)、折點(diǎn)圖形是否可見(jiàn)、折點(diǎn)圖形是否填充、折點(diǎn)圖形的形狀、對(duì)應(yīng)的圖例中線條是否可見(jiàn)、圖形是否可見(jiàn)、整體是否可見(jiàn)等)、以及對(duì)指定 item label 的設(shè)置、指定繪制圖形的設(shè)置??梢哉f(shuō)和具體繪制的圖形相關(guān)的屬性都可以通過(guò) Renderer 對(duì)象設(shè)置。

          不同的 Renderer 的實(shí)現(xiàn)類實(shí)現(xiàn)了不同的顯示方式,在含有 Renderer 對(duì)象的 JFreeChart 對(duì)象中, R enderer 對(duì)象決定了JFreeChart對(duì)象的顯示方式。例如:柱狀圖的Plot對(duì)象中默認(rèn)的Renderer對(duì)象是 CategoryItemRenderer 對(duì)象,通過(guò)設(shè)置 Plot 對(duì)象的Renderer對(duì)象 LineAndShapeRenderer ,則柱狀圖變?yōu)榫€圖。使用中一般不需要顯式的實(shí)例化一個(gè) R enderer 對(duì)象,一般通過(guò) JFreeChart 對(duì)象的 Plot 對(duì)象調(diào)用現(xiàn)有的 R enderer 對(duì)象進(jìn)行重新設(shè)置等操作。

          2 32 Axis對(duì)象

          JFreeChart 提供了兩種類型的坐標(biāo)軸: CategoryAxis (等級(jí)軸)和 ValueAxis (值軸), ValueAxis 又有 3 個(gè)子類: DateAxis (時(shí)間軸)、 NumberAxis (數(shù)字軸)、 PeriodAxis (時(shí)期軸)。這些坐標(biāo)軸還有更詳細(xì)的子類,不再一一列舉

          Axis 對(duì)象可進(jìn)行的操作有:標(biāo)題的設(shè)置(內(nèi)容、字體、Paint、顯示角度等)、坐標(biāo)線的設(shè)置(筆畫(huà)、Paint、是否可見(jiàn)等)、刻度線的設(shè)置(是否可見(jiàn)、筆畫(huà)、Paint、位于繪圖區(qū)域的長(zhǎng)度、位于繪圖區(qū)域外的長(zhǎng)度等)、刻度標(biāo)示的設(shè)置(筆畫(huà)、Paint、字體、與軸的距離等)、坐標(biāo)軸范圍設(shè)置等。

          CategoryAxis 對(duì)象還可以進(jìn)行的操作有: 刻度標(biāo)示間距 設(shè)置( 最小間距、最大間距、指定間距)等。

          ValueAxis 對(duì)象可進(jìn)行的操作有:軸端設(shè)置(顯示的圖形形狀)、范圍設(shè)置(是否自動(dòng)產(chǎn)生范圍、自動(dòng)產(chǎn)生的最小范圍、最大范圍、指定確定范圍、指定范圍大小等)、間隔設(shè)置(是否自動(dòng)產(chǎn)生間隔、指定間隔)等。

          DateAxis 對(duì)象還有對(duì)時(shí)間刻度顯示格式的設(shè)置操作。

          2 4 子標(biāo)題對(duì)象

              子標(biāo)題對(duì)象是 Title 類型的對(duì)象,一個(gè)JFreeChart可以有多個(gè)子標(biāo)題對(duì)象。JFreeChart提供了5Title的實(shí)現(xiàn),可以是圖片、文本、圖例等的形式。

          (數(shù)據(jù)源以及常用圖形的處理以及進(jìn)一步的討論在后續(xù)文章中介紹)
           

          posted @ 2006-09-01 23:21 JavaExplore 閱讀(9949) | 評(píng)論 (1)編輯 收藏

          1、代理模式:參與角色:代理與真實(shí)實(shí)體共同的抽象角色、代理角色、真實(shí)實(shí)體角色
          ?????? 遠(yuǎn)程代理:封裝對(duì)與遠(yuǎn)程對(duì)象復(fù)雜的調(diào)用通訊過(guò)程,象調(diào)用本地對(duì)象一樣
          ?????? 虛擬代理:真實(shí)實(shí)體加載時(shí)間過(guò)長(zhǎng)的,使用虛擬代理提供友好的顯示方式,一邊加載實(shí)際的對(duì)象
          ?????? 安全代理:調(diào)用真實(shí)的對(duì)象之前插入權(quán)限驗(yàn)證模塊
          ?????? 智能引用代理:調(diào)用真實(shí)的對(duì)象之后調(diào)用統(tǒng)計(jì)等相關(guān)操作模塊

          2、享元模式:參與對(duì)象:建造工廠、抽象享元、具體享元
          ?????? 分析對(duì)象的內(nèi)蘊(yùn)與外蘊(yùn)狀態(tài),即不變的私有屬性與變化的私有屬性。建造工廠使用備忘錄模式存儲(chǔ)已經(jīng)建造的對(duì)象,建造對(duì)象的時(shí)候,以參數(shù)的形式傳遞享元對(duì)象的內(nèi)蘊(yùn)屬性。實(shí)際調(diào)用中,使用傳遞外部參數(shù)的方法使用外蘊(yùn)變量。

          ?? 復(fù)合的享元對(duì)象組成的對(duì)象,不可以整體使用享元模式,但可以單個(gè)的享元對(duì)象屬性使用該模式
          ?? 優(yōu)點(diǎn):降低內(nèi)存中的對(duì)象? 缺點(diǎn):設(shè)計(jì)復(fù)雜性
          ???????

          3、門面模式:結(jié)構(gòu)模式。為包含有很多對(duì)象的子系統(tǒng)提供統(tǒng)一的操作接口類,所有對(duì)該子系統(tǒng)的調(diào)用都通過(guò)這個(gè)類,降低子系統(tǒng)之間調(diào)用的復(fù)雜度,也符合笛比特法則(一個(gè)對(duì)象的朋友盡量少,只與朋友說(shuō)話)

          4、橋梁模式:參與角色:抽象化角色、抽象化的具體角色、實(shí)現(xiàn)化角色、實(shí)現(xiàn)化的具體角色
          ?兩個(gè)有繼承等級(jí)的對(duì)象群,一個(gè)對(duì)象群對(duì)另一個(gè)對(duì)象群有調(diào)用關(guān)系的時(shí)候使用
          ??????? 目的:使抽象化與實(shí)現(xiàn)化解藕

          posted @ 2006-09-01 23:08 JavaExplore 閱讀(731) | 評(píng)論 (0)編輯 收藏

          2006年8月26日

          ???????? 今天去jdon,看了它的設(shè)計(jì)研究欄目,bang有幾篇評(píng)論單例模式的文章,聲稱“Singleton is evil”(見(jiàn)http://www.jdon.com/jive/article.jsp?forum=91&thread=17578),并且引用幾篇外文頁(yè)面佐證自己的觀點(diǎn),其中有一篇文章更是說(shuō),單例不僅不是一種模式,而是一種反模式。
          ??????? 下面我談?wù)勎覍?duì)單例模式的看法。逐一分析單例模式的陷阱,幫助大家正確使用單例模式。
          (1)?陷阱一:調(diào)用函數(shù)的性能瓶頸
          ??????? 在c++中,單例只有一種實(shí)現(xiàn)方式——LazySingleton, 實(shí)現(xiàn)如下(本文全部使用java代碼):

          public ? class ?LazySingleton {
          ????
          private ? static ?LazySingleton?m_instance = null ;
          ???? private?LazySingleton(){};
          ?????synchronized?public?static?LazySingleton?getInstance(){
          ????????
          if(m_instance==null)
          ????????????m_instance
          =new?LazySingleton();
          ????????
          return?m_instance;
          ????}

          }

          LazySingleton將對(duì)象的初始化推遲到調(diào)用的時(shí)候。并且為了防止多線程環(huán)境下產(chǎn)生多個(gè)實(shí)例,使用synchronized關(guān)鍵字保證函數(shù)getInstance調(diào)用的線程安全。synchronized關(guān)鍵字的存在保證了只會(huì)產(chǎn)生一個(gè)對(duì)象,但也成了多線程環(huán)境下的性能瓶頸。一個(gè)多線程的程序,到了這里卻要排隊(duì)等候成了一個(gè)單線程式的執(zhí)行流程,這在高并發(fā)環(huán)境下是不可容忍的。而c++中可以使用雙重檢查機(jī)制將這種性能問(wèn)題僅僅限制在第一次構(gòu)造對(duì)象的時(shí)候,而java中不可以使用雙重檢查機(jī)制。
          ????????但是java可以實(shí)現(xiàn)EagerSingleton,實(shí)現(xiàn)如下:

          public ? class ?EagerSingleton {
          ????
          private ? static ?EagerSingleton?m_instance = new ?EagerSingleton();
          ???? private?EagerSingleton(){};
          ???? public?static?agerSingleton?getInstance(){
          ????????
          return?m_instance;
          ????}

          }
          與LazySingleton相比,EagerSingleton將對(duì)象的初始化放到了類加載的時(shí)候。這樣就避免了synchronized關(guān)鍵字的性能瓶頸。
          (2)陷阱二:訪問(wèn)互斥共享資源
          ?????????EagerSingleton中訪問(wèn)互斥資源也要考慮線程安全問(wèn)題。下面看一個(gè)例子:
          public?class?EagerSingleton{
          ????
          private?static?EagerSingleton?m_instance=new?EagerSingleton();
          ????
          private?HashMap?map=new?HashMap();
          ???
          private?EagerSingleton(){};
          ???
          public?static?agerSingleton?getInstance(){
          ????????
          return?m_instance;
          ????}

          ???????
          public?void?refreshMap(Object key){
          ????????
          synchronized(map){
          ????????????
          if(!map.contains(key))
          ????????????????map.put(key,value);
          //value為此時(shí)的實(shí)時(shí)數(shù)據(jù)
          ????????}
          ?
          ????}

          }
          因?yàn)樵擃愂菃卫?,可能多線程并發(fā)訪問(wèn)map,map非線程安全,需要加線程安全關(guān)鍵字,否則就掉入了訪問(wèn)互斥資源的陷阱。
          (3)陷阱三:非法邏輯陷阱
          ??????? 這種情況一般是濫用單例模式造成的,下面考慮一種濫用單例的情況。下面的代碼的作用是getValueByName后,馬上printValue即完成操作流程。
          public?class?EagerSingleton{
          ????
          private?static?EagerSingleton?m_instance=new?EagerSingleton();
          ????
          private?String?value=null;
          ???
          private?EagerSingleton(){};
          ???
          public?static?agerSingleton?getInstance(){
          ????????
          return?m_instance;
          ????}

          ????
          synchronized?public?void?getValueByName(String?name){
          ????????value
          =getByNameFromDateBase(name);
          ????????
          ????}

          ????
          public?viod?printValue(){
          ????????System.out.println(
          this.vaue);
          ????}

          }

          該類含有一私有屬性value,在多線程環(huán)境下不能保證value值的合理邏輯,一線程getValueByName后,馬上printValue,也有可能value的值已經(jīng)被其他線程修改。這種情況就屬于單例模式的濫用,該類根本不適合做成單例。
          ??????? 消除非法邏輯的陷阱,可以通過(guò)將該類重構(gòu)為純粹的行為類完成。重構(gòu)后的代碼如下:

          public?class?EagerSingleton{
          ????
          private?static?EagerSingleton?m_instance=new?EagerSingleton();
          ???
          private?EagerSingleton(){};
          ???
          public?static?agerSingleton?getInstance(){
          ????????
          return?m_instance;
          ????}

          ????
          private?String?getValueByName(String?name){
          ????????
          return?getByNameFromDateBase(name);
          ????????
          ????}

          ????
          public?viod?printName(String?name){
          ????????String?value
          =getValueByName(String?name);
          ????????System.out.println(value);
          ????}

          }

          通過(guò)調(diào)用printName(String name)直接完成操作流程,將其中的私有屬性處理成過(guò)程式的參數(shù)傳遞,將該類修改成純粹的行為類。

          ??????? 含有私有屬性并且含有對(duì)它賦值操作的類并非都會(huì)調(diào)入該陷阱,構(gòu)造函數(shù)里進(jìn)行對(duì)私有屬性賦值不會(huì)引起非法邏輯,如下代碼

          public?class?EagerSingleton{
          ????
          private?static?EagerSingleton?m_instance=new?EagerSingleton();
          ????
          private?HashMap?map==new?HashMap();
          ????
          ??? private
          ?EagerSingleton(){
          ????????map.put(key,value);
          //value為此時(shí)的實(shí)時(shí)數(shù)據(jù)
          ????}

          ???
          public?static?agerSingleton?getInstance(){
          ????????
          return?m_instance;
          ????}

          }

          構(gòu)造函數(shù)里不必要加線程安全關(guān)鍵字也可以保證線程安全,因?yàn)轭惣虞d器是線程安全的,EagerSingleton只會(huì)在類加載的時(shí)候?qū)嵗淮?,這樣不會(huì)出現(xiàn)單例模式的線程不安全,也不會(huì)造成非法邏輯。
          (4)陷阱四:?jiǎn)卫葳宓膫鬟f
          ??????? 當(dāng)含有對(duì)象作為單例類的私有屬性時(shí),陷阱不僅會(huì)出現(xiàn)在該類本身,還會(huì)傳遞到私有對(duì)象所在的類中??慈缦麓a:

          public?class?EagerSingleton{
          ????
          private?static?EagerSingleton?m_instance=new?EagerSingleton();
          ????
          private?NewClass?newClass=nll;
          ???
          private?EagerSingleton(){
          ????????newClass
          =new?NewClass();
          ????}
          ;
          ???
          public?static?agerSingleton?getInstance(){
          ????????
          return?m_instance;
          ????}

          ???
          public?viod?printName(String?name){
          ????????String?value
          =newClass.operationByNameAndReturnValue(String?name);
          ????????System.out.println(value);
          ????}

          }
          乍一看,代碼中除了構(gòu)造函數(shù)對(duì)私有屬性進(jìn)行了初始化操作,其他地方?jīng)]有對(duì)私有屬性的賦值,不會(huì)引起非法邏輯陷阱。其實(shí)這個(gè)賦值操作可能隱含在newClass.operationByNameAndReturnValue(String name)操作,只有保證了NewClass的operationByNameAndReturnValue操作不會(huì)對(duì)它的私有屬性賦值操作,才能保證真正的合理邏輯。同樣,只有保證NewClass的operationByNameAndReturnValue操作沒(méi)有掉入訪問(wèn)互斥資源陷阱,才能真正保證EagerSingleton沒(méi)有掉入該陷阱。
          ??????? 消除該陷阱的方法:(1)類方法的名稱要合理,比如純粹的行為方法名:interprete,excute,operation之類的方法中就不該含有對(duì)私有屬性直接或者間接的賦值操作,每個(gè)方法的責(zé)任要明確。(2)單例類中盡量不要含有非單例類的實(shí)例作為私有屬性(容器類除外),一定要有類的實(shí)例作為私有屬性的時(shí)候,重新審視這個(gè)作為私有屬性的類,是不是也應(yīng)該設(shè)計(jì)成單例類;或者保證對(duì)它的初始化賦值限制在構(gòu)造函數(shù)內(nèi)。

          posted @ 2006-08-26 11:26 JavaExplore 閱讀(4902) | 評(píng)論 (13)編輯 收藏

          2006年8月24日

          最近發(fā)現(xiàn)一本<java與模式>,正好再溫故一下當(dāng)年的專業(yè)課內(nèi)容,下面是這幾天記的筆記.(并不是系統(tǒng)的講解書(shū)中的內(nèi)容)
          一  綜述:
          1、不要使用接口定義常量
          2、自己少用標(biāo)志接口
          3、不要繼承具體類
          4、類層次的中間節(jié)點(diǎn)應(yīng)該是接口或者抽象類,葉子是具體類
          5、子類應(yīng)當(dāng)擴(kuò)展父類的責(zé)任,而不是覆寫(xiě)父類的責(zé)任
          6、面向接口編程
          7、不要濫用繼承,組合優(yōu)先于繼承

          java中設(shè)計(jì)不當(dāng)?shù)念悾篶alendar:作為接口,含有與具體的歷法(羅馬歷法)相關(guān)的常量,不能擴(kuò)展到中國(guó)的陰歷歷法(不符合開(kāi)閉原則)
                              properies類:濫用繼承,繼承至hashtable,應(yīng)當(dāng)使用聚合

          8、笛比特法則:只與自己的直接朋友通信,不與陌生人通信(1)狹義笛比特法則:只與朋友通訊,通過(guò)自己的朋友傳遞間接的調(diào)用(2)結(jié)合依賴倒轉(zhuǎn)原則修改:不必通過(guò)朋友傳遞間接的調(diào)用,通過(guò)陌生人的抽象接口調(diào)用陌生人的行為(依舊不能與具體的陌生人發(fā)生通信)
          9、盡量降低類中成員的訪問(wèn)權(quán)限,不要設(shè)計(jì)退化類(類似c中struct)。
                  java中的point2D以及Dinmension2D類有這種設(shè)計(jì)缺陷(不過(guò)這種情況問(wèn)題不大)
          10、如果多個(gè)具體的產(chǎn)品類沒(méi)有共同的商業(yè)邏輯,就可以把它們抽象到一個(gè)接口中,如果有共同的商業(yè)邏輯,就把共同的部分抽象到抽象類中,共同的部分盡量向類繼承層次的上層移動(dòng),以達(dá)到復(fù)用的目的
          二   工廠模式
          1、簡(jiǎn)單工廠模式:參與角色:工廠/抽象產(chǎn)品類/具體產(chǎn)品類

             缺點(diǎn):添加新產(chǎn)品的時(shí)候,雖然產(chǎn)品相關(guān)代碼符合開(kāi)閉原則,但對(duì)工廠類本身并不符合,需要修改其中的產(chǎn)生產(chǎn)品方法或者添加新的產(chǎn)生方法(工廠里實(shí)現(xiàn)的不同造成的修改不同)來(lái)支持新的產(chǎn)品類
             退化方式:省略掉工廠角色,抽象產(chǎn)品類擔(dān)任具體產(chǎn)品類的工廠角色:提供靜態(tài)的getInstance方法,比如java類庫(kù)中的DateFormat類,(本人認(rèn)為這樣很不符合開(kāi)閉原則,父類中出現(xiàn)與具體子類相關(guān)的代碼,不方便擴(kuò)展,添加新產(chǎn)品的時(shí)候,修改的時(shí)候缺點(diǎn)與原簡(jiǎn)單工廠的工廠角色類似)

          2、工廠方法模式:參與角色:抽象工廠類/具體工廠類/抽象產(chǎn)品類/具體產(chǎn)品類
               消除了簡(jiǎn)單工廠的缺點(diǎn)


          3、抽象工廠模式:簡(jiǎn)單工廠模式與工廠方法模式的結(jié)合

          4、單例模式:餓漢和懶漢兩種,前者將本身對(duì)象作為靜態(tài)私有屬性事先生成,后者推遲到調(diào)用的時(shí)候,后者需要考慮多線程的時(shí)候,前面需要加線程安全關(guān)鍵字(注意),java中還是前者為優(yōu)。
             不要濫用單例,只有系統(tǒng)要求只有一個(gè)類的實(shí)例的時(shí)候才調(diào)用
             有的單例可能有狀態(tài)屬性,這就為多例模式提供了可能
             含有私有屬性的類作成單例的時(shí)候尤其要注意:一是私有屬性的線程安全,確實(shí)需要的時(shí)候可以加線程安全關(guān)鍵字,比如系統(tǒng)中的log類,二是確認(rèn)這些屬性是不是可以所有線程共享的,類似普通類的static
          三   各種具體模式(1)
          1、建造模式:參與角色4個(gè):指導(dǎo)者、抽象建造對(duì)象、具體建造對(duì)象、產(chǎn)品
                一個(gè)復(fù)雜的產(chǎn)品有很多的零部件,就可以使用具體的建造對(duì)象來(lái)一一構(gòu)造
          2、原始模式:深拷貝、淺拷貝
          3、適配器模式:將adaptee類適配成目標(biāo)接口
          4、合成模式:參與角色:composite接口、樹(shù)枝節(jié)點(diǎn)類、樹(shù)葉節(jié)點(diǎn)類
                分成透明式和安全式兩種,各有優(yōu)缺點(diǎn)
                (1)前者將管理子對(duì)象的方法放到接口中,這樣樹(shù)型結(jié)構(gòu)中的所有對(duì)象都是透明的,都可以統(tǒng)一調(diào)用,但是葉節(jié)點(diǎn)并沒(méi)有管理子對(duì)象的能力,因此透明但不安全
                (2)后者將管理子對(duì)象的方法下放到樹(shù)枝節(jié)點(diǎn)類中,這樣安全但不透明
          5、裝飾模式:繼承已有類的接口,提供和已有類相同的方法,并對(duì)已有類的功能提供擴(kuò)展(通過(guò)組合已有對(duì)象,調(diào)用已有對(duì)象方法的時(shí)候加入新的代碼)
                (1)透明的裝飾模式(純粹的裝飾模式):裝飾類、被裝飾類繼承于同一接口,而且裝飾類只實(shí)現(xiàn)接口的方法,不提供額外方法的實(shí)現(xiàn),調(diào)用該類的時(shí)候使用接口聲明調(diào)用(實(shí)例化當(dāng)然還是自己的構(gòu)造函數(shù)),即該類的所有方法都是透明的
                (2)半透明的裝飾模式(退化的裝飾模式):裝飾類、被裝飾類繼承于同一接口,裝飾類不僅實(shí)現(xiàn)接口的方法,還提供額外方法的實(shí)現(xiàn),這樣要調(diào)用它獨(dú)特的方法的時(shí)候就必須使用它本身來(lái)調(diào)用,退化到一半裝飾模式、一半適配器模式。

          posted @ 2006-08-24 21:25 JavaExplore 閱讀(2116) | 評(píng)論 (6)編輯 收藏

          2005年9月20日

          花了很長(zhǎng)時(shí)間,終于在Jboss部署成功了第一個(gè)EJB。
          Eclipse:3.1
          EJB:2.0
          JBoss:4.0.2
          關(guān)于如何部署EJB,網(wǎng)上有不少詳細(xì)介紹的文章。在這里我不在重復(fù)ejb的細(xì)枝末節(jié)。大體說(shuō)一下,一個(gè)簡(jiǎn)單的EJB包括:一個(gè)繼承SessionBean的類、一個(gè)繼承EJBObject接口的Remote接口、一個(gè)繼承EJBHome的Home接口、調(diào)用該EJB的一個(gè)類(網(wǎng)上的教程一般起名為XXXClient)。
          組織好這些類的目錄結(jié)構(gòu),寫(xiě)好ejb-jar.xml,基本上就完成了。
          說(shuō)明幾點(diǎn):
          1、編譯類的時(shí)候,引入jboss-j2ee.jar與jbossall-client.jar包;
          2、ejb-jar.xml的DOCTYPE處一定要如此(針對(duì)EJB2.0,我部署的時(shí)候時(shí)間都浪費(fèi)在這兒了):
          <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "3、繼承SessionBean的那個(gè)類至少要有一個(gè)ejbCreate()方法;
          4、應(yīng)該拋出的異常一定不能漏掉,特別是那兩個(gè)接口里面的方法應(yīng)該拋出的異常(都應(yīng)該有java.rmi.RemoteException);
          5、部署后以dos方式重啟jboss,若部署失敗,可以在dos窗口中看到出錯(cuò)的原因。

          posted @ 2005-09-20 21:29 JavaExplore 閱讀(1318) | 評(píng)論 (0)編輯 收藏

          2005年9月17日

          代碼中經(jīng)常會(huì)出現(xiàn)枚舉性的變量,比如血型、性別之類。
          以血型為例:

          class?Blood {
          public?final?static?
          int ?o = 0 ;
          public?final?static?
          int ?A = 1 ;
          public?final?static?
          int ?B = 2 ;
          public?final?static?
          int ?AB = 3 ;

          private?Blood();
          }



          class?person
          {
          private?
          int ?_blood;
          public?
          void ?setBlood( int ?b) {
          ???_blood
          = b;
          }

          如果要給一個(gè)person的實(shí)例設(shè)置血型,代碼如此:person.setBlood(Blood.A);
          這個(gè)寫(xiě)法的代碼中,setBlood的參數(shù)為整型,如果如此調(diào)用person.setBlood(9);
          編譯器無(wú)法發(fā)現(xiàn)錯(cuò)誤,只能靠人為控制,如果在方法setBlood中檢測(cè)參數(shù)的有效性,又超越了該方法的職責(zé)。

          重構(gòu)后的代碼如下:

          final class?Blood{
          public?final?static?Blood?O
          =new?Blood(0);
          public?final?static?Blood?A
          =new?Blood(1);
          public?final?static?Blood?B
          =new?Blood(2);
          public?final?static?Blood?AB
          =new?Blood(3);
          private?
          int?_bloodCode;
          private?Blood(
          int?b){
          ????_bloodCode
          =b;
          ??}

          public?
          int?getCode(){
          ????
          return?_bloodCode;
          ??}

          }


          class?person
          {
          private?Blood?_blood;
          public?setBlood(Blood?b)
          {
          ????_blood
          =b;
          ??}

          }

          如此,(1)隱藏了血型的編碼細(xì)節(jié)
          ????????????(2)方便編譯期間發(fā)現(xiàn)錯(cuò)誤
          ??????????? (3)避免使用超越數(shù)據(jù)范圍的參數(shù)

          posted @ 2005-09-17 21:24 JavaExplore 閱讀(1470) | 評(píng)論 (7)編輯 收藏

          1、變量、對(duì)象聲明語(yǔ)法<%!.....%>
          2、嵌入java語(yǔ)句語(yǔ)法<%......%>
          3、調(diào)用javabean語(yǔ)法<jsp:useBean id="zong" scope="page" class="test.Hello"/>
               文件Hello.class位于目錄web-inf\classes\test下,該jsp頁(yè)面與文件夾web-inf位于同一目錄下。
          4、調(diào)用javabean的屬性語(yǔ)法<jsp:getProperty id="zong" property="A"/>
             類Hello中要有方法getA();
          5、javabean 的一般語(yǔ)法,構(gòu)造函數(shù)為public,所有屬性為private,每個(gè)屬性對(duì)應(yīng)get,set方法,boolean類型屬性的對(duì)應(yīng)get方法可以用is替換。

          posted @ 2005-09-17 20:47 JavaExplore 閱讀(1891) | 評(píng)論 (3)編輯 收藏

          這是我以前在http://bbs.chinajavaworld.com上發(fā)的一個(gè)帖子

          初來(lái)論壇,見(jiàn)大家一些基礎(chǔ)問(wèn)題反復(fù)的問(wèn),很是浪費(fèi)時(shí)間與精力,下面將常見(jiàn)問(wèn)題逐一解答,并歡迎各位同道跟帖寫(xiě)出常見(jiàn)問(wèn)題以及解答方法。
          (1)、何處下載jdk?網(wǎng)址:java.sun.com/downloads
          何處下載tomcat?網(wǎng)址:http://jakarta.apache.org/site/binindex.cgi這個(gè)頁(yè)面很長(zhǎng),往下拉找到tomcat,有很多版本,現(xiàn)在最新的是 5.5.5-alpha exe PGP MD5
          (2)、為何安裝tomcat的時(shí)候停在using jvm?關(guān)掉瑞星,然后打開(kāi) 控制面板-》管理工具-》服務(wù),找到瑞星對(duì)應(yīng)的全部服務(wù)都停止。然后重新安裝即可成功。
          (3)、安裝后需要如何配置環(huán)境變量?右鍵單擊"我的電腦",在彈出菜單中選擇"屬性"→"系統(tǒng)特性" →"高級(jí)" →"環(huán)境變量", 彈出環(huán)境變量對(duì)話框,就可以編輯系統(tǒng)的環(huán)境變量了。添加PATH、JAVA_HOME、CLASSPATH、TOMCAT_HOME四個(gè)變量。PATH=你的jdk目錄\bin;JAVA_HOME=你的jdk安裝目錄;CLASSPATH=你的jdk安裝目錄\lib\tools.jar;TOMCAT_HOME=你的tomcat安裝目錄。開(kāi)啟tomcat服務(wù),然后使用:http://localhost:8080/就可以測(cè)試是不是配置成功。
          (4)、tomcat的目錄結(jié)構(gòu)是什么樣子的?下面說(shuō)一下我們會(huì)經(jīng)常接觸到的目錄與文件。bin目錄下的tomcat5.exe是tomcat服務(wù)的啟動(dòng)文件;logs目錄是一些日志文件,其中stdout.log是你的System.out.println打印的目的地(當(dāng)你打開(kāi)tomcat服務(wù)地dos界面時(shí),向該dos界面打?。?;webapps目錄是我們的網(wǎng)站文件放置的地方,webapps\ROOT是tomcat的默認(rèn)主頁(yè)目錄,可以使用http://localhost:8080來(lái)訪問(wèn)該目錄。webapps下其他目錄下的文件,我們可以使用http://localhost:8080/目錄名來(lái)訪問(wèn)。
          (5)、為何我得jsp不能正確顯示中文?這個(gè)不是配置的問(wèn)題,大家都知道我們可以在html文件里通過(guò)設(shè)置<meta http-equiv="Content-Type" content="text/html; charset=gb2312">讓html顯示中文,jsp也是一樣,你設(shè)置<%@page contentType="text/html; charset=gb2312" %>就可以顯示中文。
          (6)、如何新建虛擬目錄?
          修改 Tomcat安裝目錄\conf\server.xml ,在下列行前
          </Host>
          </Engine>
          添加下列行:
          <Context path="/my" docBase="c:\myjsp\test" debug="0" reloadable="true">
          </Context>
          表示增加虛擬目錄 my,對(duì)應(yīng)物理目錄位置c:\myjsp\test,若存在c:\myjsp\test\hello.jsp,則下列地址可訪問(wèn):
          htpp://localhost:8080/my/hello.jsp
          修改server.xml后,需要重新啟動(dòng)tomcat. (轉(zhuǎn)mouseLee回帖,測(cè)試正確)
          (7)、如何配置servlet?
          以(6)建立的虛擬目錄為例。假如你有一個(gè)servlet:MyFirstServlet。該servlet第一行代碼為:package com.myservlet;
          將MyFirstServlet.class復(fù)制到c:\myjsp\test\WEB-INF\classes\com\myservlet下面,無(wú)目錄的自己新建。然后打開(kāi)c:\myjsp\test\WEB-INF\web.xml(該文件可以從tomcat的安裝目錄\webapps\ROOT\WEB-INF下面復(fù)制),在<!-- JSPC servlet mappings end -->前面加入<servlet>
          <servlet-name>newServlet</servlet-name>
          <servlet-class>com.myservlet.MyFirstServlet</servlet-class>
          </servlet>

          <servlet-mapping>
          <servlet-name>newServlet</servlet-name>
          <url-pattern>/ceshi</url-pattern>
          </servlet-mapping>
          然后你就可以通過(guò)htpp://localhost:8080/my/ceshi來(lái)訪問(wèn)你的servlet了。

          posted @ 2005-09-17 20:14 JavaExplore 閱讀(1219) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 象山县| 遵义市| 连平县| 交城县| 台东县| 宁波市| 昌吉市| 乡城县| 高要市| 临颍县| 霍林郭勒市| 佛山市| 枝江市| 菏泽市| 忻州市| 新和县| 合山市| 鹿泉市| 合阳县| 德州市| 聂拉木县| 西宁市| 台州市| 张掖市| 沈阳市| 四会市| 上林县| 精河县| 仁怀市| 乃东县| 班玛县| 收藏| 寻甸| 南投市| 沙河市| 布尔津县| 北川| 扎囊县| 太康县| 凌海市| 张家口市|