<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JavaExplore

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

    2005年9月17日

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

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

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

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

    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ì)象,它的工廠類(lèi)提供了 33 個(gè)工廠方法用于生成不同的圖形對(duì)象(具體的工廠方法可以參見(jiàn) JFreeChart API 手冊(cè)或者源碼中的 ChartFactory 類(lèi) )。              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 類(lèi)型,可以進(jìn)行的操作有:背景設(shè)置、字體設(shè)置(字體類(lèi)型、顏色、內(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 抽象類(lèi)的具體實(shí)現(xiàn)類(lèi)。 Plot 的具體實(shí)現(xiàn)類(lèi)主要由以下重要對(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 類(lèi)都含有 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é)中專(zhuān)門(mén)講解。

    2 31 Renderer對(duì)象

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

    一般來(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è)置。可以說(shuō)和具體繪制的圖形相關(guān)的屬性都可以通過(guò) Renderer 對(duì)象設(shè)置。

    不同的 Renderer 的實(shí)現(xiàn)類(lèi)實(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 提供了兩種類(lèi)型的坐標(biāo)軸: CategoryAxis (等級(jí)軸)和 ValueAxis (值軸), ValueAxis 又有 3 個(gè)子類(lèi): DateAxis (時(shí)間軸)、 NumberAxis (數(shù)字軸)、 PeriodAxis (時(shí)期軸)。這些坐標(biāo)軸還有更詳細(xì)的子類(lèi),不再一一列舉

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

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

    posted @ 2006-09-01 23:21 JavaExplore 閱讀(9947) | 評(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、門(mén)面模式:結(jié)構(gòu)模式。為包含有很多對(duì)象的子系統(tǒng)提供統(tǒng)一的操作接口類(lèi),所有對(duì)該子系統(tǒng)的調(diào)用都通過(guò)這個(gè)類(lèi),降低子系統(tǒng)之間調(diào)用的復(fù)雜度,也符合笛比特法則(一個(gè)對(duì)象的朋友盡量少,只與朋友說(shuō)話(huà))

    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 閱讀(728) | 評(píng)論 (0)編輯 收藏

    ???????? 今天去jdon,看了它的設(shè)計(jì)研究欄目,bang有幾篇評(píng)論單例模式的文章,聲稱(chē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ì)象的初始化放到了類(lèi)加載的時(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)樵擃?lèi)是單例,可能多線程并發(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);
    ????}

    }

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

    ??????? 含有私有屬性并且含有對(duì)它賦值操作的類(lèi)并非都會(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)轭?lèi)加載器是線程安全的,EagerSingleton只會(huì)在類(lèi)加載的時(shí)候?qū)嵗淮危@樣不會(huì)出現(xiàn)單例模式的線程不安全,也不會(huì)造成非法邏輯。
    (4)陷阱四:?jiǎn)卫葳宓膫鬟f
    ??????? 當(dāng)含有對(duì)象作為單例類(lèi)的私有屬性時(shí),陷阱不僅會(huì)出現(xiàn)在該類(lèi)本身,還會(huì)傳遞到私有對(duì)象所在的類(lèi)中。看如下代碼:

    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)類(lèi)方法的名稱(chēng)要合理,比如純粹的行為方法名:interprete,excute,operation之類(lèi)的方法中就不該含有對(duì)私有屬性直接或者間接的賦值操作,每個(gè)方法的責(zé)任要明確。(2)單例類(lèi)中盡量不要含有非單例類(lèi)的實(shí)例作為私有屬性(容器類(lèi)除外),一定要有類(lèi)的實(shí)例作為私有屬性的時(shí)候,重新審視這個(gè)作為私有屬性的類(lèi),是不是也應(yīng)該設(shè)計(jì)成單例類(lèi);或者保證對(duì)它的初始化賦值限制在構(gòu)造函數(shù)內(nèi)。

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

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

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

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

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

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


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

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

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

    花了很長(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的類(lèi)、一個(gè)繼承EJBObject接口的Remote接口、一個(gè)繼承EJBHome的Home接口、調(diào)用該EJB的一個(gè)類(lèi)(網(wǎng)上的教程一般起名為XXXClient)。
    組織好這些類(lèi)的目錄結(jié)構(gòu),寫(xiě)好ejb-jar.xml,基本上就完成了。
    說(shuō)明幾點(diǎn):
    1、編譯類(lèi)的時(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è)類(lèi)至少要有一個(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 閱讀(1317) | 評(píng)論 (0)編輯 收藏

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

    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 閱讀(1469) | 評(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"/>
       類(lèi)Hello中要有方法getA();
    5、javabean 的一般語(yǔ)法,構(gòu)造函數(shù)為public,所有屬性為private,每個(gè)屬性對(duì)應(yīng)get,set方法,boolean類(lèi)型屬性的對(duì)應(yīng)get方法可以用is替換。

    posted @ 2005-09-17 20:47 JavaExplore 閱讀(1887) | 評(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ì)話(huà)框,就可以編輯系統(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 閱讀(1218) | 評(píng)論 (0)編輯 收藏

    主站蜘蛛池模板: 国产免费69成人精品视频| 亚洲小说图区综合在线| 午夜dj在线观看免费视频| 久久午夜免费鲁丝片| 特级毛片免费播放| 亚洲精品无码久久久久YW| 亚洲第一香蕉视频| 国产亚洲精品一品区99热| 国产在线观看免费不卡| 成人性生交大片免费看无遮挡| 亚洲午夜免费视频| APP在线免费观看视频| 一级特黄aaa大片免费看| 亚洲av无码有乱码在线观看| 久久精品国产亚洲AV忘忧草18 | 97久久精品亚洲中文字幕无码| 亚洲一区二区三区影院| 免费很黄很色裸乳在线观看| 日韩视频免费在线| 成人人观看的免费毛片| 希望影院高清免费观看视频| 久久午夜夜伦鲁鲁片免费无码影视 | 99久久免费国产特黄| yellow免费网站| 农村寡妇一级毛片免费看视频| 日韩欧美亚洲国产精品字幕久久久| 亚洲伊人久久大香线蕉结合| 亚洲国产精品无码久久久| 91亚洲精品视频| 亚洲精品欧洲精品| 亚洲影视一区二区| 亚洲中文字幕久久精品无码2021| 亚洲成a人片7777| 亚洲一线产品二线产品| 亚洲人成网站色7799| 在线观看亚洲专区| 一级成人生活片免费看| 久久精品无码免费不卡| 免费精品一区二区三区第35| 99re在线视频免费观看| 97性无码区免费|