一:责任链模式
- 责任链模式解决什么样的问题?
核心思想就是分而治之。当调用者面临的被调者太多时,为了降低逻辑复杂度,把相关的被调用者组织起来,形成一个链式的结构,被调用者之间进行调用传递(责任传递)。
- 责任链的实现原理
每个 被调用者 都持有下一个 被调用者 的引用,客户端只需要发起一次调用即可。
- 应用场景
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. 分析
一个包装类可以对同一接口的多种实现类进行包装,这样的实现方式就是可插拔式的,包装类甚至就像是一个工具类一样。
如果使用继承,那么包装类的定位就是被包装类的子类,且若要对多个对象都增强同一种功能,就必须创建多个类,显而易见,装饰者模式胜出!