其實,最早在思考該主題時,只考慮到上一部分,沒想過把具體的設計模式請出來的,然而這樣的東西很難說說服力,所以才決定把這些模式解釋一遍。喜歡
5.主要模式:
iterator, adater, chain of responsibility, builder, proxy, decorator, (template)strategy, bridge, state, visitor,observer, command, mediator
1.iterator模式(反向委托):這是反向委托的應用之一,通過被委托者來獲得委托實例,也就是被委托者先于委托者創建,客戶最終還是面向委托者進行操作,這里迭代器就是委托者,集合就是被委托者,這只是一個形意義上的解釋,例如,當客戶C要求跟負責人R進行會話,而又一時無法找到負責人R時, 剛好C知道R的下屬員工E,當然,R會先找到E(只因為E知道R而已,E只完成一件事,找到R),讓E去把R帶到他的面前來,OK,這樣的話,C就可以和R會話了,但是那個懶散的家伙R,他還是把事交給了員工E,那為什么,客戶不直接讓那員工來處理,而是找了一個負責人來交付呢?有一點, 我們會想,員工級別不夠高,沒人會鳥你的,太牽強了,這樣的解釋。因為我們想讓客戶看到這個負責人是以一致的行為在處理事件,其內部處理委托到具體的員工身上。這樣就無需暴露員工的內部實現細節,又將不同員工不同處理以一致的方式提供給客戶。當然,對客戶隱藏實現細節是委托的效果之一,看你怎么使用它了,你也可以不用在迭代器上,只要任何想隱藏實現細節的,你都可以拿去用。
class Aggregate{
private Object[] array;
public Aggregate(int size){
array = new Object[size];
}
public void put(){
for(int i=0;i<array.length;i++){
array[i] = i;
}
}
public Object getAt(int index){
return array[index];
}
public int length(){
return array.length;
}
public Iterator iterator(){
return new Iterator(this);
}
}
class Iterator{
Aggregate aggregate;
int curIndex = 0;
public Iterator(Aggregate aggregate){
this.aggregate = aggregate;
}
public boolean hasNext(){
return curIndex<aggregate.length();
}
public Object next(){
return aggregate.getAt(curIndex++);
}
}
void main(){
Aggregate aggregate new Aggregate();
aggregate.put(); //初始化數據
for(Iterator iterator = aggregate.iterator();iterator.hasNext();){
String value = (String)iterator.next();
System.out.println(value);
}
}
2.adapter(簡單單向委托):適配器有兩種實現實現方式,其一就是委托,另一種則為繼承。委托方式很簡單,用簡單委托即可實現,代碼如下:
class Adaptee {
public void methodAdaptee(){
....
}
}
class Adapter{
private Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
public void methodAdapter(){
adaptee.methodAdaptee();
}
}
void main(){
Adapter adapter = new Adapter(new Adaptee());
adapter.methodAdapter();
}
Adapter委托者委托被委托者Adaptee處理。這東西生活中到處都是,比如處理電壓不一致問題時所使用的變壓器等等。繼承方式暫略。
3.chain of responsibility(單向簡單委托的傳遞):委托傳遞過程,構成了該模式,看例子。
class A{
public void methodA(){}
}
class B{
A a;
public B(A a){
this.a = a;
}
public void methodB(){
if(未處理) a.methodA();
}
}
class C{
B b;
public C(B b){
this.b = b;
}
public void methodC(){
if(未處理) b.methodB();
}
}
void main(){
C c = new C(new B(new A()));
c.methodC();
}
4.Builder模式(單向簡單委托),首先,委托者(也就是建造者),知道constuct時需要的步驟,他只是把每一步驟委托給被委托者處理,然后返回最終結果,好比,包工頭,他知道建造房屋的步驟,但他不會自己動手,然后在建造過程中,他每進行一個階段都會把該階段的建造過程委托給某個工人,估計這工人還沒瘋之前,他也想當Director了,因為他沒法自己構造房屋,盡管他確實有能力,房屋的從頭到腳他都懂。god讓他只是個工人。
class Builder{
public void buildpart1(){
}
public void buildpart2(){
}
public void buildpart3(){
}
public Object getResult(){
}
}
class Director {
Builder builder;
public Director(Builder builder){
this.builder = builder;
}
public void constuct(){
builder.buildpart1();
builder.buildpart2();
builder.buildpart3();
builder.getResult();
}
}
void main(){
Director director = new Director(new Builder());
director.constuct();
}
5.proxy(單向簡單委托),下面是最原始的委托。
class Subject{
public void methodSubject(){
}
}
class Proxy{
private Subject subject;
public Proxy(){
this.subject = new Subject();
}
public void methodProxy(){
subject.methodSubject();
}
}
void main(){
Proxy proxy = new Proxy();
proxy.methodProxy();
}
代理類似于委托,屬于委托的一種,但是又有區別,為什么呢?因為代理人和本人要有一致的事件處理方式,我們就是為了讓客戶分不清是代理人在幫你處理,還是本人幫你處理,所以必須這樣做,同時,我們會把本人和代理人改成同樣的處理方式(method方法)。出現了這么特殊的委托,那么你是不是覺得有點別扭,好象有種陰影在心里做怪,憑什么要遵守這樣的約定,那么我們就把這魔鬼驅除吧。我們把這些特殊委托的雙方的公共行為提取出來,干什么?安置在接口中,或抽象類中,讓委托雙方都實現或繼承它。OK了,問題解決了。必須遵循的規則被我們分離出來了。之前說過,面向對象思想提倡面向接口或抽象編程,本來,委托雙方都該是基于借口或抽象類的,而且是獨立于不同接口或抽象類的,但是為了簡單起見,我們簡化了。它與這里提取的共同接口或抽象類是有區別的,這里是為了驅除那該死的魔鬼,同時它也無意識的遵循了面向接口或抽象編程的思想,一舉兩得,很好。
演化結果:
abstract class Subject{
abstract public void method();
}
class RealSubject extends Subject{
public void method(){
}
}
class Proxy extends Subject{
private Subject subject;
public Proxy(){
this.subject = new RealSubject();
}
public void method(){
subject.method();
}
}
void main(){
Proxy proxy = new Proxy();
proxy.methodProxy();
}
需要記得的一點是,委托從不強迫你的執行順序,你可以選擇任何委托時機,通用的模型是:
(1)委托前的初始化工作
(2)委托過程
(3)委托后的善后處理
以上三步驟可以多層嵌套,需具體而定。
所以,比如在proxy模式里,你可以在交給代理處理前后做你想做的事。
6.decorator(單向簡單委托)
下面是最原始的委托。
class Component{
public void methodComponent(){
}
}
class Decorator {
private Component component;
public Decorator(Component component){
this.component = component;
}
public void methodDecorator(){
component.methodComponent();
}
}
void main(){
Decorator decorator = new Decorator(new Component());
decorator.methodDecorator();
}
裝飾模式,是動態擴展功能是常用的。先想想,擴展某一類功能,有幾種方式?繼承,委托。那為什么不用繼承呢?因為耦合度太高,每擴展一個功能就得派生一個新的類,這樣的結果,會使類層次不斷膨脹,這種膨脹不只是在一個方向上。它橫縱通吃,有一天你會被多叉樹似的類蜘蛛網捆住的,然后蜘蛛慢慢享受它的美餐。為了逃命我們選擇了委托,讓裝飾者委托被裝飾者,同時為了讓兩者有一致的行為方式,同樣抽象出接口或抽象類。你會發現,這跟proxy模式結構一樣的,沒錯,基本一樣。關鍵是,目的不同,裝飾模式是為了擴展功能,主要對于層次級別的擴展很有用,假如,你為了擴展功能而僅僅派生了一個類,我會建議你使用,繼承擴展。那么層次級別的擴展什么意思呢?就是依據擴展樹的深度來考慮,可能是這樣的,你擴展了原先的某個類A的methodA功能,你給它加了文件的持久化功能,然后,你可能還要在文件持久化上繼續擴展緩沖功能。同時,該樹很可能是多叉的,所以,你可以按照這種方式進行橫向擴展。演化結果:
abstract class Component{
abstract public void method();
}
class ConcreteCompnent extends Component{
public void method(){
}
}
abstract class Decorator extends Component{
protected Component component;
public Decorator(Component component){
this.component = component;
}
public void method(){
component.method();
}
}
class ConcreteDecorator extends Decorator{
public void method(){
base.method();
增加新功能
}
}
proxy可以認為是decorator的簡化形式,上面提到,為了擴展功能而僅僅派生了一個類的方式是不合理的,同樣通過委托來擴展功能而僅僅得到一個裝飾者同樣也是不可取的,但是,我們不會拋棄這樣的結構,如果這種情況產生了,我們改變其名稱--代理,同時改變其目的,OK,得到的就是Proxy模式。然后,我想說的是,委托,是一種形,而真正的意是要結合具體模式的,就象在這里,它可以被解釋為擴展,也可以被解釋為代理。這才是它的意義所在。
posted on 2008-08-13 16:55
zhqh 閱讀(187)
評論(0) 編輯 收藏 所屬分類:
設計模式