Java设计模式(一):责任链模式

简介: 将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。实际上,责任链模式还有一种变体,那就是请求会被所有接收对象都能处理一遍,直到某个接收对象不能正常处理再退出,或者全部执行一遍,不存在中途终止的情况

研究sentinel源码时候说到了责任链这种设计模式,所以近期打算开启java设计模式分析。

1.设计模式概念

概念

Java包含23种设计模式,是一套对代码设计经验的总结,被人们反复利用,多人熟知的代码设计方式。在众多热门框架源码中用到许多种设计模式,这也是为什么框架可适配、可扩展,经典源码被大家反复阅读学习的原因吧。

设计模式的好处

设计模式作为一个程序员进阶的必修之路,合理运用设计模式能写出可扩展、可读、可维护的高质量代码。个人总结了一下几个学设计模式带来的直观好处:

1)应对面试中的设计模式相关问题;

2)告别写被人吐槽的烂代码;

3)提高复杂代码的设计和开发能力;

4)让读源码、学框架事半功倍;

5)为你的职场发展做铺垫,将来也写一个大家追捧的框架。

项目推荐:基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba企业级系统架构底层框架封装,解决业务开发时常见的非功能性需求,防止重复造轮子,方便业务快速开发和企业技术栈框架统一管理。引入组件化的思想实现高内聚低耦合并且高度可配置化,做到可插拔。严格控制包依赖和统一版本管理,做到最少化依赖。注重代码规范和注释,非常适合个人学习和企业使用

Github地址https://github.com/plasticene/plasticene-boot-starter-parent

Gitee地址https://gitee.com/plasticene3/plasticene-boot-starter-parent

微信公众号Shepherd进阶笔记

交流探讨群:Shepherd_126

2.设计模式六大原则(面试高频考点)

开闭原则

对扩展开放,对修改关闭(尽可能对代码少修改)

里氏替换原则

它是面向对象基本原则之一,任何父类(基类)出现的地方,子类都可以出现,也就是子类可以替换父类的任何功能(体现了父类的可扩展性)

依赖倒转原则

尽可能面向接口编程,依赖接口而不依赖类

接口隔离原则

一个类如果能实现多个接口,尽可能实现多个,为了降低依赖,降低耦合

最少知道原则

一个实体尽可能少的与其他实体产生相互关联关系,将实体的功能独立

合成复用原则

尽量使用合成,聚合的方式,而不使用继承

3.设计模式分类

Java设计模式分为三大类

创建型模式:对象实例化的模式,创建型模式用于解耦对象的实例化过程。

结构型模式:把类或对象结合在一起形成一个更大的结构。

行为型模式:类和对象如何交互,及划分责任和算法

接下来步入今天的主角:责任链模式

4.责任链模式定义

将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。实际上,责任链模式还有一种变体,那就是请求会被所有接收对象都能处理一遍,直到某个接收对象不能正常处理再退出,或者全部执行一遍,不存在中途终止的情况。

在责任链模式中,一个产品在流水线经过多个员工(也就是刚刚定义中说的“接收对象”)依次处理加工。一个产品先经过 A 处理加工,然后再把请求传递给 B 处理加工,B 处理完后再传递给 C 处理加工,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫责任链模式。

示例代码

首先定义一个所有处理器类的抽象父类Handler ,doHandle() 是抽象方法,需要具体处理类来重写实现该方法

/**
 * @author fjzheng
 * @version 1.0
 * @date 2021/11/9 15:15
 */

public abstract class Handler {
   
   
    //successor代表责任链中下一环节,eg:这里代表流水线上下一加工人员
    protected Handler next = null;

    public void setNext(Handler next) {
   
   
        this.next = next;
    }

    //final修饰不能重写覆盖此方法
    public final void handle() {
   
   
        //执行责任链的具体处理类方法
        boolean handled = doHandle();
        //判断chain中当前环节是否执行成功和chain是有下一环节
        if (next != null && handled) {
   
   
            next.handle();
        }
    }

    protected abstract Boolean doHandle();
}

接下来是三个具体的处理加工类,这里即代表加工人员,通过实现抽象类handler的doHandle(),表明自己在加工责任链中任务,当然这里可以不只是三个,可以是n个,只要实现抽象类handler,然后再责任链中加入自己即可。

