一:責任鏈模式
- 責任鏈模式解決什麼樣的問題?
核心思想就是分而治之。當調用者面臨的被調者太多時,爲了降低邏輯複雜度,把相關的被調用者組織起來,形成一個鏈式的結構,被調用者之間進行調用傳遞(責任傳遞)。
- 責任鏈的實現原理
每個 被調用者 都持有下一個 被調用者 的引用,客戶端只需要發起一次調用即可。
- 應用場景
tomcat的過濾器鏈/struts2的21種攔截器等等,在第三方成熟的框架大多都有涉及
- 具體演示
- 對被調用者抽象出來一個接口,方便調用時隱藏具體實現,利於解耦
public interface ProducerHandler { void handleRequest(); void setNext(ProducerHandler next); }創建幾個被調用者的實現
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; }}
組裝鏈式關係並調用
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. 分析
一個包裝類可以對同一接口的多種實現類進行包裝,這樣的實現方式就是可插拔式的,包裝類甚至就像是一個工具類一樣。
如果使用繼承,那麼包裝類的定位就是被包裝類的子類,且若要對多個對象都增強同一種功能,就必須創建多個類,顯而易見,裝飾者模式勝出!