1. 程式人生 > >Java基礎-----裝飾者模式

Java基礎-----裝飾者模式

package cn.itcast.other;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;


/*
 裝飾者設計模式:增強一個類的功能,而且還可以讓這些裝飾類互相裝飾。
 
 BufferedReader是不是拓展了FileReader的功能。
 BuferedWriter 也是拓展了FileWriter的功能。
 
 需求1: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有行號。
 
  需求2:編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有分號。
  
  需求3: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有雙引號。
  
 
 需求4: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有行號+ 分號。
  
 需求5: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有分號+ 雙引號。


 需求6: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有雙引號+ 行號。
   
 需求7: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有行號+ 分號+雙引號。
 
----| Reader
-----------| BufferedReader
---------------| BufferedLineNum  帶行號
---------------| BufferedSemi    帶分號
---------------| BufferedQuto   帶雙引
---------------| 子類.. 
---------------|


增強一個類的功能時候我們可以選擇使用繼承:

通過繼承實現增強一個類的功能優點:   程式碼結構清晰,通俗易懂。

缺點: 使用不靈活,會導致繼承的體系過於龐大。

 
 
 
 */
class BufferedLineNum extends BufferedReader{
//行號
int count = 1 ;


public BufferedLineNum(Reader in) {
super(in);
}

@Override
public String readLine() throws IOException {
String line = super.readLine(); 
if(line ==null){
return null;
}
line = count+" "+ line;
count++;
return line;
}
}




//帶分號的緩衝輸入字元流
class BufferedSemi extends BufferedReader{


public BufferedSemi(Reader in) {
super(in);
}

@Override
public String readLine() throws IOException {
String line =  super.readLine();
if(line==null){
return null;
}
line = line+";";
return line;
}
}




//帶雙引號的緩衝輸入字元流
class  BufferedQuto extends BufferedReader{


public BufferedQuto(Reader in) {
super(in);
}

@Override
public String readLine() throws IOException {
String line = super.readLine();
if(line==null){
return null;
}
line = "\""+line+"\"";
return line;
}
}










public class Demo1 {


public static void main(String[] args) throws IOException {
File file = new File("F:\\a.txt");
//建立資料的輸入通道
FileReader fileReader = new FileReader(file);
//建立帶行號的緩衝輸入字元流
BufferedLineNum bufferedLineNum = new BufferedLineNum(fileReader);

//帶有分號的緩衝輸入字元流
BufferedSemi bufferedSemi = new BufferedSemi(fileReader);

//帶有雙引號的緩衝輸入字元流
BufferedQuto bufferedQuto = new BufferedQuto(fileReader);


String line = null;
while((line = bufferedQuto.readLine())!=null){
System.out.println(line);
}

}

}



package cn.itcast.other;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
/*
  裝飾者設計模式:增強一個類的功能,而且還可以讓這些裝飾類互相裝飾。
 
 裝飾者設計模式的步驟:
1. 在裝飾類的內部維護一個被裝飾類的引用。
2. 讓裝飾類有一個共同的父類或者是父介面。
 
 
 裝飾者設計模式要讓這些裝飾類有一個共同的父類的目的是為了讓這些裝飾類可以構成一個裝飾鏈以達到互相裝飾的效果。
 
 需求1: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有行號。
 
  需求2:編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有分號。
  
  需求3: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有雙引號。
  
 
 需求4: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有行號+ 分號。
  
 需求5: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有分號+ 雙引號。


 需求6: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有雙引號+ 行號。
   
 需求7: 編寫一個類拓展BufferedReader的功能, 增強readLine方法返回 的字串帶有行號+ 分號+雙引號。
 
 
 繼承實現的增強類和修飾模式實現的增強類有何區別?


繼承實現的增強類:
優點:程式碼結構清晰,而且實現簡單. 
缺點:對於每一個的需要增強的類都要建立具體的子類來幫助其增強,這樣會導致繼承體系過於龐大。


修飾模式實現的增強類:
優點:內部可以通過多型技術對多個需要增強的類進行增強, 可以是這些裝飾類達到互相裝飾的效果。使用比較靈活。

缺點:需要內部通過多型技術維護需要被增強的類的例項。進而使得程式碼稍微複雜。




*/
import java.io.IOException;




