導航:首頁 > 編程語言 > visitorjava

visitorjava

發布時間:2023-05-29 11:04:08

java常用的的設計模式和開發模式都有哪些

設計模式主要分三個類型、創建型、結構型和行為型。設計模式分:3種類型及23種模式。

JAVA中的開發模式:MVC是一個很常用的程序開發設計模式,M-Model(模型):封裝應用程序的狀態;V-View(視圖):表示用戶界面;C-Controller(控制器):對用戶的輸入作出反應,創建並設置模型。

(1)visitorjava擴展閱讀

創建型模式:單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。

結構型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。

行為型模式:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式(Interpreter模式)、狀態模式、策略模式、職責鏈模式(責任鏈模式)、訪問者模式。

Ⅱ 在組合模式中實現訪問者(Visitor)模式

本文從一個給定的實現了組合(Composite)模式的例子開始 說明怎麼在這個數據結構上實現業務邏輯代碼 依次介紹了非面向對象的方式 在組合結構中加入方法 使用訪問者(Visitor)模式以及用改進後的訪問者(Visitor)模式來實現相同的業務邏輯代碼 並且對於每種實現分別給出了優缺點

讀者定位於具有Java程序開發和設計模式經驗的開發人員

讀者通過本文可以學到如何在組合(Composite)模式中實現各種不同的業務方法及其優缺點

組合(Composite)模式

組合模式是結構型模式中的一種 GOF的《設計模式》一書中對使用組合模式的意圖描述如下 將對象組合成樹形結構以表示 部分 整體 的層次結構 Composite使得用戶對單個對象和組合對象的使用具有一致性

組合模式應用廣泛 根據GOF中對組合模式的定義 Composite模式一般由Component介面 Leaf類和Composite類組成 現在需要對一個軟體產品管理系統的實體建模 某公司開發了一系列軟體集(SofareSet) 包含了多橘正種品牌(Brand)的軟體產品 就象IBM提供了Lotus WebsPhere等品牌 每個品牌下面又有各種產品(Proct) 如IBM的Lotus下面有Domino Server/Client產品等 建模後的類圖如下(代碼可以參見隨本文帶的附件中 包 test entity下所有的源文件)

如圖所示

( )介面SofareComponent就是對應於組合模式中的Component介面 它定義了所有類共有介面的預設行為

( )AbsSofareComposite類對應於Composite類 並且是抽象類 所有可以包含子節點的類都擴展這個類 這個類的主要功能是用來存儲子部件 實現了介面中的方法 部分可以重用的代碼寫在此類中

( )SofareSet類繼承於AbsSofareComposite類 對應於軟體集 軟體集下直接可以包含品牌(Brand) 也可以直接包含不屬於任何品牌的產品(Proct)

( )Brand類繼承於AbsSofareComposite類 對應於品牌 包含了品牌名屬性 並且用來存儲Proct類的實例

( )Proct類就是對應的Leaf類 表示葉子節點 葉子節點沒有子節點

用不同的方法實現業務邏輯

數據結構建立好之後 需要在這個數據結構上添加方法實現圓氏悔業務邏輯 比如現在的這個例子中 有這樣的需求 給定一些用戶選擇好的產品 需要計算出這些選中後軟體的總價格 下面開始介紹如何使用各種不同的方法來實現這個業務邏輯

非面向對象的編程方式