/**
 * @author fjzheng
 * @version 1.0
 * @date 2021/11/9 15:16
 */

/**
 * 这里可以写handlerA具体处理逻辑,最终返回处理是否成功
 */
public class HandlerA extends Handler {
   
   
    @Override
    public Boolean doHandle() {
   
   
        System.out.println("handlerA execute.....");
        return true;

    }
}

/**
 * 这里可以写handlerB具体处理逻辑,最终返回处理是否成功
 */
public class HandlerB extends Handler {
   
   
    @Override
    public Boolean doHandle() {
   
   
        System.out.println("handlerB execute.....");
        return true;
    }
}

/**
 * 这里可以写handlerC具体处理逻辑,最终返回处理是否成功
 */
public class HandlerC extends Handler{
   
   
    @Override
    protected Boolean doHandle() {
   
   
        System.out.println("handlerC execute.....");
        return true;
    }
}

构建加工处理责任链HandlerChain

/**
 * @author fjzheng
 * @version 1.0
 * @date 2021/11/9 15:17
 */

/**
 * HandlerChain 是加工人员处理链,从数据结构的角度来看,它就是一个记录了链头、链尾的链表。其中,记录链尾是为了方便添加加工人员
 */
public class HandlerChain {
   
   
    private Handler head = null;
    private Handler tail = null;

    public void addHandler(Handler handler) {
   
   
        handler.setNext(null);
        //第一次添加具体处理类时,头、尾都等于该类
        if (head == null) {
   
   
            head = handler;
            tail = handler;
            return;
        }
        //不是第一添加,该类设置tail的下一环节,将尾部设置该类,最终形成一个链表结构
        tail.setNext(handler);
        tail = handler;
    }

    public void handle() {
   
   
        //从第一个开始执行
        if (head != null) {
   
   
            head.handle();
        }
    }
}

测试用例

/**
 * @author fjzheng
 * @version 1.0
 * @date 2021/11/9 15:18
 */

/**
 * 这里模拟一个产品在流水线上加工流程,如果在某个加工人员出错,就不再流向下一个加工人员
 * 往责任链chain中添加加工人员handler
 */
public class TestDemo {
   
   
    public static void main(String[] args) {
   
   
        HandlerChain chain = new HandlerChain();
        chain.addHandler(new HandlerA());
        chain.addHandler(new HandlerB());
        chain.addHandler(new HandlerC());
        chain.handle();
    }
}

结果示例如下:

handlerA execute.....
handlerB execute.....
handlerC execute.....

上面是使用链表来构造责任链的,接下来我们通过数组实现,代码如下:

public interface IHandler {
   
   
  boolean handle();
}

public class HandlerA implements IHandler {
   
   
  @Override
  public boolean handle() {
   
   
    boolean handled = false;
    //...
    return handled;
  }
}

public class HandlerB implements IHandler {
   
   
  @Override
  public boolean handle() {
   
   
    boolean handled = false;
    //...
    return handled;
  }
}

public class HandlerChain {
   
   
  private List<IHandler> handlers = new ArrayList<>();

  public void addHandler(IHandler handler) {
   
   
    this.handlers.add(handler);
  }

  public void handle() {
   
   
    for (IHandler handler : handlers) {
   
   
      boolean handled = handler.handle();
      if (handled) {
   
   
        break;
      }
    }
  }
}

// 使用举例
public class Application {
   
   
  public static void main(String[] args) {
   
   
    HandlerChain chain = new HandlerChain();
    chain.addHandler(new HandlerA());
    chain.addHandler(new HandlerB());
    chain.handle();
  }
}

5.责任链模式的应用场景

敏感词检测在当今互联网是一个必不可少的功能要求,防止发布一些包含敏感词(比如涉黄、广告、反动等词汇)不良信息。针对这个应用场景,我们就可以利用职责链模式来过滤这些敏感词

public interface SensitiveWordFilter {
   
   
  boolean doFilter(Content content);
}

public class SexyWordFilter implements SensitiveWordFilter {
   
   
  @Override
  public boolean doFilter(Content content) {
   
   
    boolean legal = true;
    //...
    return legal;
  }
}

// PoliticalWordFilter、AdsWordFilter类代码结构与SexyWordFilter类似