//帶行號的緩衝輸入字元流
class BufferedLineNum2  extends BufferedReader{  

//在內部維護一個被裝飾類的引用。
BufferedReader bufferedReader;

int count = 1;

public BufferedLineNum2(BufferedReader bufferedReader){
super(bufferedReader);// 注意: 該語句沒有任何的作用,只不過是為了讓程式碼不報錯。
this.bufferedReader = bufferedReader;
}


public String readLine() throws IOException{
String line = bufferedReader.readLine();
if(line==null){
return null;
}
line = count+" "+line;
count++;
return line;
}





//帶分號緩衝輸入字元流
class BufferedSemi2 extends BufferedReader{  //為什麼要繼承?  是為了讓這些裝飾類的物件可以作為引數進行傳遞,達到互相裝飾 的效果。


//在內部維護一個被裝飾類的引用。
BufferedReader bufferedReader;


public BufferedSemi2(BufferedReader bufferedReader){ // new BuffereLineNum();
super(bufferedReader);// 注意: 該語句沒有任何的作用,只不過是為了讓程式碼不報錯。
this.bufferedReader = bufferedReader;
}

public String readLine() throws IOException{
String line = bufferedReader.readLine();  //如果這裡的ReadLine方法是呼叫了buffereLineNum的readLine方法,問題馬上解決。
if(line==null){
return null;
}
line = line +";";
return line;
}

}


//緩衝類帶雙引號
class BufferedQuto2 extends BufferedReader{

//在內部維護一個被裝飾的類
BufferedReader bufferedReader;

public BufferedQuto2(BufferedReader bufferedReader){  //new  BufferedSemi2();
super(bufferedReader) ; //只是為了讓程式碼不報錯..
this.bufferedReader = bufferedReader;
}

public String readLine() throws IOException{
String line = bufferedReader.readLine();  //如果這裡的ReadLine方法是呼叫了buffereLineNum的readLine方法,問題馬上解決。
if(line==null){
return null;
}
line = "\""+line +"\"";
return line;
}


}






public class Demo2 {

public static void main(String[] args) throws IOException {
File file = new File("F:\\a.txt");
FileReader fileReader = new FileReader(file);
//建立緩衝輸入字元流
BufferedReader bufferedReader = new BufferedReader(fileReader);
//建立帶行號的緩衝輸入字元流
BufferedLineNum2 bufferedLineNum = new BufferedLineNum2(bufferedReader);

//帶分號的緩衝輸入字元流
BufferedSemi2 bufferedSemi2 = new BufferedSemi2(bufferedLineNum);

//帶雙引號的緩衝輸入字元流
BufferedQuto2 bufferedQuto2 = new  BufferedQuto2(bufferedSemi2);

String line = null;
while((line = bufferedQuto2.readLine())!=null){
System.out.println(line);
}




}

}




package cn.itcast.other;
/*練習:
一家三口每個人都會工作,兒子的工作就是畫畫,母親的工作就是在兒子的基礎上做一個增強,不單止可以畫畫,還可以上塗料。
爸爸的工作就是在媽媽基礎上做了增強,就是上畫框。


*/
interface Work{

public void work();
}


class Son implements Work{


@Override
public void work() {
System.out.println("畫畫...");
}
}




class Mather implements Work{


//需要被增強的類。
Work worker;

public Mather(Work worker){
this.worker = worker;
}

@Override
public void work() {
worker.work();
System.out.println("給畫上顏色..");
}
}




class Father implements Work{


//需要被增強的類的引用
Work worker;

public Father(Work worker){
this.worker = worker;
}


@Override
public void work() {
worker.work();
System.out.println("上畫框...");
}

}




public class Demo3 {

public static void main(String[] args) {
Son s = new Son();
// s.work();
Mather m = new Mather(s);
// m.work();
Father f = new Father(s);
f.work();


}
}