设计模式 - 结构型模式_适配器模式

Posted 小小工匠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式 - 结构型模式_适配器模式相关的知识,希望对你有一定的参考价值。

文章目录


结构型模式

结构型模式主要是解决如何将对象和类组装成较大的结构, 并同时保持结构的灵活和⾼效。

结构型模式包括:适配器、桥接、组合、装饰器、外观、享元、代理,这7类


概述


适配器模式的主要作⽤就是把原本不兼容的接⼝,通过适配修改做到统⼀。使得⽤户⽅便使⽤,就像我们提到转换头、出国旅游买个插座等等,都是为了适配各种不同的口 ,做的兼容。

在业务开发中我们会经常的需要做不同接⼝的兼容,尤其是中台服务,中台需要把各个业务线的各种类型服务做统⼀包装,再对外提供接⼝进⾏使⽤。⽽这在平常的开发中也是⾮常常⻅的。


Case

营销系统 接收各种各样的MQ消息或者接⼝,如果⼀个个的去开发,就会耗费很⼤的成本,同时对于后期的拓展也有⼀定的难度。

此时就会希望有⼀个系统可以配置⼀下就把外部的MQ接⼊进⾏,这些MQ就像上⾯提到的可能是⼀些注册开户消息、商品下单消息等等。


场景模拟⼯程

  • 模拟了三个不同类型的MQ消息,⽽在消息体中都有⼀些必要的字段,⽐如: ⽤户ID、时间、业务ID,但是每个MQ的字段属性并不⼀样。就像⽤户ID在不同的MQ⾥也有不同的字段:uId、userId等。
  • 同时还提供了两个不同类型的接⼝,⼀个⽤于查询内部订单订单下单数量,⼀个⽤于查询第三⽅是否⾸单。
  • 后⾯会把这些不同类型的MQ和接⼝做适配兼容。

【注册开户MQ】

@Data
@NoArgsConstructor
@AllArgsConstructor
public class CreateAccount 

    /**
     * 开户编号
     */
    private String number;

    /**
     * 开户地
     */
    private String address;


    /**
     * 开户时间
     */
    private Date accountDate;


    /**
     * 开户描述
     */
    private String desc;


    @Override
    public String toString() 
        return JSON.toJSONString(this);
    


【内部订单MQ】

@Data
@NoArgsConstructor
@AllArgsConstructor
public class OrderMq 

    /**
     * 用户ID
     */
    private String uid;

    /**
     * 商品
     */
    private String sku;

    /**
     * 订单ID
     */
    private String orderId;

    /**
     * 下单时间
     */
    private Date createOrderTime;


    @Override
    public String toString() 
        return JSON.toJSONString(this);
    


【第三⽅订单MQ】

@Data
@NoArgsConstructor
@AllArgsConstructor
public class POPOrderDelivered 

    /**
     * 用户ID
     */
    private String uId;

    /**
     * 订单号
     */
    private String orderId;

    /**
     * 下单时间
     */
    private Date orderTime;

    /**
     * 商品
     */
    private Date sku;

    /**
     * 商品名称
     */
    private Date skuName;


    /**
     * 金额
     */
    private BigDecimal decimal;


    @Override
    public String toString() 
        return JSON.toJSONString(this);
    



【查询⽤户内部下单数量接⼝】

public class OrderService 

    private Logger logger = LoggerFactory.getLogger(POPOrderService.class);

    public long queryUserOrderCount(String userId)
        logger.info("自营商家,查询用户的订单是否为首单:", userId);
        return 10L;
    



【查询⽤户第三⽅下单⾸单接⼝】

public class POPOrderService 

    private Logger logger = LoggerFactory.getLogger(POPOrderService.class);

    public boolean isFirstOrder(String uId) 
        logger.info("POP商家,查询用户的订单是否为首单:", uId);
        return true;
    



以上这⼏项就是不同的MQ以及不同的接⼝的⼀个体现,后⾯将使⽤这样的MQ消息和接⼝,给它们做相应的适配。


Bad Impl

其实⼤部分时候接MQ消息都是创建⼀个类⽤于消费,通过转换他的MQ消息属性给⾃⼰的⽅法。

我们接下来也是先体现⼀下这种⽅式的实现模拟,但是这样的实现有⼀个很⼤的问题就是,当MQ消息越来越多后,甚⾄⼏⼗⼏百以后,作为中台系统要怎么优化呢?

⽬前需要接收三个MQ消息,所有就有了三个对应的类,和我们平时的代码⼏乎⼀样。如果MQ量不多,这样的写法也没什么问题,但是随着数量的增加,就需要考虑⽤⼀些设计模式来解决。

public class CreateAccountMqService 

    public void onMessage(String message) 

        CreateAccount mq = JSON.parseObject(message, CreateAccount.class);

        mq.getNumber();
        mq.getAccountDate();

        // ... 处理自己的业务
    




Better Impl (适配器模式重构代码)

接下来使⽤适配器模式来进⾏代码优化,也算是⼀次很⼩的重构。

适配器模式要解决的主要问题就是多种差异化类型的接⼝做统⼀输出。 把不同类型的消息做统⼀的处理,便于减少后续对MQ接收。如果我们接收MQ后,在配置不同的消费类时,如果不希望⼀个个开发类,那么可以使⽤代理类的⽅式进⾏处理。

【工程结构】

【适配器模型结构】

  • 这⾥包括了两个类型的适配;接⼝适配、MQ适配。之所以不只是模拟接⼝适配,因为很常⻅了,所以把适配的思想换⼀下到MQ消息体上,增加对设计模式的认知。
  • 先是做MQ适配,接收各种各样的MQ消息。当业务发展的很快,需要对下单⽤户⾸单才给奖励,在这样的场景下再增加对接⼝的适配操作。

以上是关于设计模式 - 结构型模式_适配器模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式 - 结构型模式_适配器模式

《精通Python设计模式》学习结构型之适配器模式

一点公益模式和二码公益系统详细解释

小程序餐饮模式定制开发

设计模式 - 结构型模式_外观模式

设计模式 - 结构型模式_桥接模式