設計模式----裝飾者模式UML和實現代碼

1、什麼是裝飾者模式?

  1. 裝飾者模式定義:

    在沒必要改變原類文件和使用繼承的狀況下,動態地擴展一個對象的功能。它是經過建立一個包裝對象,也就是裝飾來包裹真實的對象。
    java

  2. 類型:結構型模式

  3. 順口溜:橋組享代外

2、裝飾者模式UML





3、JAVA代碼實現

package com.amosli.dp.structural.decorator;

public abstract class Component {
	public abstract void operation();
}

package com.amosli.dp.structural.decorator;

public class ConcreteComponent extends Component {

	@Override
	public void operation() {
		System.out.println("concrete operation...");
	}

}

package com.amosli.dp.structural.decorator;

public class Decorator extends Component {

	private Component component;


	public Component getComponent() {
		return component;
	}


	public void setComponent(Component component) {
		this.component = component;
	}


	@Override
	public void operation() {
		component.operation();
	}

}


package com.amosli.dp.structural.decorator;

public class ConcreteDecoratorA extends Decorator{

	private String addedStat;
	public String getAddedStat() {
		return addedStat;
	}
	public void setAddedStat(String addedStat) {
		this.addedStat = addedStat;
	}
	@Override
	public void operation() {
		super.operation();
		addedStat="addedStat";
		System.out.println("added stat..");
	}
	
}

package com.amosli.dp.structural.decorator;

public class ConcreteDecoratorB extends Decorator {

	@Override
	public void operation() {
		super.operation();
		addBehavior();
	}
	
	public void addBehavior(){
		System.out.println("add behavior");
	}
}


package com.amosli.dp.structural.decorator;

public class Client {
	public static void main(String[] args) {
		Component component = new ConcreteComponent();
		Decorator decorator = new ConcreteDecoratorA();
		Decorator decoratorB = new ConcreteDecoratorB();
		decorator.setComponent(component);
		decoratorB.setComponent(decorator);
		decoratorB.operation();
	}
}


裝飾者模式隱含的是經過一條條裝飾鏈去實現具體對象,每一條裝飾鏈都始於一個Componet對象,每一個裝飾者對象後面緊跟着另外一個裝飾者對象,而對象鏈終於ConcreteComponet對象。git


問題:  說裝飾者模式比用繼承會更富有彈性,在類圖中不是同樣用到了繼承了嗎? 
github

說明:裝飾者和被裝飾者之間必須是同樣的類型,也就是要有共同的超類。在這裏應用繼承並非實現方法的複製,而是實現類型的匹配。由於裝飾者和被裝飾者是同一個類型,所以裝飾者能夠取代被裝飾者,這樣就使被裝飾者擁有了裝飾者獨有的行爲。根據裝飾者模式的理念,咱們能夠在任什麼時候候,實現新的裝飾者增長新的行爲。若是是用繼承,每當須要增長新的行爲時,就要修改原程序了。ide


4、裝飾者模式的應用場景:

一、  想透明而且動態地給對象增長新的職責的時候。this

二、  給對象增長的職責,在將來存在增長或減小可能。spa

三、  用繼承擴展功能不太現實的狀況下,應該考慮用組合的方式。設計

5、優缺點

裝飾者模式的優勢:

一、  經過組合而非繼承的方式,實現了動態擴展對象的功能的能力。code

二、  有效避免了使用繼承的方式擴展對象功能而帶來的靈活性差,子類無限制擴張的問題。component

三、  充分利用了繼承和組合的長處和短處,在靈活性和擴展性之間找到完美的平衡點。orm

四、  裝飾者和被裝飾者之間雖然都是同一類型,可是它們彼此是徹底獨立並能夠各自獨立任意改變的。

五、  遵照大部分GRASP原則和經常使用設計原則,高內聚、低偶合。

裝飾者模式的缺點:

一、  裝飾鏈不能過長,不然會影響效率。

二、  由於全部對象都是繼承於Component,因此若是Component內部結構發生改變,則不可避免地影響全部子類(裝飾者和被裝飾者),也就是說,經過繼承創建的關係老是脆弱地,若是基類改變,勢必影響對象的內部,而經過組合(Decoator HAS A Component)創建的關係只會影響被裝飾對象的外部特徵。

三、只在必要的時候使用裝飾者模式,不然會提升程序的複雜性,增長系統維護難度。

5、源碼地址

本系列文章源碼地址,https://github.com/amosli/dp  歡迎Fork  & Star !!

相關文章
相關標籤/搜索