裝飾器模式

裝飾器模式

被這個模式困惑了一段時間,實際上是被一些術語嚇到了,其實並無那麼難。java

通俗來講,就是一個對象原來有一些功能,而後發現功能不夠用,想讓這個對象更增強大,就使用一個裝飾器對這個對象裝飾一下,給其在原有的基礎上裝飾功能。

實現裝飾的核心就是這個對象的裝飾先後類型不變,因此被裝飾的就應該是一個接口或抽象類類型,被裝飾器裝飾以後仍是能夠指向接口或抽象類。angularjs

以接口爲例

總接口Peopleide

/**
 * 一我的的接口
 */
public interface People {

    // 這我的有描述本身的方法
    void show();
}

基礎的實現,普通人:ui

/**
 * People的基礎實現,一無全部的普通人
 */
public class CommonPeople implements People {

    @Override
    public void show() {
        System.out.println("普通人,一無全部");
    }
}

三個裝飾器,分別爲人裝飾車、房、對象。this

每一個裝飾器都是調用原People的方法,而後爲其添加本類應該裝飾的功能。全部的裝飾器都須要實現People接口(若是採用抽象類實現須要繼承抽象類),保證這個對象被裝飾以後仍然是People類型。阿里雲

/**
 * 車裝飾器
 */
public class CarDecorator implements People {

    private People people;

    public CarDecorator(People people) {
        this.people = people;
    }

    @Override
    public void show() {
        this.people.show();
        System.out.println("許多年後,終於有車了");
    }
}
/**
 * 房裝飾器
 */
public class HouseDecorator implements People {

    private People people;

    public HouseDecorator(People people) {
        this.people = people;
    }

    @Override
    public void show() {
        this.people.show();
        System.out.println("許多年後,終於有房了");
    }
}
/**
 * 對象裝飾器
 */
public class ObjectDecorator implements People {

    private People people;

    public ObjectDecorator(People people) {
        this.people = people;
    }

    @Override
    public void show() {
        this.people.show();
        System.out.println("許多年後,終於有對象了");
    }
}

裝飾

public class Main {

    public static void main(String[] args) {
        // 一無全部的普通人
        People people = new CommonPeople();
        people.show();

        System.out.println("-------------------");

        // 這我的有車了
        people = new CarDecorator(people);
        people.show();

        System.out.println("-------------------");

        // 這我的有房了
        people = new HouseDecorator(people);
        people.show();

        System.out.println("-------------------");

        // 這我的有對象了
        people = new ObjectDecorator(people);
        people.show();
    }
}

運行結果:spa

clipboard.png

若是不使用裝飾器,咱們沒法這麼隨意地去拓展對象的功能。code

若是不使用裝飾器,類有什麼功能, new出來的對象就有什麼功能。三個裝飾器,能夠排列組合,有房有車的人,有房有對象的人,隨意地爲這個對象添加功能,想要什麼就加什麼。而不是像以前生硬地繼承, new什麼就有什麼功能。

裝飾器使用

提及裝飾器,AngularJS中但是提供了很是詳盡的支持,Decorators in AngularJS視頻

clipboard.png

就好比AngularJS中的裝飾器,若是是咱們本身寫的一個Service,有一天發現功能不夠用了,隨便改,反正是我本身寫的代碼。對象

可是若是你發現第三方庫給你提供的Service方法不夠用呢?去改它的代碼嗎?這是不現實的。

這個慕課網的課程描述了當開發阿里雲時,發現UI-Bootstrap中的一個popover組件不能自定義模板(如今的UI-Bootstrap已解決此問題),基於公共組件的開發心得 - 阿里懶懶交流會AngularJS專場

解決方案:

1、改掉它的源代碼,本身發佈一個庫,而後項目中使用這個修改完的庫。(沒錯,阿里的大大們就是這麼幹的。)

2、設置裝飾器,用裝飾器爲原組件添加新功能。(這個在視頻中也提到了,不過是在他們用方案一解決完這個問題時才發現的新方案。偷偷地去看過阿里雲中關於popover彈窗的代碼,仍是用的方案一,可能時間久了,很差改動。)

相關文章
相關標籤/搜索