裝飾器模式
裝飾器模式中主要有兩個角色:
- 裝飾器;
- 被裝飾的對象。
用老王買裝備的例子來說,老王就是被裝飾的對象,而衣服、褲子、帽子等就是裝飾器。
裝飾器和被裝飾的對象有兩個特點,也是裝飾器模式的關(guān)鍵:
- 他們實現(xiàn)同一個接口;
- 裝飾器中使用了被裝飾的對象。
使用裝飾器模式的幾個關(guān)鍵點:
- 裝飾器和被裝飾類要實現(xiàn)同一個接口( 實際開發(fā)中也可能用繼承 )。
- 裝飾器中的方法可以調(diào)用被裝飾對象提供的方法,以此實現(xiàn)功能累加的效果,例如,夾克裝飾器和帽子裝飾器中調(diào)用了
person.cost() + xx實現(xiàn)累計消費金額的累加。
實例
public interface Person {
/**
* 計算累計消費
* @return
*/
public Double cost();
public void show();
}
/**
* 抽象的服飾裝飾器
*/
public abstract class ClothesDecorator implements Person {
//裝飾器中要使用被裝飾器的對象,構(gòu)造方法中傳入
protected Person person;
public ClothesDecorator(Person person) {
this.person = person;
}
}
/**
* 被裝飾的對象
*/
public class LaoWang implements Person{
@Override
public Double cost() {
return 0.0; //赤果果的時候累計消費為0
}
@Override
public void show() {
System.out.println("我是赤果果的老王");
}
}
public class Jacket extends ClothesDecorator {
public Jacket(Person person) {
super(person);
}
@Override
public void show() {
person.show();
System.out.println("穿上夾克,累計消費" + this.cost());
}
@Override
public Double cost() {
return person.cost() + 100; //夾克100元
}
}
public class Hat extends ClothesDecorator {
public Hat(Person person) {
super(person);
}
@Override
public void show() {
//執(zhí)行已有功能
person.show();
//此處是附加的功能
System.out.println("戴上帽子,累計消費" + this.cost());
}
@Override
public Double cost() {
return person.cost() + 50; //帽子50元
}
}
單元測試:
import com.netease.learn.designPattern.decorator.Hat;
import com.netease.learn.designPattern.decorator.Jacket;
import com.netease.learn.designPattern.decorator.LaoWang;
import com.netease.learn.designPattern.decorator.Person;
import org.junit.Test;
public class DecoratorTest {
@Test
public void test1() {
Person laowang = new LaoWang();
//穿上夾克
laowang = new Jacket(laowang);
//戴上帽子
laowang = new Hat(laowang);
laowang.show();
System.out.println("買單,老王總共消費:" + laowang.cost());
}
}