设计模式之责任链模式和装饰者模式

一:责任链模式

  • 责任链模式解决什么样的问题?

核心思想就是分而治之。当调用者面临的被调者太多时,为了降低逻辑复杂度,把相关的被调用者组织起来,形成一个链式的结构,被调用者之间进行调用传递(责任传递)。

  • 责任链的实现原理

每个 被调用者 都持有下一个 被调用者 的引用,客户端只需要发起一次调用即可。

  • 应用场景

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

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