public class SensitiveWordFilterChain {
   
   
  private List<SensitiveWordFilter> filters = new ArrayList<>();

  public void addFilter(SensitiveWordFilter filter) {
   
   
    this.filters.add(filter);
  }

  // return true if content doesn't contain sensitive words.
  public boolean filter(Content content) {
   
   
    for (SensitiveWordFilter filter : filters) {
   
   
      if (!filter.doFilter(content)) {
   
   
        return false;
      }
    }
    return true;
  }
}

public class ApplicationDemo {
   
   
  public static void main(String[] args) {
   
   
    SensitiveWordFilterChain filterChain = new SensitiveWordFilterChain();
    filterChain.addFilter(new AdsWordFilter());
    filterChain.addFilter(new SexyWordFilter());
    filterChain.addFilter(new PoliticalWordFilter());

    boolean legal = filterChain.filter(new Content());
    if (!legal) {
   
   
      // 不发表
    } else {
   
   
      // 发表
    }
  }
}

具体过滤算法这里不做阐述,毕竟不是本文的主要内容。

接下来展示一下不用责任链设计模式实现敏感词检测功能:

public class SensitiveWordFilter {
   
   
  // return true if content doesn't contain sensitive words.
  public boolean filter(Content content) {
   
   
    if (!filterSexyWord(content)) {
   
   
      return false;
    }

    if (!filterAdsWord(content)) {
   
   
      return false;
    }

    if (!filterPoliticalWord(content)) {
   
   
      return false;
    }

    return true;
  }

  private boolean filterSexyWord(Content content) {
   
   
    //....
  }

  private boolean filterAdsWord(Content content) {
   
   
    //...
  }

  private boolean filterPoliticalWord(Content content) {
   
   
    //...
  }
}

你可能会说,我像上面这样也可以实现敏感词过滤功能,而且代码更加简单,为什么非要使用职责链模式呢?这是不是过度设计呢?

首先,我们来看,职责链模式如何应对代码的复杂性

将大块代码逻辑拆分成函数,将大类拆分成小类,是应对代码复杂性的常用方法。应用职责链模式,我们把各个敏感词过滤函数继续拆分出来,设计成独立的类,进一步简化了 SensitiveWordFilter 类,让 SensitiveWordFilter 类的代码不会过多,过复杂。

其次,我们再来看,职责链模式如何让代码满足开闭原则,提高代码的扩展性。

当我们要扩展新的过滤算法的时候,比如,我们还需要过滤特殊符号,按照非职责链模式的代码实现方式,我们需要修改 SensitiveWordFilter 的代码,违反开闭原则。不过,这样的修改还算比较集中,也是可以接受的。而职责链模式的实现方式更加优雅,只需要新添加一个 Filter 类,并且通过 addFilter() 函数将它添加到 FilterChain 中即可,其他代码完全不需要修改

假设敏感词过滤框架并不是我们开发维护的,而是我们引入的一个第三方框架,我们要扩展一个新的过滤算法,不可能直接去修改框架的源码。这个时候,利用职责链模式就能达到开篇所说的,在不修改框架源码的情况下,基于职责链模式提供的扩展点,来扩展新的功能。换句话说,我们在框架这个代码范围内实现了开闭原则。

除此之外,利用职责链模式相对于不用职责链的实现方式,还有一个好处,那就是配置过滤算法更加灵活,可以只选择使用某几个过滤算法。

6.框架中的常用过滤器、拦截器中责任链模式的应用

过滤器Filter

Servlet Filter 是 Java Servlet 规范中定义的组件,翻译成中文就是过滤器,它可以实现对 HTTP 请求的过滤功能,比如鉴权、限流、记录日志、验证参数等等。因为它是 Servlet 规范的一部分,所以,只要是支持 Servlet 的 Web 容器(比如,Tomcat、Jetty 等),都支持过滤器功能。为了帮助你理解,我画了一张示意图阐述它的工作原理,如下所示。

使用示例代码:

@WebFilter
public class LogFilter implements Filter {
   
   
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
   
   
    // 在创建Filter时自动调用,
    // 其中filterConfig包含这个Filter的配置参数,比如name之类的(从配置文件中读取的)
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
   
   
    System.out.println("拦截客户端发送来的请求.");
    chain.doFilter(request, response);
    System.out.println("拦截发送给客户端的响应.");
  }

  @Override
  public void destroy() {
   
   
    // 在销毁Filter时自动调用
  }
}

