**英文名稱:(Decorator Pattern)**
**定義**:動態的給一個對象添加一些額外的職責。就增加功能來說,裝飾模式相比生成子類更加靈活。
## 裝飾模式的一般模式

Component抽象構件
---|Component是一個接口或者是抽象類,就是定義我們最核心的對象,也就是最原始的對象。
ConcreteComponent具體構件
---|ConcreteComponent是最核心、最原始、最基本的接口或抽象類的實現,要裝飾的就是它。
Decorator裝飾角色
---|一般是一個抽象類,實現接口或者抽象方法,它的屬性里必然有一個private變量指向Component抽象構件
具體裝飾角色
---|要把最原始的、最基本的、最核心的東西裝飾成其他東西。
~~~
public class DecoratorPattern {
public static void main(String[] args) {
//拿到原始構件
Component origin = new ConcreteComponent();
origin = new ConcreteDecorator1(origin);
origin = new ConcreteDecorator2(origin);
origin.doSomething();
}
}
abstract class Component{
//抽象的方法,定義一些核心的方法。讓子類去實現
public abstract void doSomething();
}
class ConcreteComponent extends Component{
@Override
public void doSomething() {
System.out.println("我是抽象構件的具體實現....");
}
}
abstract class Decorator extends Component{
//有一個私有方法,指向Component類
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void doSomething() {
//讓Component的實現類去執行方法。
this.component.doSomething();
}
}
/**
* 1號修飾類
* @author admin
*
*/
class ConcreteDecorator1 extends Decorator{
//指向父類的方法
public ConcreteDecorator1(Component component) {
super(component);
}
private void decorator1(){
System.out.println("-----開始之前先修飾-----------");
}
@Override
public void doSomething() {
System.out.println("-111111111111111111111-");
//修飾方法
this.decorator1();
//執行原始方法
super.doSomething();
}
}
/**
* 2號修飾類
* @author admin
*
*/
class ConcreteDecorator2 extends Decorator{
//指向父類的方法
public ConcreteDecorator2(Component component) {
super(component);
}
private void decorator2(){
System.out.println("-----結束之后再修飾-----------");
}
@Override
public void doSomething() {
System.out.println("-2222222222222222222222-");
//執行原始方法
super.doSomething();
//修飾方法
this.decorator2();
}
}
~~~
## 一個例子:
老師把我的成績單發下來,讓家長簽字。因為成績考的不好,所以不能直接把成績單拿給爸爸看,
因此我得在拿出成績單前加一些修飾語。例如:告訴爸爸班里同學的最高分,我的分數是多少。
之后再說我在班里的名次。這樣就能避免一場海罵了。

~~~
public class DecoratorTest {
public static void main(String[] args) {
//拿著自己的原始成績單。
SchoolScore mScore = new ConcreteStudent();
//加上一層修飾,最高分的修飾。
mScore = new HighScoreDecorator(mScore);
//再加上第二次修飾,我的排名的修飾。
mScore = new SortDecorator(mScore);
//做出報告說明
mScore.report();
//可以讓家長簽字了
mScore.sign("lzl");
}
}
abstract class SchoolScore{
//定義一個成績單的接口,共每個學生去實現
//每個學生報告給家長,自己的成績。
public abstract void report();
//要求家長簽字。
public abstract void sign(String name);
}
class ConcreteStudent extends SchoolScore{
@Override
public void report() {
System.out.println("我的語文成績是 89,數學成績是 78,英語成績是 77.");
}
@Override
public void sign(String name) {
System.out.println("家長簽字:"+name);
}
}
/**
* 因為怕父親看到成績被他罵,所以我要來個裝飾類。
* @author admin
*/
abstract class MyDecorator extends SchoolScore{
//定義學生的成績
private SchoolScore score;
//用構造函數,實例化學生成績類。
public MyDecorator(SchoolScore score) {
this.score = score;
}
//抽象方法,為學生提交成績單時,添加一些修飾方法。
public void report(){
this.score.report();
}
//重寫父類的方法。讓家長簽字
@Override
public void sign(String name) {
this.score.sign(name);
}
}
/**
* 首先添加一個全班最高成績的說明,
* 讓父親知道我這個成績還算可以。
* @author admin
*/
class HighScoreDecorator extends MyDecorator{
public HighScoreDecorator(SchoolScore score) {
super(score);
}
private void highScoreSchool() {
System.out.println("語文最高分:99,數學最高分:88,英語最高分:77");
}
@Override
public void report() {
//先說明最高成績
this.highScoreSchool();
//再報自己的成績
super.report();
}
}
class SortDecorator extends MyDecorator{
public SortDecorator(SchoolScore score) {
super(score);
}
private void getSort() {
System.out.println("我在班里的排名是:第十...");
}
@Override
public void report() {
//先報完成績
super.report();
//再說明名次。
this.getSort();
}
}
~~~
**裝飾模式的優點**:
---|裝飾類和被裝飾類可以獨立的發展,不會相互耦合。
---|裝飾模式是繼承關系的一種替代方案。Decorator不管修飾多少層,返回的對象還是Component,實現的還是is-a的關系。
---|裝飾模式可以動態的擴展一個實現類的功能。
**裝飾模式的缺點**:
---|多層的裝飾模式是比較復雜的。
**裝飾模式的使用場景**:
---|擴展一個類的功能,或給一個類增加附加的功能
---|動態的給一個對象增加功能,這些功能可以動態的撤銷
---|為一批的兄弟類進行改裝或者加裝功能,首選裝飾模式。
- 前言
- 6大設計原則(一)---單一職責原則
- 6大設計原則(二)---里氏替換原則
- 6大設計原則(三)---依賴倒置原則
- 6大設計模式(四)----接口隔離原則
- 6大設計原則(五)---迪米特法則
- 6大設計原則(六)---開閉原則。
- 設計模式(一)---單例模式
- 設計模式(二)---工廠方法模式
- 設計模式(三)---抽象工廠模式
- 設計模式(四)---模板方法模式
- 設計模式(五)---建造者模式
- 設計模式(六)---代理模式
- 設計模式(七)---原型模式
- 設計模式(八)---中介者模式
- 設計模式(九)---命令模式
- 設計模式(十)---責任鏈模式
- 設計模式(十一)---裝飾模式
- 設計模式(十二)---策略模式
- 設計模式(十三)---適配器模式
- 設計模式(十四)---迭代器模式
- 設計模式(十五)---組合模式
- 設計模式(十六)---觀察者模式
- 設計模式(十七)---門面模式
- 設計模式(十八)---備忘錄模式
- 設計模式(十八)---訪問者模式
- 設計模式(二十)---狀態模式
- 設計模式(二十二)---享元模式
- 設計模式(二十三)---橋梁模式