天天看點

java裝飾者模式和擴充卡模式

java中裝飾模式,裝飾類和被裝飾類要實作同一個接口,為什麼?怎麼了解呢
裝飾者需要和被裝飾者必須是一樣的類型,原因有兩個:其一是裝飾者必須能取代被裝飾者,也就是說裝飾者可以脫離被裝飾者單獨使用。其二是裝飾者和被裝飾者必須達到類型比對,這樣他們才能組合在一起,然後共同去描述和修飾某一事物。
裝飾者模式,在javajdk中典型的應用是io流:被裝飾者FileInputStream和裝飾者FilterInputStream都是繼承自InputStream。我把他們的類圖給你黏貼出來:
回答滿意的話給最佳噢~
java裝飾模式和繼承的差別
java裝飾模式和繼承的差別如下:
裝飾模式以對客戶透明的方式動态地給一個對象附加上更多的責任。換言之,用戶端并不會覺得對象在裝飾前和裝飾後有什麼不同。裝飾模式可以在不使用創造更多子類的情況下,将對象的功能加以擴充。
什麼是java裝飾設計模式
在不必改變原類檔案和使用繼承的情況下,動态地擴充一個對象的功能。它是通過建立一個包裝對象,也就是裝飾來包裹真實的對象。
public class Test {
// 将内容寫到另一個檔案
public void write() {
String string = "測試包裝模式";
try {
FileWriter fw = new FileWriter("D:/copyfile.txt");
// 用到包裝模式,擴充FileWriter的功能
BufferedWriter bW = new BufferedWriter(fw);
bW.write(string);
bW.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Test test = new Test();
test.write();
}
}執行結果:
關于java中裝飾者模式的詳解,不了解啊,,誰給解釋解釋。。。
裝飾者模式可以動态地給一個對象增加其他職責。就擴充對象功能來說,裝飾者模式比生成子類更為靈活。(定義)
不給你寫代碼了,寫了估計你也不看。
簡單的給你解釋吧:你隻會做一件事情A,我想讓你去做B-A這件事情,不改變你的行為,你肯定不會做的。但是小明會做另一件事情B,是以我就可以讓小明去做B,并且告訴小明做完後 如果遇見你 就讓你做事情A。讓後我們你們兩個放在一塊,讓小明做B,然後事情B-A就可以被做了。同樣我想完成事情C-A,隻要找到會做C的小王就可以了。
在這裡你就是被裝飾者,小明和小王就是裝飾者。之是以把你叫做裝飾者,可能是因為你做的事情是主要的事情。其實這些都是可以靈活利用的 。
建議你看書header first 設計模式
如果想看代碼,百度太多了。
如果不明白,可以追問。DataInputStream bis = new DataInputStream(new BufferedInputStream(new FileInputStream("File")));
 BufferedInputStream bis2 = new BufferedInputStream(new DataInputStream(new FileInputStream("File")));BufferedInputStream添加了緩沖功能,請問,bis還有緩沖功能麼?bis現在是DataInputStream類型的,bis2才是BufferedInputStream類型的,這是我學些IO的一個問題,為什麼bis還有緩沖功能?
問題:動态給一個對象添加一些額外的職責
思考:可以修改這個類的源代碼嗎?
回答:可以
思考:那直接修改源代碼就行了
問題:如果不可以修改呢?
思考:如果不可以修改源代碼,那怎麼添加?
回答:有一些類庫可以直接修改編譯後的class檔案,但是這裡不考慮
可以直接包含這個類的對象,如果這個類有實作某些接口,剛好某個需要添加額外智能的方法正好是其中一個方法,那就好辦了
Son這個類的paint()方法需要添加一些額外的功能
package decorator;
public class Son implements Work {
  public void paint() {
System.out.println("兒子用鉛筆畫好了一幅畫。");
}這個類不是實作了Work方法嗎?那就好辦了,建立一個類,繼承Work接口:
package decorator;
public class Mother implements Work {
  //被裝飾者
  private Work work;
  public Mother(Work work) {
this.work = work;
  private Mother() {}
  public void paint() {
//媽媽裝飾者做的職責
System.out.println("媽媽正在做給畫上顔色前的準備工作。");
//被裝飾者做的職責
work.paint();
//媽媽裝飾者做的職責
System.out.println("媽媽給畫上好了顔色。");
}那個所謂的Work接口:
package decorator;
public interface Work {
  public void paint();
}你不是想讓Son可以的paint方法多做點工作麼?那我new出Mother類執行paint方法不就可以了嗎
看代碼就知道,其實這個裝飾器模式并不怎麼好用,每個需要裝飾的類或者需要繼承某個接口,這實在是一個限制
網上找的資料:
裝飾模式(Decorator)
裝飾模式又名包裝(Wrapper)模式。
裝飾模式以對用戶端透明的方式擴充對象的功能,是繼承關系的一個替代方案。
裝飾模式通過建立一個包裝對象,也就是裝飾,來包裹真實的對象。
裝飾模式以對用戶端透明的方式動态地給一個對象附加上更多的責任。換言之,用戶端并不會覺得對象在裝飾前和裝飾後有什麼不同。
裝飾模式可以在不創造更多子類的情況下,将對象的功能加以擴充。
裝飾模式把用戶端的調用委派到被裝飾類。裝飾模式的關鍵在于這種擴充是完全透明的。
裝飾模式的角色
抽象構件角色(Component):給出一個抽象接口,以規範準備接收附加責任的對象。
具體構件角色(Concrete Component):定義将要接收附加責任的類。
裝飾角色(Decorator):持有一個構件(Component)對象的引用,并定義一個與抽象構件接口一緻的接口。
具體裝飾角色(Concrete Decorator):負責給構件對象“貼上”附加的責任。
Java IO中的裝飾模式
在IO中,具體構件角色是節點流,裝飾角色是過濾流。
FilterInputStream和FilterOutputStream是裝飾角色,而其他派生自它們的類則是具體裝飾角色。
裝飾模式的特點
裝飾對象和真實對象有相同的接口。這樣用戶端對象就可以以和真實對象相同的方式和裝飾對象互動。
裝飾對象包含一個真實對象的引用(reference)。
裝飾對象接收所有來自用戶端的請求,它把這些請求轉發給真實的對象。
裝飾對象可以在轉發這些請求之前或之後附加一些功能。
這樣就確定了在運作時,不用修改給定對象的結構就可以在外部增加附加的功能。
public interface Component
public void doSomething();
}這是抽象構件角色,是一個接口。具體構件角色實作這個接口:
public class ConcreteComponent implements Component
@Override
public void doSomething()
{
System.out.println("功能A");
}
}裝飾角色:
public class Decorator implements Component
private Component component;
public Decorator(Component component)
{
this.component = component;
}
@Override
public void doSomething()
{
component.doSomething();
}
}其中包含了構件角色的引用,方法調用中利用構件角色的方法。
具體裝飾角色(兩個):
public class ConcreteDecorator1 extends Decorator
public ConcreteDecorator1(Component component)
{
super(component);
}
@Override
public void doSomething()
{
super.doSomething();
this.doAnotherThing();
}
private void doAnotherThing()
{
System.out.println("功能B");
}
}public class ConcreteDecorator2 extends Decorator
public ConcreteDecorator2(Component component)
{
super(component);
}
@Override
public void doSomething()
{
super.doSomething();
this.doAnotherThing();
}
private void doAnotherThing()
{
System.out.println("功能C");
}
}使用測試:
public class Client
public static void main(String[] args)
{
Component component = new ConcreteComponent();
Component component1 = new ConcreteDecorator1(component);
component1.doSomething();
System.out.println("-----------");
Component component2 = new ConcreteDecorator2(component1);
component2.doSomething();
}
-----------
功能C沒必要死鑽模式,意義不大,了解開閉原則即可這些模式多用就會了。現在不用過分深究