
2005年8月2日
模板模式:
模板方法中分兩種方法:一種是模板方法,另一種是基本方法。
模板方法:就是把基本方法組合在一起形成一個總算法或則總行為,這個模板方法一般會在抽象定義并且在子類種不加以修改的繼承下來。一個抽象類可以有任意多個模板方法。
基本方法:它又分為抽象方法,具體方法,鉤子方法。
抽象方法由抽象類申明,由子類具體實現;具體方法由抽象類申明并實現,而子類并不實現或則置換,這里面也可以有工廠方法;鉤子方法,由抽象類申明并實現,但是它是一個空的實現,一般都是由子類進行擴張實現。
posted @
2005-08-19 21:15 sky 閱讀(373) |
評論 (0) |
編輯 收藏
import java.io.*;
public class FileRead{
private static double totalFile = 0;
private static double totalDirectory = 0;
public String replace(String value){
StringBuffer replace = new StringBuffer(value);
int i = 0;
int last = replace.lastIndexOf("──");
i = replace.indexOf("──");
while((i != last)&&(i != -1)){
replace.replace(i,i+"──".length()," ");
i = replace.indexOf("──");
last = replace.lastIndexOf("──");
}
return replace.toString();
}
public void searchFile(File f,String value,boolean b)throws IOException{
StringBuffer string = new StringBuffer(value);
string.append("──");
boolean bool = b;
String path = f.getAbsolutePath();
File currentFile = new File(path); //取得當前路徑的文件
File[] file = currentFile.listFiles();
for(int i=0;i<file.length;i++){
StringBuffer s = null;
String lastDirectory = null;
/*
* 判斷文件夾是否為該目錄下的最后一個文件夾,如果是的話,則取消打印"│"符號
*/
for(int k=0;k<file.length;k++){
if(file[k].isDirectory())
lastDirectory = new String(file[k].getName());
}
if(file[i].getName().equals(lastDirectory)){
if(string.indexOf("│") != -1){
string.delete(string.lastIndexOf("│"),string.lastIndexOf("│")+1);
}
}
/*
* 格式化打印,將符號最后的"──"變為"├──"(當最后的符號不為"│──"時)
*/
if(!((string.lastIndexOf("──")-1) == string.lastIndexOf("│──"))){
s = new StringBuffer(string.substring(0,string.lastIndexOf("──")));
s.append("├──");
}else{
if(string.indexOf("│──")!=-1){
s = new StringBuffer(string.substring(0,string.lastIndexOf("│──")));
s.append("├──");
}
}
if(file[i].getName().equals(file[file.length-1].getName()))
if(s != null)
if(s.lastIndexOf("├") != -1)
s.replace(s.lastIndexOf("├"),s.lastIndexOf("├")+1,"└");
/*
* 如果s不為空,則將s傳入方法replace中進行格式化
*/
if(s != null)
System.out.println(replace(s.toString()) + file[i].getName());
if(file[i].isDirectory()){
totalDirectory += 1;
/*
* 如果該文件夾的子目錄下還有兩個以上的文件和文件夾,則打印一個"│"符號,并標記bool為true
*/
String pathstring = file[i].getAbsolutePath();
File current = new File(pathstring); //取得當前路徑的文件
File[] fp = current.listFiles();
if(fp.length >1){
bool = true;
}
if(bool)
string.append("│");
searchFile(file[i],string.toString(),bool);
/*
* 如果bool已經被標記過,則將上一次的"│"符號刪除
*/
if(bool)
if(string.indexOf("│") != -1)
string.delete(string.lastIndexOf("│"),string.length());
bool = false;
}
totalFile += 1;
}
}
public static void main(String args[])throws IOException{
String path = null;
if(args.length<1)
path =".";
else
path = args[0];
FileRead read = new FileRead();
File file = new File(path);
if(!file.exists()){
System.err.print("the path is error");
System.exit(1);
}
read.searchFile(file,"│",false);
System.out.println("the file is :" + (totalFile-totalDirectory));
System.out.println("thd directory is : " + totalDirectory);
}
}
該程序存在一個問題,也就是當jdk中的File類無法判斷目錄下的一些目錄是文件夾或則是文件時?
posted @
2005-08-19 20:20 sky 閱讀(577) |
評論 (0) |
編輯 收藏
策略模式:
策略模式的對算法的包裝,是把使用算法的責任和算法本生分開,委派給不同的對象管理。策略模式通常把一個系列的算法包裝到一系列的策略類里面,作為一個抽象策略類的子類。
使用條件:
如果在一個系統種有許多類,他們之間的區別僅僅在于他們的行為,并且這個系統需要動態的在幾種算法種選擇一種。
posted @
2005-08-14 23:51 sky 閱讀(190) |
評論 (0) |
編輯 收藏
不變模式:
不變模式可以增強對象的強壯性,不變模式準許多個對象共享一個對象,這降低了對該對象進行并發訪問時的同步化開銷。如果要修改一個不變對象的狀態,則需要創建一個新的對象,并將其存入新的對象里。不變模式只涉及到一個類,一個類的內部狀態一旦被創建以后,在整個期間都不會發生變化。他有兩種一種是強不變模式和弱不變模式。
弱不變模式:
首先滿足沒有方法可以改變對象的狀態,則對象一旦被創建之后,對象的狀態就不會改變。二該對象的所有的屬性都是私有的,并且不準許聲明任何公有的方法來改變他們。三這個對象所引用的對象也應該是不變的對象,如果在初始化時應用了一個可變的對象,則應該對該可變對象進行復制一份,而不要使用原來的拷貝。這種模式的缺點是他可以用子類,并且子類可以是可變的對象。可變的子類可能一修改父類對象的狀態,從而可能會允許外界修改父對象的狀態。
問題: 為什么說可變的對象可以修該父類對象的狀態呢?怎樣做?
強不變模式首先要滿足弱不變模式,然后將這個類聲明成final類,則它變不可能有子類了,并且也將該對象所考慮到的所有方法聲明為final。
不變模式與享元模式有很大的相同處,他們的對象狀態都有要求不隨環境的變化而變化,不過享元模式的內涵狀態在不影響享元對象的共享時,可以為可變的。不變模式對對象的要求要比享元模式對對象的要求更嚴格。
posted @
2005-08-14 23:39 sky 閱讀(640) |
評論 (2) |
編輯 收藏
橋梁模式:
橋梁模式就是抽象化和實現化脫藕,使得兩者可以獨立地變法。例子如java中的peer架構。
橋梁模式與適配器模式的區別是,
posted @
2005-08-12 23:28 sky 閱讀(331) |
評論 (0) |
編輯 收藏
門面模式:
在外界訪問要訪問多個內部系統時,并且他與這些內部系統有著復雜的關系時,我們則可以用門面模式來解決這樣的問題。
門面模式他只是提供一個可以共外界方便訪問內部子系統的一個接口,他并不會對子系統進行擴展,他只提供子系統所具有的方法。對外界來說,他是一個子系統,但是內部的子系統并不知道有這么一個類。例如:一個學生要去圖書館借書,這里有3個表,rule是記錄不同的讀者的借書規則(如研究生可以借7而本科生只能借4本),publish表是記錄過期未還書的學生,passwork是記錄圖書館所頒發過的借書證。如果一個學生要借書,則他必須要有一個在passwork中存在的借書證,并且沒有在publish中的情況,則可以保證向該學生提供借閱,但是借閱的書則要按rule中的規則來進行。所以一個學生client借書必須訪問這些類,為了便于管理,我們提供一個 FacadeFactory類來處理,這個類提供了所有client向子系統訪問的方法。這樣對于client來說就輕松多了,也便于我們維護代碼了。但是FacadeFactory不能夠向client提供內部子系統不存在的方法。
由于一個系統中所需要的只需要一個實例,則我們可以把門面類設置為單例類,如上面的FacadeFactory,他應該設置為一個單例類,這樣就不會發生多個人同時借一本書了。
posted @
2005-08-12 19:38 sky 閱讀(233) |
評論 (0) |
編輯 收藏
享元模式:flyweight pattern
享元模式包括兩種狀態,內蘊狀態和外蘊狀態。他的種類有單純享元模式和復合享元模式,結構圖如下:
我們從結構種可以看出,復合享元模式是由單純享元模式和合成模式組合而成的。
享元模式有四種角色:抽象享元角色,具體享元角色,享元工廠角色,和客戶角色。享元模式中的享元工廠角色可以通過單例模式來實現。
使用條件:
一個系統中有大量的對象,這些對象消耗大量的內存,這些對象大部份是可以外部化的,這些對象可以按照內蘊狀態分成很多的組,當把外蘊對象從對象中踢除時,每一個組都可以僅用一個對象代替,軟件系統不依賴這些對象的身份,換言之,這些對象可以是不可分辨的。不過他要使用一個維護記錄了系統已有的所以享元的表,而這需要消耗資源。因此應當在有足夠多的享元的實例可提供共享實才值得使用享元模式。
posted @
2005-08-11 22:37 sky 閱讀(265) |
評論 (0) |
編輯 收藏
裝飾模式:
他的各個角色的作用為:抽象角色:給出一個抽象的接口,以規范準備接收附加責任的對象。
具體角色:定義一個將要接收附加責任的類。
裝飾角色:持有一個構件對象的實例,并定義一個雨抽象接口一致的接口。
具體裝飾角色:負責給構件對象“貼上”附加責任。
裝飾類一般在以下情況使用:
1、 需要擴展一個類的功能,或給一個類增加附加責任。
2、 需要動態的給一個對象增加功能,這些功能可以再動態的測銷。
3、 需要增加由一些基本的排列組合產生非常大量的功能,從而使繼承關系變得不現實。
他有很多特點:
1、 裝飾模式雨繼承關系的目的都是要擴展對象的功能,但是裝飾模式可以提供比繼承更多的靈活性。裝飾模式準系統動態的決定“貼上”一個需要的“裝飾”,或者除掉一個不需要的裝飾。而繼承則不同,繼承關系是靜態的,他在系統運行前就決定了。
2、 他可以通過使用不同的具體修飾類以及這些裝飾類的排例組合,設計可以創造更多不同行為的組合。
3、 他雖然比繼承性要靈活,這意味著他比繼承更容易出錯。
缺點:由于使用裝飾模式可以比使用繼承關系需要較少數目的類,但是在另一方面,使用裝飾模式會產生比使用繼承方式更多的對象。這在使用時進行錯誤查詢變得更困難了,特別是這些對象看上去都很像。
posted @
2005-08-11 22:36 sky 閱讀(237) |
評論 (0) |
編輯 收藏
import java.util.*;
class BookName{
String name;
int number;
}
abstract class Note{
BookName name = new BookName();
abstract public void setName(String value);
abstract public int getNumber();
abstract public void setNumber(int value);
abstract public String getName();
}
class StudentNote extends Note implements Cloneable{
BookName name = new BookName();
int isbn;
public void setName(String value){
name.name = value;
}
public void setNumber(int i){
name.number = i;
}
public int getNumber(){
return name.number;
}
public String getName(){
return name.name;
}
public Object clone() throws CloneNotSupportedException{
StudentNote st = new StudentNote();
st = (StudentNote)super.clone();
st.name = new BookName();
st.name.name = name.name;
st.name.number = name.number;
return st;
}
public void setIsbn(int i){
isbn = i;
}
public int getIsbn(){return isbn;}
}
class Manager{
private Vector v = new Vector();
public void add(Note note){
v.addElement(note);
}
public Note get(int i){
return (Note)v.get(i);
}
public int size(){
return v.size();
}
}
class Client{
private StudentNote student;
private static Manager client = new Manager();
public void register()throws CloneNotSupportedException{
student = new StudentNote();
StudentNote st = (StudentNote)student.clone();
client.add(st);
}
public static Manager getInstance(){
return client;
}
}
class test{
public static void main(String[] args)throws CloneNotSupportedException {
Client c = new Client();
c.register();
c.register();
Manager manager = c.getInstance();
StudentNote student = (StudentNote)manager.get(0);
StudentNote st = (StudentNote)manager.get(1);
student.setName("sky");
student.setNumber(101);
student.setIsbn(10001);
st.setName("fly");
st.setNumber(102);
st.setIsbn(10002);
System.out.println(student.getName() + "\t" + student.getNumber() + "\t" + student.getIsbn());
System.out.println(st.getName() + "\t" + st.getNumber() + "\t" + st.getIsbn());
}
}
posted @
2005-08-09 13:03 sky 閱讀(211) |
評論 (0) |
編輯 收藏
<java與模式> ---電子書 page 425
裝飾模式—Decorator
裝飾模式有名包裝模式,裝飾模式以對客戶端透明的方式來擴展對象的功能,是繼承關系的一個替代的方案。
客戶端并不會覺得裝飾模式在裝飾前和裝飾后有什么不同,他可以在不使用更多的子類的情況下來進行對對象的功能加以擴展。結構圖如下:
裝飾模式原來被裝飾類的一個子類的實例,把客戶端的調用委派到被裝飾類。他有以下組成:抽象構件,具體構件,裝飾角色,具體裝飾;他一般在下面這些情況使用他最好:
1、 需要擴展一個類的功能,或給一個類增加附加責任。
2、 需要動態的給一個對象增加功能,這些功能可能被動態的撤消。
3、 需要增加一些基本功能的排例組合而產生的非常大量的功能,從而使繼承關系變得不現實。
優點:他可以靈活的增加一個類或對象的功能,也可以通過不同的具體裝飾類的排例組合設計出更加復雜的,功能更強的類。
缺點:他雖然增加了一個類的靈活性,但同時他也給一個類的管理帶來了復雜性。
posted @
2005-08-03 00:00 sky 閱讀(210) |
評論 (0) |
編輯 收藏
import java.io.*;
public class FileRead{
private static int space=0;
private static double totalFile = 0;
private static double totalDirectory = 0;
public String printSpace(int space){
String str = "";
for(int i=0;i<space;i++)
str += " ";
return str;
}
public void searchFile(File f)throws IOException{
String path = f.getAbsolutePath();
File currentFile = new File(path); //取得當前路徑的文件
File[] file = currentFile.listFiles();
space++;
for(int i=0;i<file.length;i++){
System.out.println(printSpace(space) + file[i].getName());
if(file[i].isDirectory()){
totalDirectory += 1;
searchFile(file[i]);
if(space>0)
space--;
}
totalFile += 1;
}
}
public static void main(String args[])throws IOException{
String path = null;
if(args.length<1)
path =".";
else
path = args[0];
FileRead read = new FileRead();
File file = new File(path);
if(!file.exists()){
System.err.print("the path is error");
System.exit(1);
}
read.searchFile(file);
System.out.println("the file is :" + (totalFile-totalDirectory));
System.out.println("thd directory is : " + totalDirectory);
}
}
這個程序在便歷多文件時會出現問題?不知道問題在哪里?
合成模式
合成模式他是一種樹型結構,他可以通過對合成的圖的單獨部分方法達到對整個合成圖方法問。他由三部分組成,抽象構件—Component和樹枝構件—Composite以及樹葉構件Leaf。合成模式分為兩種,一種是透明式的。另一個是安全式的合成模式。
透明式的合成模式和安全式的合成模式,他們的組成成分都一樣,他們的區別是:透明式的合成模式,他在抽象構件種增加了操作子類對象的一些接口,這樣在實現的過程中,無論是樹枝構件還是樹葉構件都必須實現這些接口,這對樹葉構件來說,這種接口實現是多余的,所以樹葉構件是通過平庸式的方式來實現,這種實現,將造成編譯時可以通過,但是當用戶在應用的過程過如果調用這些方法,將造成運行時的錯誤,這就造成了程序的不安全;而安全式的合成模式,他并沒有在抽象構件實現對子結點接口的申明,他是通過樹枝直接對管理子類所需要的方法進行申明,這就給程序帶來靈活性,但是也給程序帶來不便的管理性,這種實現使得程序不會出現運行時的錯誤。
一般我們在這樣的情況下應用合成模式:
1、當我們要體現構件的部分和整體的結構時。
2、當我們要要忽略個體構件與整體構件的區別時,并且要平等的對待個體構件和整體構件時。
使用合成構件有以下好處:
1、使用合成模式可以很容易的增加新構件的種類。
2、使用合成模式方便了用戶對構件的使用,因為他們不用擔心使用的是樹頁構件還是樹枝構件。
他的缺點:使用合成模式之后在控制樹枝構件的類型就不是那么容易了。
posted @
2005-08-02 01:56 sky 閱讀(176) |
評論 (0) |
編輯 收藏