我们可以看到doFilter()方法中的FilterChain参数,这就是责任链模式的身影,接下来解析一下FilterChain。

不过,我们前面也讲过,Servlet 只是一个规范,并不包含具体的实现,所以,Servlet 中的 FilterChain 只是一个接口定义。具体的实现类由遵从 Servlet 规范的 Web 容器来提供,比如,ApplicationFilterChain 类就是 Tomcat 提供的 FilterChain 的实现类,源码如下所示

public final class ApplicationFilterChain implements FilterChain {
   
   
  private int pos = 0; //当前执行到了哪个filter
  private int n; //filter的个数
  private ApplicationFilterConfig[] filters;
  private Servlet servlet;

  @Override
  public void doFilter(ServletRequest request, ServletResponse response) {
   
   
    if (pos < n) {
   
   
      ApplicationFilterConfig filterConfig = filters[pos++];
      Filter filter = filterConfig.getFilter();
      filter.doFilter(request, response, this);
    } else {
   
   
      // filter都处理完毕后,执行servlet
      servlet.service(request, response);
    }
  }

  public void addFilter(ApplicationFilterConfig filterConfig) {
   
   
    for (ApplicationFilterConfig filter:filters)
      if (filter==filterConfig)
         return;

    if (n == filters.length) {
   
   //扩容
      ApplicationFilterConfig[] newFilters = new ApplicationFilterConfig[n + INCREMENT];
      System.arraycopy(filters, 0, newFilters, 0, n);
      filters = newFilters;
    }
    filters[n++] = filterConfig;
  }
}

ApplicationFilterChain 中的 doFilter() 函数的代码实现比较有技巧,实际上是一个递归调用。你可以用每个 Filter(比如 LogFilter)的 doFilter() 的代码实现,直接替换 ApplicationFilterChain 的第 12 行代码,一眼就能看出是递归调用了。我替换了一下,如下所示:

  @Override
  public void doFilter(ServletRequest request, ServletResponse response) {
   
   
    if (pos < n) {
   
   
      ApplicationFilterConfig filterConfig = filters[pos++];
      Filter filter = filterConfig.getFilter();
      //filter.doFilter(request, response, this);
      //把filter.doFilter的代码实现展开替换到这里
      System.out.println("拦截客户端发送来的请求.");
      chain.doFilter(request, response); // chain就是this
      System.out.println("拦截发送给客户端的响应.")
    } else {
   
   
      // filter都处理完毕后,执行servlet
      servlet.service(request, response);
    }
  }

这样实现主要是为了在一个 doFilter() 方法中,支持双向拦截,既能拦截客户端发送来的请求,也能拦截发送给客户端的响应,你可以结合着 LogFilter 那个例子,以及对比待会要讲到的 Spring Interceptor,来自己理解一下。而我们上面给出的两种(基于链表、数组)实现方式,都没法做到在业务逻辑执行的前后,同时添加处理代码。

拦截器Interceptor

刚刚讲了 Servlet Filter,现在我们来讲一个功能上跟它非常类似的东西,Spring Interceptor,翻译成中文就是拦截器。尽管英文单词和中文翻译都不同,但这两者基本上可以看作一个概念,都用来实现对 HTTP 请求进行拦截处理。它们不同之处在于,Servlet Filter 是 Servlet 规范的一部分,实现依赖于 Web 容器。Spring Interceptor 是 Spring MVC 框架的一部分,由 Spring MVC 框架来提供实现。客户端发送的请求,会先经过 Servlet Filter,然后再经过 Spring Interceptor,最后到达具体的业务代码中。我画了一张图来阐述一个请求的处理流程,具体如下所示:

使用示例:

public class LogInterceptor implements HandlerInterceptor {
   
   

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
   
   
    System.out.println("拦截客户端发送来的请求.");
    return true; // 继续后续的处理
  }

  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
   
   
    System.out.println("拦截发送给客户端的响应.");
  }

  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
   
   
    System.out.println("这里总是被执行.");
  }
}


@Configuration
public class OrderWebConfig implements WebMvcConfigurer {
   
   
    @Resource
    private AuthInterceptor authInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
   
   
        registry.addInterceptor(LogInterceptor).excludePathPatterns("/api/mall/order/orderNo/**");
    }
}

拦截器也是基于职责链模式实现的。其中,HandlerExecutionChain 类是职责链模式中的处理器链。它的实现相较于 Tomcat 中的 ApplicationFilterChain 来说,逻辑更加清晰,不需要使用递归来实现,主要是因为它将请求和响应的拦截工作,拆分到了两个函数中实现。HandlerExecutionChain 的源码如下所示,同样,我对代码也进行了一些简化,只保留了关键代码

public class HandlerExecutionChain {
   
   
 private final Object handler;
 private HandlerInterceptor[] interceptors;

 public void addInterceptor(HandlerInterceptor interceptor) {
   
   
  initInterceptorList().add(interceptor);
 }

 boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
   
   
  HandlerInterceptor[] interceptors = getInterceptors();
  if (!ObjectUtils.isEmpty(interceptors)) {
   
   
   for (int i = 0; i < interceptors.length; i++) {
   
   
    HandlerInterceptor interceptor = interceptors[i];
    if (!interceptor.preHandle(request, response, this.handler)) {
   
   
     triggerAfterCompletion(request, response, null);
     return false;
    }
   }
  }
  return true;
 }

 void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
   
   
  HandlerInterceptor[] interceptors = getInterceptors();
  if (!ObjectUtils.isEmpty(interceptors)) {
   
   
   for (int i = interceptors.length - 1; i >= 0; i--) {
   
   
    HandlerInterceptor interceptor = interceptors[i];
    interceptor.postHandle(request, response, this.handler, mv);
   }
  }
 }

 void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex)
   throws Exception {
   
   
  HandlerInterceptor[] interceptors = getInterceptors();
  if (!ObjectUtils.isEmpty(interceptors)) {
   
   
   for (int i = this.interceptorIndex; i >= 0; i--) {
   
   
    HandlerInterceptor interceptor = interceptors[i];
    try {
   
   
     interceptor.afterCompletion(request, response, this.handler, ex);
    } catch (Throwable ex2) {
   
   
     logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
    }
   }
  }
 }
}

在 SpringMVC 框架中,DispatcherServlet 的 doDispatch() 方法来分发请求,它在真正的业务逻辑执行前后,执行 HandlerExecutionChain 中的 applyPreHandle() 和 applyPostHandle() 函数,用来实现拦截的功能。

