設計模式--裝飾者模式和建造者模式
1. 裝飾者模式
動態地給一個對象添加一些額外的職責。就增加功能來說, Decorator模式相比生成子類更為靈活,而且能解決繼承子類爆炸問題。
參與者
1.Component(被裝飾對象的基類)
定義一個對象接口,可以給這些對象動態地添加職責。
2.ConcreteComponent(具體被裝飾對象)
定義一個對象,可以給這個對象添加一些職責。
3.Decorator(裝飾者抽象類)
維持一個指向Component實例的引用,並定義一個與Component接口一致的接口。
4.ConcreteDecorator(具體裝飾者)
具體的裝飾對象,給內部持有的具體被裝飾對象,增加具體的職責。
代碼案例:
Component (被裝飾對象的基類)
public interface Person { void eat(); }
ConcreteComponent (具體被裝飾對象)
public class Man implements Person { public void eat() { System.out.println("男人在吃"); } }
Decorator (裝飾者抽象類)
public abstract class Decorator implements Person { protected Person person; public void setPerson(Person person) { this.person = person; } public void eat() { person.eat(); } }
ConcreteDectrator (具體裝飾者)
public class ManDecoratorA extends Decorator { public void eat() { super.eat(); reEat(); System.out.println("ManDecoratorA類"); } public void reEat() { System.out.println("再吃一頓飯"); } } public class ManDecoratorB extends Decorator { public void eat() { super.eat(); System.out.println("==============="); System.out.println("ManDecoratorB類"); } }
Test
public class Test { public static void main(String[] args) { Man man = new Man(); ManDecoratorA md1 = new ManDecoratorA(); ManDecoratorB md2 = new ManDecoratorB(); md1.setPerson(man); md2.setPerson(md1); md2.eat(); } }
2. 建造者模式
在用戶不知道對象的建造過程和細節的情況下就可以直接創建復雜的對象。
舉個例子:
那我們新建一個人的類。
Person類
public class Person { private String head; private String body; private String foot; public String getHead() { return head; } public void setHead(String head) { this.head = head; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getFoot() { return foot; } public void setFoot(String foot) { this.foot = foot; } @Override public String toString() { return "Person [head=" + head + ", body=" + body + ", foot=" + foot + "]"; } }
定義了造人標準的接口 PersonBuilder
public interface PersonBuilder { void buildHead(); void buildBody(); void buildFoot(); Person buildPerson(); }
既然接口都有了,我們就按照人的一些特性,建造一個機器人 Robot 吧。
public class Robot implements PersonBuilder { Person person; public Robot(){ person = new Person(); } //創建一個機器人 @Override public void buildHead() { person.setHead("機器人的頭部"); System.out.println("正在構造機器人的頭部"); } @Override public void buildBody() { person.setBody("身體"); System.out.println("正在構造機器人的身體"); } @Override public void buildFoot() { person.setFoot("腳"); System.out.println("正在構造機器人的腳部"); } @Override public Person buildPerson() { System.out.println("機器人構造完畢"); return person; } }
這個機器人 Robot 實現了 PersonBuilder 這個造人標準的接口了。最後返回造好的Robot。
好的,其實到這裏呢,我們已經完成了建造的過程。那就這麽簡單的建造過程,還搞了一個建造模式嗎?非也。接下來,就是介紹建造者模式的精髓,那就是director。這個director呢,就是來執行我們剛才的造人動作的。沒錯,精髓就是我們剛才的造人動作。我們先看代碼:
Director類
public class Director { public Person createRobotByDirector(PersonBuilder pb){ pb.buildBody(); pb.buildFoot(); pb.buildHead(); return pb.buildPerson(); } }
這個director類呢,重點在於createRobotByDirecotr的參數是我們的造人標準的接口。這樣一來,只要是實現了我們的這個接口的類,就都可以作為參數,我們剛剛不是造了一個高智商的人嗎?那我們如果想造一個身體運動能力出色的人,也就是運動員,這個director也可以啟動這個造人過程,只要我們把這個運動員的類先寫好。我們來看看director是如何發揮的
public class Test { public static void main(String[] args) { Director d = new Director(); Person p = d.createRobotByDirector(new Robot()); System.out.println(p); } }
運行結果:
正在構造機器人的身體 正在構造機器人的腳部 正在構造機器人的頭部 機器人構造完畢 Person [head=機器人的頭部, body=身體, foot=腳]
看,createRobotByDirecotr這個方法帶的參數就是我們高智商人的那個類。那我們想造一個運動員,就可以像高智商人那樣建好類,然後傳進來就可以了!
總結: 其實根本就不會知道具體是怎麽造人的,因為這個過程讓director給代勞了。故體現了:在用戶不知道對象的建造過程和細節的情況下就可以直接創建復雜的對象。
設計模式--裝飾者模式和建造者模式