設計模式之責任鏈模式和裝飾者模式

一:責任鏈模式

  • 責任鏈模式解決什麼樣的問題?

核心思想就是分而治之。當調用者面臨的被調者太多時,爲了降低邏輯複雜度,把相關的被調用者組織起來,形成一個鏈式的結構,被調用者之間進行調用傳遞(責任傳遞)。

  • 責任鏈的實現原理

每個 被調用者 都持有下一個 被調用者 的引用,客戶端只需要發起一次調用即可。

  • 應用場景

tomcat的過濾器鏈/struts2的21種攔截器等等,在第三方成熟的框架大多都有涉及

  • 具體演示
  1. 對被調用者抽象出來一個接口,方便調用時隱藏具體實現,利於解耦
    public interface ProducerHandler {
    void handleRequest();
     void setNext(ProducerHandler next);
    }
  2. 創建幾個被調用者的實現

    CarTyreProducerHandler,CarWindowProducerHandler

    其中一個是這樣的:
    public class CarTyreProducerHandler implements ProducerHandler{
     private ProducerHandler nextProducer;
     @Override
     public void handleRequest(){
     doHandler();
     if(nextProducer != null){
    nextProducer.handleRequest();
     }else{
            System.out.println("所有的生產者都已完成生產");
     }
      }
     @Override
     public void setNext(ProducerHandler next){
    this.nextProducer = next;
       }

    }

  3. 組裝鏈式關係並調用

CarTyreProducerHandler tyreProducerHandler = new CarTyreProducerHandler();
CarWindowProducerHandler carWindowProducerHandler = new CarWindowProducerHandler();
tyreProducerHandler.setNext(carWindowProducerHandler);
tyreProducerHandler.handleRequest();


二:裝飾者模式

  • 裝飾者模式解決的問題是什麼?

裝飾者模式是爲了增強對象的行爲,跟繼承的區別在於,繼承的侷限在於子類只能增強一個父類,而裝飾者它可以對某一類的對象進行增強,這樣就避免了冗餘的繼承體系,

使得擴展性很強。

  • 裝飾的實現原理

持有被裝飾的對象,並具備  被裝飾者  的行爲,對其行爲進行補充增強

  • 具體演示

1.抽象出一個接口,使裝飾者和被裝飾者具備同一種的行爲

public interface Robot {
//講話
 void speak();
 //移動
 void move();
}

2.創建兩個具體的類用來 被裝飾

AIRobot(ai機器人),OrdinaryRobot(普通機器人)
其中一個是這樣的
public class AIRobot implements Robot{
@Override
 public void speak() {
        System.out.println("ai robot speak");
 }
@Override
 public void move() {
        System.out.println("ai robot move");
 }
}

3.主角上場,創建裝飾類,用來裝飾如上兩個對象,在這裏命名爲(機器的音量調節包裝類)

public class VolumeControlRobotWraper implements Robot {
private Robot robot;

 public VolumeControlRobotWraper(Robot robot) {
this.robot = robot;
 }
@Override
 public void speak() {
        System.out.println("Turn up the volume");
 robot.speak();
 }
@Override
 public void move() {
robot.move();
 }
}

4.開始裝飾,查看效果如何

@Test
public void test(){
//創建兩個不同的機器
 AIRobot aiRobot = new AIRobot();
 OrdinaryRobot ordinaryRobot = new OrdinaryRobot();
 //給所有的機器包裝一個調節音量的功能
 VolumeControlRobotWraper wraper = new VolumeControlRobotWraper(aiRobot);
 VolumeControlRobotWraper wraper1 = new VolumeControlRobotWraper(ordinaryRobot);
 wraper.speak();
 wraper1.speak();
}

執行結果:

Turn up the volume
ai機器人講話
Turn up the volume
普通機器人講話

 

5. 分析

一個包裝類可以對同一接口的多種實現類進行包裝,這樣的實現方式就是可插拔式的,包裝類甚至就像是一個工具類一樣。

如果使用繼承,那麼包裝類的定位就是被包裝類的子類,且若要對多個對象都增強同一種功能,就必須創建多個類,顯而易見,裝飾者模式勝出!

 

相關示例代碼請移步 https://gitee.com/HeadingAlong/springfeature.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章