天天看點

設計模式學習筆記——裝飾模式裝飾模式

裝飾模式

裝飾模式定義:動态地給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。

結構圖:

設計模式學習筆記——裝飾模式裝飾模式

Component:定義對象接口,可以給對象動态地添加職責。 ConcreteComponent:定義具體的對象,即裝飾的對象,也可以給該對象添加職責。 Decorator:裝飾抽象類,繼承了Component,從外類來擴充Component類的功能。(Component不知道Decorator的存在)

代碼實作

Component類:

/**
 * Component
 * @author xukai
 * 2016年3月8日 上午10:09:38
 */
public abstract class Component {

	public abstract void operation();
	
}
           

ConcreteComponent類:

/**
 * ConcreteComponent
 * @author xukai
 * 2016年3月8日 上午10:10:57
 */
public class ConcreteComponent extends Component {

	@Override
	public void operation() {
		System.out.println("裝飾對象的操作");
	}

}
           

Decorator類:

/**
 * 裝飾父類
 * 
 * @author xukai 2016年3月8日 上午10:11:32
 */
public abstract class Decorator extends Component {

	protected Component component;

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

	@Override
	public void operation() {
		if (component != null) {
			component.operation();
		}
	}

}
           

ConcreteDecoratorA類:

/**
 * 具體服裝類
 * @author xukai
 * 2016年3月8日 上午10:13:55
 */
public class ConcreteDecoratorA extends Decorator {

	/**
	 * 本類獨有功能,差別其他具體服飾類
	 */
	@SuppressWarnings("unused")
	private String addedState;
	
	/**
	 * 1.運作原Component的operation方法
	 * 2.執行本類方法,addedState,對其進行裝飾
	 */
	@Override
	public void operation() {
		super.operation();
		addedState = "New State";
		System.out.println("裝飾A");
	}
	
}
           

ConcreteDecoratorB類:

/**
 * 具體服飾類
 * 
 * @author xukai 2016年3月8日 上午10:15:57
 */
public class ConcreteDecoratorB extends Decorator {

	/**
	 * 本類特有方法,差別其他具體服飾類
	 */
	private void addedBehavior(){
		System.out.println("裝飾B");
	}
	
	/**
	 * 1.運作原Component的operation方法
	 * 2.執行本類方法,addedBehavior,對其進行裝飾
	 */
	@Override
	public void operation() {
		super.operation();
		addedBehavior();
	}

}
           

用戶端:

/**
 * 用戶端測試
 * @author xukai
 * 2016年3月8日 上午10:20:56
 */
public class DecoreteClient {
	
	public static void main(String[] args) {
		ConcreteComponent concrete = new ConcreteComponent();		//1
		ConcreteDecoratorA concrete_A = new ConcreteDecoratorA();	//2
		ConcreteDecoratorB concrete_B = new ConcreteDecoratorB();	//3
		
		concrete_A.setComponent(concrete);				//4
		concrete_B.setComponent(concrete_A);				//5
		concrete_B.operation();						//6
	}
}
           
設計模式學習筆記——裝飾模式裝飾模式

流程分析: 1.建立ConcreteComponent對象——concrete 2.建立ConcreteDecoratorA對象——concrete_A

3.建立ConcreteDecoratorB對象——concrete_B 4.将concrete_A中的protected的Component設定為concrete(ConcreteComponent對象) 5.将concrete_B中的protected的Component設定為concrete_A(ConcreteDecoratorA對象)

6.1執行ConcreteDecoratorB中的operation()方法 6.2執行super.operation(),實際為其父類Decorator的operation方法 6.3Decorator的operation方法内容為,執行Component的operation方法,此時Component實際為ConcreteDecoratorA對象 6.4執行ConcreteDecoratorA的operation方法:super.operation,繼續執行Decorator的operation方法,此時Component實際為ConcreteComponent對象 6.5執行ConcreteComponent中的operation方法 6.6執行ConcreteDecoratorA特有的裝飾 6.7執行ConcreteDecoratorB特有的裝飾

下面是一個demo 問題:要求寫一個可以給人搭配不同的服飾的系統。

*注: 如果隻有一個ConcreteComponent類而沒有抽象的Component類,那麼Decorator類可以是ConcreteComponent的一個子類。 如果隻有一個ConcreteDecorator類,那麼就沒有必要建立一個單獨的Decorator類,而可以把Decorator和ConcreteDecorator的責任合并成一個類。     

設計模式學習筆記——裝飾模式裝飾模式

Person類:

public class Person {

	public Person() {
	}
	
	public Person(String name) {
		this.name = name;
	}

	private String name;
	
	public void show(){
		System.out.println(name + "穿衣順序:");
	}
}
           

服飾類(Decorator)

/**
 * 服飾類
 * @author hcc
 *
 */
public class Finery extends Person{
	
	protected Person component;
	
	public void decorate(Person component){
		this.component = component;
	}
	
	@Override
	public void show() {
		if(component != null){
			component.show();
		}
	}
}
           

具體服飾類(ConcreteDecorator)

/**
 * 具體服飾類:T恤
 * @author hcc
 *
 */
public class TShirts extends Finery {

	@Override
	public void show() {
		super.show();
		System.out.println("T恤");
	}
}
           

具體服飾類(ConcreteDecorator)

/**
 * 具體服飾類:垮褲
 * @author hcc
 *
 */
public class BigTrouser extends Finery {

	@Override
	public void show() {
		super.show();
		System.out.println("垮褲");
	}
}
           

測試類:

public class DecorateDemoTest {
	
	public static void main(String[] args) {
		Person person = new Person("徐凱");
		
		TShirts tShrits = new TShirts();
		BigTrouser bigTrouser = new BigTrouser();
		
		tShrits.decorate(person);
		bigTrouser.decorate(tShrits);
		
		bigTrouser.show();
	}

}
           
設計模式學習筆記——裝飾模式裝飾模式

總結

使用原因: 當系統需要新功能的時候,是向舊的類中添加新的代碼。這些新加的代碼通常裝飾了原有類的核心職責或主要行為,在主類中加入了新的字段,新的方法,新的邏輯,進而增加了主類的複雜度。

裝飾模式提供了一個非常好的解決方案,它把每個要裝飾的功能放在單獨的類中,并讓這個類包裝它所要裝飾的對象,是以,當需要執行特殊行為時,客戶代碼就可以運作時根據需要有選擇的、按順序的使用裝飾功能包裝對象

優點:

把類中的裝飾功能從類中搬移去除,簡化原有類。把類的核心職責和裝飾功能區分開。

繼續閱讀