硬肝系列:23种设计模式之适配器模式

用示例代码来帮你了解适配器模式

对于“设计模式”这个词大家肯定都不陌生,很多框架也用到了设计模式,但是大部分的开发者应该是没有深入的了解过,我准备硬肝下这23设计模式作为专题文章的开端,一共23种设计模式,我尽量在<23天肝完。

为什么要学习设计模式:https://blog.csdn.net/kaituozhe_sh/article/details/107922339

在我大学四年,对设计模式也没有什么概念,写代码就想着能实现就可以了,不会有设计模式那样的思想,但是当学习到了框架的时候,对于设计模式才有了一些更深入的了解,使用设计模式的代码在扩展性上会比暴力的代码更容易维护,特别是当一个程序猿离职了后,你去接手它的代码,里面是一大堆if else,这样真的会崩溃,修改都不知道从何下手
在这里插入图片描述

硬肝系列目录

创建型模式

23种设计模式之工厂模式

23种设计模式之抽象工厂模式

23种设计模式之建造者模式

23种设计模式之原型模式

23种设计模式之单例模式

结构型模式

23种设计模式之适配器模式

23种设计模式之桥梁模式

23种设计模式之代理模式

23种设计模式之外观模式

23种设计模式之装饰器模式

23种设计模式之享元模式

23种设计模式之组合模式

行为型模式

23种设计模式之责任链模式

23种设计模式之命令模式

23种设计模式之迭代器模式

23种设计模式之中介者模式

23种设计模式之备忘录模式

到目前为止、23种设计模式的创建型模式已经给大家肝完了,现在我们进入到一个全新的章节,结构型模式!!!

适配器模式

什么是适配器?

对于手机和电源来说,充电器就是一个适配器,充电器将220V的额定电压转换为我手机所需要充电的电压,要不然用220V来对手机进行充电,我相信目前为止的手机都接受不了这么大的电压,还有一些耳机转接头、屏幕转接头也是一类适配器,那对于我们代码来说什么样的才叫适配器呢?我举个例子A、B两个系统传输数据可能在A系统的用户id字段为userId,但是B系统的用户id字段为uId,这样就出现分歧了,B系统得将userId转换为uId才可以储存吧,这里就相当于用到我们适配器模式的开发原理了,随着系统越来越大,子系统越来越多,各个子系统的信息传递就成了很大的一个问题,而且子系统有些又是外包出去的项目,这就导致了一个问题,数据库设计的字段设计大部分是不一样的,这就需要从其他系统接收信息的时候需要我们这边自己处理一下才能存库或者进行下一步的操作

到目前为止、对于实际项目我接触过的有利用适配器模式进行开发的系统就有一个,我用一个图来给大家说明

上图
通过我们上面的图可以看出,适配器前置也可以作为一个小系统,也可以处理业务逻辑,但是最主要的是监听消息以及消息转换,转换成我们子系统所需要的消息格式,所以对于多个子系统的互相通信,适配器还是很有需要的

现在我们用一个比较简单的代码来模拟实际项目用到适配器模式的事件

举个栗子,像平常我们使用的TB、JD等购物软件,当用户下单的时候,会给你一定的积分吧、有时候还会送一些小礼品,因为现在几乎所有的互联网公司都是使用的微服务架构,各个子系统各自执行,互不影响,通过网络进行消息的传递,有的时候需要消息队列来进行通信,但是消息队列只负责消息的发送与持久化,不能帮你更改里面的内容啊,所以我们需要在各自的子系统中维护其他子系统传递过来的消息,现在我们模拟三个子系统之间的通信,订单系统礼品系统积分系统

订单系统需要传递的消息:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderTransferAdapter {
    private String userId;
    private String orderId;
    private String address;
    private BigDecimal monetary;
    private Date createDate;
}

这就出现了一个问题,我礼品系统的用户Id不叫userId,而是uIdorderIdoId,所以我们需要一个适配器来转换订单系统传过来的字段,变成我们所需要的格式
定义一个适配器抽象类:

@Data
public abstract class AbstractTransferAdapter<T> {
	//json为其他子系统传过来的消息
    public abstract T transfer(JSONObject json);
}

礼品类来继承抽象类,实现适配器模式:

public class GiftTransferAdapter extends AbstractTransferAdapter<GiftTransferAdapter.TargetObject>{