目录
相关文章
|
2天前
|
设计模式 存储 Java
【十】设计模式~~~结构型模式~~~享元模式(Java)
文章详细介绍了享元模式(Flyweight Pattern),这是一种对象结构型模式,通过共享技术实现大量细粒度对象的重用,区分内部状态和外部状态来减少内存中对象的数量,提高系统性能。通过围棋棋子的设计案例,展示了享元模式的动机、定义、结构、优点、缺点以及适用场景,并探讨了单纯享元模式和复合享元模式以及与其他模式的联用。
【十】设计模式~~~结构型模式~~~享元模式(Java)
|
2天前
|
设计模式 存储 Java
【九】设计模式~~~结构型模式~~~外观模式(Java)
文章详细介绍了外观模式(Facade Pattern),这是一种对象结构型模式,通过引入一个外观类来简化客户端与多个子系统之间的交互,降低系统的耦合度,并提供一个统一的高层接口来使用子系统。通过文件加密模块的实例,展示了外观模式的动机、定义、结构、优点、缺点以及适用场景,并讨论了如何通过引入抽象外观类来提高系统的可扩展性。
【九】设计模式~~~结构型模式~~~外观模式(Java)
|
2天前
|
设计模式 Java
【八】设计模式~~~结构型模式~~~装饰模式(Java)
文章详细介绍了装饰模式(Decorator Pattern),这是一种对象结构型模式,用于在不使用继承的情况下动态地给对象添加额外的职责。装饰模式通过关联机制,使用装饰器类来包装原有对象,并在运行时通过组合的方式扩展对象的行为。文章通过图形界面构件库的设计案例,展示了装饰模式的动机、定义、结构、优点、缺点以及适用场景,并提供了Java代码实现和应用示例。装饰模式提高了系统的灵活性和可扩展性,适用于需要动态、透明地扩展对象功能的情况。
【八】设计模式~~~结构型模式~~~装饰模式(Java)
|
2天前
|
设计模式 XML 存储
【七】设计模式~~~结构型模式~~~桥接模式(Java)
文章详细介绍了桥接模式(Bridge Pattern),这是一种对象结构型模式,用于将抽象部分与实现部分分离,使它们可以独立地变化。通过实际的软件开发案例,如跨平台视频播放器的设计,文章阐述了桥接模式的动机、定义、结构、优点、缺点以及适用场景,并提供了完整的代码实现和测试结果。桥接模式适用于存在两个独立变化维度的系统,可以提高系统的可扩展性和灵活性。
【七】设计模式~~~结构型模式~~~桥接模式(Java)
|
2天前
|
设计模式 存储 负载均衡
【五】设计模式~~~创建型模式~~~单例模式(Java)
文章详细介绍了单例模式(Singleton Pattern),这是一种确保一个类只有一个实例,并提供全局访问点的设计模式。文中通过Windows任务管理器的例子阐述了单例模式的动机,解释了如何通过私有构造函数、静态私有成员变量和公有静态方法实现单例模式。接着,通过负载均衡器的案例展示了单例模式的应用,并讨论了单例模式的优点、缺点以及适用场景。最后,文章还探讨了饿汉式和懒汉式单例的实现方式及其比较。
【五】设计模式~~~创建型模式~~~单例模式(Java)
|
2天前
|
设计模式 算法 安全
Java编程中的设计模式:提升代码的可维护性和扩展性
【8月更文挑战第19天】在软件开发的世界里,设计模式是解决常见问题的一种优雅方式。本文将深入探讨Java编程语言中常用的几种设计模式,并解释如何通过这些模式来提高代码的可维护性和扩展性。文章不涉及具体的代码实现,而是侧重于理论和实践相结合的方式,为读者提供一种思考和改善现有项目的新视角。
|
2天前
|
设计模式 XML 存储
【六】设计模式~~~结构型模式~~~适配器模式(Java)
文章详细介绍了适配器模式(Adapter Pattern),这是一种结构型设计模式,用于将一个类的接口转换成客户期望的另一个接口,使原本不兼容的接口能够一起工作,提高了类的复用性和系统的灵活性。通过对象适配器和类适配器两种实现方式,展示了适配器模式的代码应用,并讨论了其优点、缺点以及适用场景。
|
2天前
|
设计模式 Java
常用设计模式介绍~~~ Java实现 【概念+案例+代码】
文章提供了一份常用设计模式的全面介绍,包括创建型模式、结构型模式和行为型模式。每种设计模式都有详细的概念讲解、案例说明、代码实例以及运行截图。作者通过这些模式的介绍,旨在帮助读者更好地理解源码、编写更优雅的代码,并进行系统重构。同时,文章还提供了GitHub上的源码地址,方便读者直接访问和学习。
常用设计模式介绍~~~ Java实现 【概念+案例+代码】
|
2天前
|
设计模式 算法 Java
【十六】设计模式~~~行为型模式~~~策略模式(Java)
文章详细介绍了策略模式(Strategy Pattern),这是一种对象行为型模式,用于定义一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法独立于使用它的客户而变化,提高了系统的灵活性和可扩展性。通过电影院售票系统中不同类型用户的打折策略案例,展示了策略模式的动机、定义、结构、优点、缺点以及适用场景,并提供了Java代码实现和测试结果。
【十六】设计模式~~~行为型模式~~~策略模式(Java)
|
2天前
|
设计模式 网络协议 Java
【十五】设计模式~~~行为型模式~~~状态模式(Java)
文章详细介绍了状态模式(State Pattern),这是一种对象行为型模式,用于处理对象在其内部状态改变时的行为变化。文中通过案例分析,如银行账户状态管理和屏幕放大镜工具,展示了状态模式的应用场景和设计方法。文章阐述了状态模式的动机、定义、结构、优点、缺点以及适用情况,并提供了Java代码实现和测试结果。状态模式通过将对象的状态和行为封装在独立的状态类中,提高了系统的可扩展性和可维护性。
【十五】设计模式~~~行为型模式~~~状态模式(Java)