這種方式下 編程思路最簡單 遍歷SofareSet實例中的所有節點 如果遍歷到的當前對象是Proct的話就累加 否則繼續遍歷下一層直到全部遍歷完畢 代碼片斷如下

    /** *取得某個SofareComponent對象下面所有Proct的價格 *@parambrand *@return */ public double getTotalPrice(){ SofareComponenttemp=sofareComponent; double totalPrice= ; //如果傳入的實例是SofareSet的類型 if (temp instanceof SofareSet){ Iteratorit=((SofareSet)sofareComponent) getChilds() &erator(); while (it hasNext())核山{ //遍歷 temp=(SofareComponent)it next(); //如果子對象是Proct類型的 直接累加 if (temp instanceof Proct){ Proctproct=(Proct)temp; totalPrice+=proct getPrice(); } else if (temp instanceof Brand){ //如果子對象是Brand類型的 則遍歷Brand下面所有的產品並累加 Brandbrand=(Brand)temp; totalPrice+=getBrandPrice(brand); } } } else if (temp instanceof Brand){ //如果傳入的實例是SofareSet的類型 則遍歷Brand下面所有的產品並累加 totalPrice+=getBrandPrice((Brand)temp); } else if (temp instanceof Proct){ //如果子對象是Proct類型的 直接返回價格 return ((Proct)temp) getPrice(); } return totalPrice; } /** *取得某個Brand對象下面所有Proct的價格 *@parambrand *@return */ private double getBrandPrice(Brandbrand){ IteratorbrandIt=brand getChilds(erator(); double totalPrice= ; while (brandIt hasNext()){ Proctproct=(Proct)brandIt next(); totalPrice+=proct getPrice(); } return totalPrice; }

這段代碼的好處是實現業務邏輯的時候無需對前面已經定好的數據結構做改動 並且效率比較高 缺點是代碼凌亂而且頻繁使用了instanceof判斷類型和強制類型轉換 代碼的可讀性不強 如果層次多了代碼就更加混亂

面向對象的編程方式(將計算價格的方法加入數據結構中)

下面我們採用面向對象的方式 可以這么做 在介面SoftWareComponent中加入一個方法 名叫getTotalPrice 方法的聲明如下

    /** *返回該節點中所有子節點對象的價格之和 *@return */ public double getTotalPrice();
由於類Brand和SofareSet都繼承了AbsSofareComposite 我們只需在類AbsSofareComposite中實現該方法getTotalPrice方法即可 如下
    public double getTotalPrice(){ Iteratorit=erator(); double price= ; while (it hasNext()){ =(SofareComponent)it next(); //自動遞歸調用各個對象的getTotalPrice方法並累加 price+=sofareComponent getTotalPrice(); } return price; }
在Proct類中實現如下
    public double getTotalPrice(){ return price; }
在外面需要取得某個對象的總價格的時候只需這樣寫(在本文的例子 test business SofareManager中可以找到這段代碼)
    //getMockData()方法返回數據 SofareComponentdata=getMockData(); //只需直接調用data對象的getTotalPrice方法就可以返回該對象下所有proct對象的價格 double price=data getTotalPrice(); //找到某個對象後直接調用其getTotalPrice方法也可以返回總價格 price=data findSofareComponentByID( id ) getTotalPrice();

現在把業務邏輯的實現都放在了數據結構中(組合模式的結構中) 好處很明顯 每個類只管理自己相關的業務代碼的實現 跟前面舉的面向過程方式的實現方式相比 沒有了instanceof和強制類型轉換 但是不好的地方是如果需要增加新的業務方法的話就很麻煩 必須在介面SoftWareComponent中首先聲明該方法 然後在各個子類中實現並且重新編譯

使用訪問者模式

使用訪問者模式就能解決上面提到的問題 如果要經常增加或者刪除業務功能方法的話 需要頻繁地對程序進行重新實現和編譯 根據面向對象設計原則之一的SRP(單一職責原則)原則 如果一個類承擔了多於一個的職責 那麼引起該類變化的原因就會有多個 就會導致脆弱的設計 在發生變化時 原有的設計可能會遭到意想不到的破壞 下面我們引入了一個叫做Visitor的介面 該介面中定義了針對各個子類的訪問方法 如下所示

    public interface Visitor{ public void visitBrand(Brandbrand); public void visitSofareSet(SofareSetsofareSet); public void visitProct(Proctproct); }
visitBrand方法是訪問Brand對象節點的時候用的 剩下的方法依次類推 並在介面SofareComponent中增加一個方法
    public void accept(Visitorvisitor);
在SofareSet中實現介面中的accept方法 首先直接調用Visitor介面中的visitSofareSet方法 傳入的參數是本身對象 然後遞歸調用子對象的accept方法
    public void accept(Visitorvisitor){ visitor visitSofareSet( this ); Iteratorit=erator(); while (it hasNext()){ SofareComponentponent=(SofareComponent)it next(); ponent accept(visitor); } }
在Brand中實現介面中的accept方法 首先直接調用Visitor介面中的visitBrand方法 傳入的參數是本身對象 然後遞歸調用子對象的accept方法
    public void accept(Visitorvisitor){ visitor visitBrand( this ); Iteratorit=erator(); while (it hasNext()){ SofareComponentponent=(SofareComponent)it next(); ponent accept(visitor); } }
其實在上面的兩個類的實現中可以將遍歷子節點並調用其accept方法的代碼寫到父類AbsSofareComposite中的某個方法中 然後直接調用父類中的這個方法即可 這里為了解釋方便分別寫在了兩個子類中 在Proct中實現介面中的accept方法 直接調用Visitor介面的visitProct方法即可
    public void accept(Visitorvisitor){ visitor visitProct( this ); }
下面需要實現Visitor介面 類名是CaculateTotalPriceVisitor 實現了計算總價格的業務邏輯 實現代碼如下所示
    public class CaculateTotalPriceVisitor implements Visitor{ private double totalPrice; public void visitBrand(Brandbrand){ } public void visitSofareSet(SofareSetsofareSet){ } public void visitProct(Proctproct){ //每次在組合的結構中碰到Proct對象節點的時候 就會調用此方法 totalPrice+=proct getPrice(); } public double getTotalPrice(){ return totalPrice; } }
上面那段代碼中 首先在類內定義一個總價格的屬性 由於Brand和SofareSet都沒有價格 因此在實現中 只需在visitProct方法中累加totalPrice即可 在外面如果需要計算總價格的話這樣寫(在本文的例子 test business SofareManager中可以找到這段代碼)
    //建立一個新的Visitor對象 = new CaculateTotalPriceVisitor(); //將該visitor對象傳到結構中 data accept(visitor); //調用visitor對象的getTotalPrice()方法就返回了總價格 double price=visitor getTotalPrice();

下面是它的時序圖 在類SofareManager中的main方法中 調用軟體集對象(data)的accept方法 並將生成的visitor對象傳給它 accept方法開始遞歸調用各個子對象的accept方法 如果當前的對象是SofareSet的實例 則調用visitor對象visitSofareSet方法 在visitor對象中對該節點的數據進行一些處理 然後返回 依次類推 遍歷到Brand對象和Proct對象也與此類似 當前的邏輯是計算軟體產品的總價格 因此當遍歷到Proct對象的時候 取出產品的價格並且累加 最後當結構遍歷完畢後 調用visitor對象的getTotalPrice方法返回給定軟體集對象的(data)的總的價格 如果需要加入一個新的計算邏輯 只實現Visitor介面 並且將該類的實例傳給data對象的accept方法就可以實現不同的邏輯方法了

點擊小圖看大圖

我們可以看到通過訪問者模式很好地解決了如何加入新的業務代碼而無需重新改動 編譯既有代碼 但是該模式也不是沒有缺點 如果在組合模式中結構加入新的子類的話會導致介面Visitor也跟著改動 導致所有Visitor的子類都需要實現新增的方法 因此這種訪問者模式適合於結構不經常變動的情況

改進訪問者模式

前面我們說到了如何使用Visitor模式及使用該模式後的優缺點 下面舉具體的例子說明 假設現在客戶提出了一個產品集(ProctSet)的概念 隨著公司軟體版本的增多 需要將同一個版本的產品(Proct)都放到產品集(ProctSet)中 而一個品牌包含有多個產品集 因為現在組合結構中增加了一個節點 所以在Visitor介面中也必須隨之增加一個叫做visitProctSet的方法 並且會導致原有系統中所有已經實現了Visitor介面的類都需要重新實現並編譯 用Java的反射機制可以解決這個問題

使用Java的Method Reflection機制實現訪問者模式

首先我們需要改變一下Visitor介面 介面名叫做ReflectionVisitor 如下所示

    public interface ReflectionVisitor{ /** *定義了一個訪問節點的方法 *@paramsofareComposite */ public void visitSofareComposite( Object sofareComposite); }

在現在的介面的方法里 能接受任意的對象(參數是Object)

下面實現介面ReflectionVisitor 名叫ReflectionVisitorImpl 代碼如下所示

    public class ReflectionVisitorImpl implements ReflectionVisitor{ public void visitSofareComposite( Object sofareComposite){ //判斷是否是null if (sofareComposite== null ){ throw new NullPointerException ( Thevisitnodeshouldnotbenull! ); } //組裝class數組 即調用動態方法的時候參數的類型 Class []classes= new Class []{sofareComposite getClass()}; //組裝與class數組相對應的值 Object []objects= new Object []{sofareComposite}; try { //查找visit方法 Methodm=getClass() getMethod( visit classes); //調用該方法 m invoke( this objects); } catch ( NoSuchMethodException e){ //沒有找到相應的方法 System out println( : +sofareComposite getClass()); } catch ( Exception e){ //發生了別的異常 System out println( ); e printStackTrace(); } } }

這段代碼首先判斷傳入的對象是否是空指針 然後創建class數組和object數組 然後用getMethod方法取得方法名是 visit 方法的參數是 對象sofareComposite對應的類 的方法 最後調用該方法 調用該方法的時候可能會發生NoSuchMethodException異常 發生這個異常就表明它的子類或者當前類中沒有與參數中傳入相對應的visit方法

下面再來寫新版本Visitor類 擴展剛寫好的那個ReflectionVisitorImpl類 名叫 如下所示

    public class extends ReflectionVisitorImpl{ private double totalPrice; public void visit(Proctproct){ totalPrice+=proct getPrice(); } public void visit(SofareSetsofareSet){ System out println( Nopriceforsofareset ); } public double getTotalPrice(){ return totalPrice; } }
代碼中聲明了兩個visit方法(因為在類ReflectionVisitorImpl中 查找名為visit 參數與傳進去的對象匹配的的方法) 一個是給Proct的 另外一個是給SofareSet的 在這里SofareSet中並沒有價格 只需當前的對象是類Proct的實例的時候將價格累加即可 如果在組合模式的結構中增加了新的類 只需要在ReflectionVisitorImpl的擴展類中聲明一個visit方法 該方法的參數是新增加的類 對於文中的例子 只需增加下面的一個方法
    public void visit(ProctSetproctSet){ //實現的代碼 }

在組合結構的介面SofareComponent中改一下accept方法 參數是修改後的Visitor介面 如下所示

public void accept(ReflectionVisitor visitor);

由於在類SofareSet Brand和ProctSet中實現上面accept方法的代碼都一樣 因此把代碼抽象到上層共有的抽象類AbsSofareComposite中 如下所示

    public void accept(ReflectionVisitorvisitor){ visitor visitSofareComposite( this ); Iteratorit=erator(); while (it hasNext()){ SofareComponentponent=(SofareComponent)it next(); //遞歸調用子對象的accept方法 ponent accept(visitor); } }
現在如果想在外面要調用的話 代碼如下所示(在本文的例子 test business SofareManager中可以找到這段代碼)
    //建立一個新的Visitor對象 reflectionVisitor = new (); //將該visitor對象傳到結構中 data accept(reflectionVisitor); //調用visitor對象的getTotalPrice()方法就返回了總價格 double price=reflectionVisitor getTotalPrice();

另外由於沒有實現Brand類的visit方法 在組合結構遍歷到Brand的節點的時候會拋出NoSuchMethodException異常 就是沒有關於該節點方法的實現 在當前的程序中會列印出一句話

You did not implement the visit method for class:class test entity Brand

如果運行程序時發生了別的異常 請參見相應的Java API文檔

在現在的改進後的訪問者模式中 如果在組合的結構中新增或刪除節點並不會對已經實現了的Visitor產生任何影響 如果新增了業務方法 只需擴展類ReflectionVisitorImpl就可以了 因此很好地解決了訪問者模式的問題

改進訪問者模式實現與既有代碼對接

到現在為止 改進後的訪問者模式好像已經很好地解決了所有出現的問題 但是考慮到有下面的這種情況 現在需要寫一個JSP的標簽庫(TagLib) 這個標簽庫還必須具有Visitor的功能(就是需要有遍歷節點的功能) 可以將節點的內容根據需要列印到HTML頁面中 由於標簽本身需要繼承相應的類(如TagSupport) 如果繼續使用上面提供的方法將無法實現 因為Java不允許多重繼承 不過我們可以將原有ReflectionVisitorImpl的代碼再改進一下以解決這種情況 新的Visitor的實現類叫NewReflectionVisitorImpl 代碼如下所示

    public class NewReflectionVisitorImpl implements ReflectionVisitor{ //實現visit方法的類 private Object targetObject; //構造方法 傳入實現了visit方法的類 public NewReflectionVisitorImpl( Object targetObject){ if (targetObject== null ) throw new NullPointerException ( ! ); this targetObject=targetObject; } public void visitSofareComposite( Object sofareComposite){ //……與上個例子相同 try { //從目標的對象中查找visit方法 Methodm=targetObject getClass() getMethod( visit classes); //調用該方法 m invoke(targetObject objects); } catch ( NoSuchMethodException e){ //……與上個例子相同 } catch ( Exception e){ //……與上個例子相同 } } }
該類的實現與上面的實現差不多 多了一個構造函數 在該構造函數的參數中傳入實現了visit方法的類 並且維護了指向該類的一個引用 另外最重要的地方是下面的兩行代碼
    //從目標的對象中查找visit方法 Methodm=targetObject getClass() getMethod( visit classes); //調用該方法 m invoke(targetObject objects);

本來的代碼中從本身的類及其子類中查找visit方法 而現在是從維護的目標類中查找visit方法

現在需要寫Tag類 這個類擴展了TagSupport類 如下所示(為說明的方便 隨本文的例子提供了一個模擬的TagSupport類)

    public class MyTag extends TagSupport{ = null ; private double totalPrice= ; public int doEngTag(){ //創建一個visitor對象 並且將本身傳入visitor對象中 ReflectionVisitorvisitor= new NewReflectionVisitorImpl( this ); //遍歷結構 sofareComponent accept(visitor); //列印出價格 out println(totalPrice); return ; } //實現了針對Proct的visit方法 public void visit(Proctproct){ totalPrice+=proct getPrice(); } public void visit(Brandbrand){ out println(brand getId()+brand getDescription()); } //別的代碼請參見隨本文帶的源程序 …… }
如果想測試上面寫的那段代碼 (在本文的例子 test business SofareManager中可以找到這段代碼))如下所示
    //getMockData()方法返回數據 SofareComponentdata=getMockData(); MyTagmyTag= new MyTag(); myTag setSofareComponent(data); //計算總價格 並列印出來 myTag doEngTag();

可以看到通過Java的反射機制很好地解決了多重繼承的問題 使該訪問者模式能夠更好地應用於你的應用中 另外可以看到 那些visit方法所在的類已經不是實現了介面ReflectionVisitor 可以說是訪問者模式在Java語言的支持下的一種特殊實現

如果擔心引入類反射機制後帶來的效率問題 你可以將Method對象通過某種方式緩沖起來 這樣不會每次從傳入的對象中找visit方法 可以部分地提高效率

結論

lishixin/Article/program/Java/gj/201311/11152

Ⅲ java 返回用戶在指定文件夾中的指定後綴的所有文件

Java實現獲取指定路徑下的指定格式的文件代碼如下:

packagefilenameFilter;

importjava.io.File;

/*
*實現功能:
*獲取指定路徑下的指定格式的文件;
**/

publicclassTest{

publicstaticvoidlistPath(Filefile){
//接收篩選過後的文件對象數組
//用文件對象調用listFiles(FilenameFilterfilter);方法,
//返回抽象路徑名數組,這些路徑名表示此抽象路徑名表示的目錄中滿足指定過濾器的文件和目錄
Filefiles[]=file.listFiles(newMyFilenameFilter());

/*//遍歷出指定文件路徑下符合條件的文件
for(Filef:files){
System.out.println(f);
}*/

//遍歷出指定文件路徑下的所有符合篩選條件的文件
for(Filef:files){
if(f.isDirectory()){
listPath(f);
}else{
System.out.println(f);
}
}}

publicstaticvoidmain(String[]args){
//創建指定目錄的文件對象
Filefile=newFile("F:\test");
//調用文件曬篩選的方法,並將文件對象出入,
listPath(file);
}
}

packagefilenameFilter;

importjava.io.File;

importjava.io.FilenameFilter;


//實現FilenameFilter介面,可用於過濾器文件名
//本方法實現的是篩選指定格式結尾的文件
{

/**
*@paramargs
*
*實現功能;實現FilenameFilter介面,定義出指定的文件篩選器
*
*/


@Override
//重寫accept方法,測試指定文件是否應該包含在某一文件列表中
publicbooleanaccept(Filedir,Stringname){
//TODOAuto-generatedmethodstub
//創建返回值
booleanflag=true;
//定義篩選條件
//endWith(Stringstr);判斷是否是以指定格式結尾的
if(name.toLowerCase().endsWith(".jpg")){

}elseif(name.toLowerCase().endsWith(".txt")){

}elseif(name.toLowerCase().endsWith(".gif")){

}else{
flag=false;
}
//返回定義的返回值

//當返回true時,表示傳入的文件滿足條件
returnflag;
}

}

Ⅳ 軟體設計模式主要有哪幾種

軟體設計模式主要有以下三大類共23種:

一、創建型模式:

1、工廠方法模式工廠方法模式的創建是因為簡單工廠模式有一個問題,在簡單工廠模式中類的創建依賴工廠類,如果想要拓展程序,必須對工廠類進行修改,這違背了開閉原則,所以就出現了工廠方法模式,只需要創建一個工廠介面和多個工廠實現類。

2、抽象工廠模式抽象工廠模式是提供一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類。區別於工廠方法模式的地方,工廠方法模式是創建一個工廠,可以實現多種對象;而抽象工廠模式是提供一個抽象工廠介面,裡面定義多種工廠,每個工廠可以生產多種對象。

3、單例模式單例模式能保證一個類僅有一個實例,並提供一個訪問它的全局訪問點,同時在類內部創造單一對象,通過設置許可權,使類外部無法再創造對象。單例對象能保證在一個JVM中,該對象只有一個實例存在。

4、建造者模式建造者模式是將一個復雜的構建與其表示相分離,使得同樣的構建過程可以創建不同的表示。在程序當中就是將一些不會變的基本組件,通過builder來進行組合,構建復雜對象,實現分離。

5、原型模式:原型模式是用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。其實就是將對象復制了一份並返還給調用者,對象需繼承Cloneable並重寫clone方法。原型模式的思想就是將一個對象作為原型,對其進行復制、克隆,產生一個和原對象類似的新對象。

二、結構型模式:

1、適配器模式適配器模式是使得原本由於介面不兼容而不能一起工作的那些類可以一起工作,銜接兩個不兼容、獨立的介面的功能,使得它們能夠一起工作,適配器起到中介的作用。

2、裝飾模式:裝飾器模式是動態地給一個對象添加一些額外的職責,給一個對象增加一些新的功能,要求裝飾對象和被裝飾對象實現同一個介面,裝飾對象持有被裝飾對象的實例。除了動態的增加,也可以動態的撤銷,要做到動態的形式,不可以用繼承實現,因為繼承是靜態的。

3、代理模式代理模式是為其他對象提供一種代理以控制對這個對象的訪問,也就是創建類的代理類,間接訪問被代理類的過程中,對其功能加以控制。

4、外觀模式外觀模式是為子系統中的一組介面提供一個一致的界面,外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。

5、橋接模式橋接模式是將抽象部分與實現部分分離,使它們都可以獨立的變化。橋接模式就是把事物和其具體實現分開,使他們可以各自獨立的變化(突然聯想到了mvc模式)。

6、組合模式:組合模式是將對象組合成樹形結構以表示"部分-整體"的層次結構,組合模式使得用戶對單個對象和組合對象的使用具有一致性。

7、享元模式:享元模式是運用共享技術有效地支持大量細粒度的對象。享元模式的主要目的是實現對象的共享,即共享池,當系統中對象多的時候可以減少內存的開銷,重用現有的同類對象,若未找到匹配的對象,則創建新對象,這樣可以減少對象的創建,降低系統內存,提高效率。

三、行為型模式:

1、策略模式:

策略模式是定義一系列的演算法,把它們一個個封裝起來, 並且使它們可相互替換,且演算法的變化不會影響到使用演算法的客戶。

2、模版方法模式:

模板方法模式是定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。該模式就是在一個抽象類中,有一個主方法,再定義1...n個方法,可以是抽象的,也可以是實際的方法,定義一個類,繼承該抽象類,重寫抽象方法,通過調用抽象類,實現對子類的調用。

模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟,將一些固定步驟、固定邏輯的方法封裝成模板方法。調用模板方法即可完成那些特定的步驟。

3、觀察者模式:

觀察者模式是定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。

也就是當被觀察者狀態變化時,通知所有觀察者,這種依賴方式具有雙向性,在QQ郵箱中的郵件訂閱和RSS訂閱,當用戶瀏覽一些博客時,經常會看到RSS圖標,簡單來說就是當訂閱了該文章,如果後續有更新,會及時通知用戶。這種現象即是典型的觀察者模式。

4、迭代器模式:

迭代器模式是提供一種方法順序訪問一個聚合對象中各個元素, 而又無須暴露該對象的內部表示。

在Java當中,將聚合類中遍歷各個元素的行為分離出來,封裝成迭代器,讓迭代器來處理遍歷的任務;使簡化聚合類,同時又不暴露聚合類的內部,在我們經常使用的JDK中各個類也都是這些基本的東西。

5、責任鏈模式:

責任鏈模式是避免請求發送者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,並且沿著這條鏈傳遞請求,直到有對象處理它為止。有多個對象,每個對象持有對下一個對象的引用,這樣就會形成一條鏈,請求在這條鏈上傳遞,直到某一對象決定處理該請求。

6、命令模式:

命令模式是將一個請求封裝成一個對象,從而使發出者可以用不同的請求對客戶進行參數化。模式當中存在調用者、接收者、命令三個對象,實現請求和執行分開;調用者選擇命令發布,命令指定接收者。

7、備忘錄模式:

備忘錄模式是在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。創建一個備忘錄類,用來存儲原始類的信息;同時創建備忘錄倉庫類,用來存儲備忘錄類,主要目的是保存一個對象的某個狀態,以便在適當的時候恢復對象,也就是做個備份。

8、狀態模式:

狀態模式是允許對象在內部狀態發生改變時改變它的行為。對象具有多種狀態,且每種狀態具有特定的行為。

9、訪問者模式:

訪問者模式主要是將數據結構與數據操作分離。在被訪問的類裡面加一個對外提供接待訪問者的介面,訪問者封裝了對被訪問者結構的一些雜亂操作,解耦結構與演算法,同時具有優秀的擴展性。通俗來講就是一種分離對象數據結構與行為的方法。

10、中介者模式:

中介者模式是用一個中介對象來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的交互。

11、解釋器模式:

解釋器模式是給定一個語言,定義它的文法表示,並定義一個解釋器,這個解釋器使用該標識來解釋語言中的句子,基本也就用在這個范圍內,適用面較窄,例如:正則表達式的解釋等。


(4)visitorjava擴展閱讀:

軟體設計的概念以及意義:

軟體設計模式是對軟體設計經驗的總結,是對軟體設計中反復出現的設計問題的成功解決方案的描述。為了記錄這些成功的設計經驗並方便以後使用,軟體設計模式通常包含 4 個基本要素:模式名稱、問題、解決方案以及效果。

模式名稱實際上就是一個幫助記憶的名稱,是用於軟體設計的技術術語,有助於設計者之間的交流。

問題描述了設計者所面臨的設計場景,用於告訴設計者在什麼情況下使用該模式。

解決方案描述了設計的細節,通常會給出方案的原理圖示(例如 UML 的類圖,序列圖等,也可能是一些示意圖)及相關文字說明,如果可能,還會給出一些代碼實例,以便對解決方案的深入理解。

效果描述了設計方案的優勢和劣勢,這些效果通常面向軟體的質量屬性,例如,可擴展性、可復用性等。

軟體設計模式的重要意義在於設計復用。設計模式可以使設計者更加方便地借鑒或直接使用已經過證實的成功設計方案,而不必花費時間進行重復設計。一些設計模式甚至提供了顯示的類圖設計及代碼實例,為設計的文檔化及軟體的開發提供了直接的支持。

Ⅳ java中visitor什麼意思

你想說的是vector吧
Vector 類在 java 中可以實現自動增長的對象數組。
Java中,數組對象一旦慶歲創建後,其元素的個數 不能被修改。而Java.util包中的Vector類(向量)提供類似於數組的能力,且能夠動態地調整自身的大小。Vector類似於一個數組,但與數組相比在使用上譽散睜有兩個優點:
① 使用的時候無須聲明上限,隨著元素的增加,Vector的長度會自動增加;
② Vector類提供額外的方法來增加、刪除元素,比數組操作掘昌高效。

Ⅵ java訪問者模式中Visitor.visitor(this)中的this是什麼意思舉個例子詳細說

this就是當前類啊
這個意思就是把當前類的當前對象傳到visitor對象裡面

Ⅶ java 可以動態創建 屬性欄位么

可以的,你用 javassist, cglib 或者更為底層的工具 ASM 都是可以。

ASM 的話相對復雜一些,參考代碼:

下面這個是用 ASM 工具為 Student 類添加一個 public String 類型的 address 屬性:

1,需要添加屬性的原始類:Student.java

Java code?

public class Student {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

2,添加屬性的適配器:AddFieldAdapter.java

Java code?

import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;

public class AddFieldAdapter extends ClassAdapter {
private int accessModifier;
private String name;
private String desc;
private boolean isFieldPresent;

public AddFieldAdapter(ClassVisitor cv, int accessModifier, String name, String desc) {
super(cv);
this.accessModifier = accessModifier;
this.name = name;
this.desc = desc;
}

@Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
if (name.equals(this.name)) {
isFieldPresent = true;
}
return cv.visitField(access, name, desc, signature, value);
}

@Override
public void visitEnd() {
if (!isFieldPresent) {
FieldVisitor fv = cv.visitField(accessModifier, name, desc, null, null);
if (fv != null) {
fv.visitEnd();
}
}
cv.visitEnd();
}
}

3,添加屬性的工具 AddField.java

Java code?

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;

public class AddField {

private Class clazz = null;
private ClassReader cr = null;
private ClassWriter cw = null;
private ClassAdapter ca = null;
private File classFile = null;

private final static String CLASS_FILE_SUFFIX = ".class";

public AddField(Class clazz) {
this.clazz = clazz;
}

/**
* 添加一個 public 的類成員
* @param fieldName 類成員名
* @param fieldDesc 類成員類型描述
*/
public void addPublicField(String fieldName, String fieldDesc) {
if(cr == null) {
try {
cr = new ClassReader(clazz.getCanonicalName());
} catch (IOException e) {
e.printStackTrace();
}
cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
}
if(ca == null) {
ca = new AddFieldAdapter(cw, Opcodes.ACC_PUBLIC, fieldName, fieldDesc);
} else {
ca = new AddFieldAdapter(ca, Opcodes.ACC_PUBLIC, fieldName, fieldDesc);
}
}

/**
* 將位元組碼寫入類的 .class 文件
*
*/
public void writeByteCode() {
cr.accept(ca, ClassReader.SKIP_DEBUG);
byte[] bys = cw.toByteArray();
OutputStream os = null;
try {
os = new FileOutputStream(getFile());
os.write(bys);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

/**
* 獲得類文件的 File 對象
* @return
*/
private File getFile() {
if(classFile == null) {
StringBuffer sb = new StringBuffer();
sb.append(clazz.getResource("/"))
.append(clazz.getCanonicalName().replace(".", File.separator))
.append(CLASS_FILE_SUFFIX);
classFile = new File(sb.substring(6));
}
return classFile;
}
}

Ⅷ java如何統計網站訪問量

步驟一、建一個表,表名任意,這里取名為:visitorcounter,表的結構如下所示:
+-------+------------------+------+-----+------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+------------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| vdate | date | NO | | 2000-01-01 | |
| vnum | int(11) | NO | | 0 | |
+-------+------------------+------+-----+------------+----------------+
步驟二、建立一個java類,名字也為:visitorcounter,類的內容如下:
package com.hdzx.pub;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.Date;
public class VisitorCounter {
private final static String TABLE_NAME = "visitorcounter";
private static String today = null;
private static long today_num = 0;
private static long total_num = 0;
//載入訪問量
public static void loadNum(){
if(total_num<1)
loadTotalNum();
if(today_num<1)
loadToadyNum();
}
//載入今日訪問量
private static void loadToadyNum() {
// TODO Auto-generated method stub
DBConnect db = null;
ResultSet rs = null;
if(today==null)
today = getTodayDate();
String sql = "select vnum from "+TABLE_NAME+" where vdate='"+today+"'";
try {
db = new DBConnect();
rs = db.executeQuery(sql);
if(rs.next()){
today_num = rs.getLong("vnum");
}
else
{
sql = "insert into "+TABLE_NAME+"(vdate,vnum) values('"+today+"',0)";
db.executeUpdate(sql);
today_num = 0;
}
} catch (Exception e) {
// TODO: handle exception
today_num = 0;
System.out.println("com.hdzx.pub~VisitorCounter.incTotalCounter:獲得訪問人數");
}
}
//載入總訪問量
private static void loadTotalNum() {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
DBConnect db = null;
ResultSet rs = null;
if(today==null)
today = getTodayDate();
String sql = "select vnum from "+TABLE_NAME+" where id=1";
try {
db = new DBConnect();
rs = db.executeQuery(sql);
if(rs.next()){
total_num = rs.getLong("vnum");
}
else
{
total_num = 0;
}
} catch (Exception e) {
// TODO: handle exception
total_num = 0;
System.out.println("com.hdzx.pub~VisitorCounter.incTotalCounter:獲得訪問人數");
}
}
//增加總的訪問量
private static int incTotalCounter(){
int k = 0;
DBConnect db = null;
loadNum();
total_num = total_num+1;
String sql = "update "+TABLE_NAME+" set vnum="+total_num+" where id=1";
try {
db = new DBConnect();
k = db.executeUpdate(sql);
} catch (Exception e) {
// TODO: handle exception
System.out.println("com.hdzx.pub~VisitorCounter.incTotalCounter:增加訪問人數");
}
return k;
}
//增加今日的訪問量
public static int incTodayCounter(){
int k = 0;
DBConnect db = null;
String sql = null;
loadNum();
today_num += 1;
sql = "update "+TABLE_NAME+" set vnum="+today_num+" where vdate='"+today+"'";
try {
db = new DBConnect();
k = db.executeUpdate(sql);
if(k > 0)
incTotalCounter();
} catch (Exception e) {
// TODO: handle exception
System.out.println("com.hdzx.pub~VisitorCounter.incTotalCounter:增加訪問人數");
}
return k;
}
//獲得今天的日期
private static String getTodayDate(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(new Date());
}
///獲得今日訪問量
public static long getTodayNum(){
loadNum();
return today_num;
}
//獲得總的訪問量
public static long getTotalNum(){
loadNum();
return total_num;
}
}
步驟三、經過以上的步驟後,在頁面中加入以下的代碼,就可以實現網站訪問量的統計工作:
if(session.isNew())
{
VisitorCounter.incTodayCounter();
}
%>
今日訪問量:<%=VisitorCounter.getTodayNum() %><br/>
總的訪問量: <%=VisitorCounter.getTotalNum() %>

閱讀全文

與visitorjava相關的資料

熱點內容
伺服器端渲染的數據怎麼爬 瀏覽:163
壓縮空氣噴射器 瀏覽:488
python提高效率 瀏覽:796
華為文件管理怎麼樣輸入解壓碼 瀏覽:800
深思加密狗初始化 瀏覽:566
黃金崩潰pdf 瀏覽:309
華為特定簡訊息加密 瀏覽:375
微機原理與單片機技術李精華答案 瀏覽:816
pic12c508單片機 瀏覽:309
androidgps調用 瀏覽:226
金文編pdf 瀏覽:445
14乘87減147的簡便演算法 瀏覽:473
怎麼創建edu文件夾 瀏覽:721
演算法的基礎問題 瀏覽:256
蘋果手機怎麼選擇app支付 瀏覽:856
訪問加密伺服器失敗怎麼回事 瀏覽:439
程序員每天跑步5公里 瀏覽:789
黨員對程序員有幫助么 瀏覽:550
慢跑穿壓縮衣還是緊身衣 瀏覽:214
什麼伺服器引擎最好 瀏覽:497