    @Override
    public TargetObject transfer(JSONObject json) {
        return new TargetObject
                .TargetObjectBuilder()
                .uid(json.getStr("userId"))
                .oid(json.getStr("orderId"))
                .userAddress(json.getStr("address"))
                .createDate(json.getDate("createDate"))
                .build();
    }
    @Data
    @Builder
    static class TargetObject{
        private String uid;
        private String oid;
        private String userAddress;
        private Date createDate;
    }
}

从上面的代码我们可以看出,根据订单系统传过来的json格式字符串,我们通过定义一个静态内部类,内部类的字段就是我们礼品系统所需要的字段名称,transfer()返回的就是礼品系统所需要的对象

积分系统也是一样的道理,直接上代码:

public class IntegralTransferAdapter extends AbstractTransferAdapter<IntegralTransferAdapter.TargetObject>{

    @Override
    public TargetObject transfer(JSONObject json) {
        return new TargetObject
                .TargetObjectBuilder()
                .consumerId(json.getStr("userId"))
                .oid(json.getStr("orderId"))
                .consume(json.getBigDecimal("monetary"))
                .createDate(json.getDate("createDate"))
                .build();
    }

    @Data
    @Builder
    static class TargetObject{
        private String consumerId;
        private String oid;
        private BigDecimal consume;
        private Date createDate;
    }
}

积分系统的用户Id在这称作consumerId,原理和礼品系统一样
最后我们写一个测试类来测试我们的代码是否正确

public class TestAdapter {
    public static void main(String[] args) {
        //模拟用户下单
        //创建订单
        OrderTransferAdapter order = new OrderTransferAdapter();
        order.setUserId("ALiangX");
        UUID uuid = UUID.randomUUID();
        order.setOrderId(uuid.toString());
        order.setAddress("中国山东济南");
        order.setMonetary(new BigDecimal(2021.314));
        order.setCreateDate(new Date());

        //将需要传输的字段放到json字符串中
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("userId",order.getUserId());
        jsonObject.set("orderId",order.getOrderId());
        jsonObject.set("address",order.getAddress());
        jsonObject.set("monetary",order.getMonetary().toString());
        jsonObject.set("createDate",order.getCreateDate().toString());
        System.out.println("订单系统传输的数据" + jsonObject.toString() + "\n");
        //模拟网络传输----------------kafka~~~~过了0.00001s通过消息队列到达子系统
        GiftTransferAdapter gift = new GiftTransferAdapter();
        //得到一个礼品系统需要的对象giftObject
        GiftTransferAdapter.TargetObject giftObject = gift.transfer(jsonObject);
        System.out.println("礼品系统通过适配器转换得到的数据: \n uId: " + giftObject.getUid() +
                "\n oId: " + giftObject.getOid() +
                "\n UserAddress: " + giftObject.getUserAddress() +
                "\n CreateDate: " + giftObject.getCreateDate());
        
        IntegralTransferAdapter integral = new IntegralTransferAdapter();
        //得到一个积分系统需要的对象integralObject
        IntegralTransferAdapter.TargetObject integralObject= integral.transfer(jsonObject);
        System.out.println("积分系统通过适配器转换得到的数据: \n consumerId: " + integralObject.getConsumerId() +
                "\n oId: " + integralObject.getOid() +
                "\n consume: " + integralObject.getConsume() +
                "\n CreateDate: " + integralObject.getCreateDate());
    }
}

输出结果:

订单系统传输的数据{"address":"中国山东济南","monetary":"2021.314000000000078216544352471828460693359375","orderId":"c418a764-3947-4d12-a799-d24cb3450fad","userId":"ALiangX","createDate":"Fri Mar 19 16:20:40 CST 2021"}

礼品系统通过适配器转换得到的数据: 
 uId: ALiangX
 oId: c418a764-3947-4d12-a799-d24cb3450fad
 UserAddress: 中国山东济南
 CreateDate: Fri Mar 19 16:20:40 CST 2021
 
积分系统通过适配器转换得到的数据: 
 consumerId: ALiangX
 oId: c418a764-3947-4d12-a799-d24cb3450fad
 consume: 2021.314000000000078216544352471828460693359375
 CreateDate: Fri Mar 19 16:20:40 CST 2021

子系统得到数据之后就可以进行自己的业务处理了,这里只是简单的模拟了一下适配器模式的应用,通过适配器模式,我们再也不用为数据库字段设计不同而苦恼,随着系统的不断深入,拥有坚实的基础还是非常重要的!!!

完成:TO: 2021/3/19 16:55

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉淀顶峰相见的PET

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值