继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

谈谈组合策略模式及在生产的应用

0xcaffebabe
关注TA
已关注
手记 43
粉丝 10
获赞 21

谈谈组合策略模式及在生产的应用

组合模式

学设计模式第一次听到这个模式时被迷惑了,以为所谓的组合模式是跟面向对象编程里的组合概念的一样

// 想象中的组合模式class Car {
  private Door door;
  private Wheel Whee;}

读了 GOF 的设计模式之后,书里是将组合模式描述为

将对象组合成树形结构的部分-整体层次结构,使得客户使用单个对象或组合对象都有一致性

也就是说组合部分与被组合部分在对外表现上,应该都是一致的,也就是其实是这样的

class Node {
  private Node part1;
  private Node part2;}

真正让我理解组合模式和它的妙用是在《领域驱动设计》这本书里面,作者提出了一个航线的概念,也就是这样,通过组合基本组件以达到功能更强大的一个组件

interface Route {
    Route segement1, segement2;} // 路线class NationalHighway implements Route{} // 国道class CountryRoad implements Route {} // 乡道

策略模式

所谓策略,则可以理解为针对某种特定问题的算法,由于不同的算法各有优劣,所以需要将策略抽象为一个接口,让客户代码根据需求选择不同策略来解决问题,代码如下

interface Strategy{
    void execute(..);}class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    
    void execute(){
        strategy.execute(..);
    }}class StrategyA implements Strategy{
    // 具体实现}// 使用Context context = new Context(new StrategyA());context.execute();

二者的结合

组合与策略两者的结合,不仅可以充分利用组合模式的灵活性,同时也可以利用策略模式的不同算法可选择性

interface Strategy{
    void execute(..);}class StrategyA implements Strategy{
    // 具体实现}class StrategyB implements Strategy{
    // 具体实现}// 组合策略class CompositeStrategy implements Strategy {
  private Strategy strategyA, strategyB;}

通过组合不仅可以显式编程,交由不同的具体客户满足不同的需求,同时细粒度的策略也暴露了出去,也能让策略更有针对性及可选择性,更进一步,可以使用工厂模式将策略的组装与生成封装在工厂内部,这样客户代码也不必关心他使用的具体策略是什么,只要策略满足他的需求即可

生产上的应用

这个业务场景是这样

  • 我们有许多三方接口来获取某种信息

  • 每种接口不仅需要单独对外提供服务,同时也需要聚合所有接口数据再对外提供服务

通过封装,这些返回的信息基本上都是一样的,但由于我们的项目在不同的地方运行,不同的地方可能有些接口可用,有些接口不可用,所以此时就通过组合策略模式来满足以上的所有需求

interface FetchInfoStrategy {
    Info fetch(...);}// 具体三方接口class ThirdPartAFetchInfoStrategy implements FetchInfoStrategy{...}class ThirdPartBFetchInfoStrategy implements FetchInfoStrategy{...}class ThirdPartCFetchInfoStrategy implements FetchInfoStrategy{...}// 组合三方接口class CompositeFetchInfoStrtegy implements FetchInfoStrategy {
  // 通过配置化动态注入
  private static final List<Class<? extends FetchInfoStrategy>> STRATEGY_LIST;

  Info fetch(...) {
    // 循环调用策略,记录各个接口返回结果
    // 合并结果并返回
  }}

通过这样子的组合策略,不仅满足了需求,也为后续的优化留下了空间,若想通过异步调用各个接口,或者调整具体合并逻辑,都可以通过新增一个组合策略,避免修改老代码带来预期之外的问题


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP