成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

詳解Java實踐之適配器模式

瀏覽:141日期:2022-08-10 11:18:06
目錄一、前言二、適配器模式介紹三、案例場景模擬3.1、場景模擬工程3.2、場景簡述3.2.1、注冊開戶MQ3.2.2、內部訂單MQ3.2.3、第三方訂單MQ3.2.4、查詢用戶內部下單數量接口3.2.5、查詢用戶第三方下單首單接口四、代碼實現4.1、工程結構4.2、Mq接收消息實現五、適配器模式重構代碼5.1、工程結構5.2、代碼實現(MQ消息適配)5.2.1、統一的MQ消息體5.2.2、MQ消息體適配類5.2.3、測試適配類5.3、代碼實現(接口使用適配)5.3.1、定義統一適配接口5.3.2、分別實現兩個不同的接口5.3.3、測試適配類六、總結一、前言

工作到3年左右很大一部分程序員都想提升自己的技術棧,開始嘗試去閱讀一些源碼,例如Spring、Mybaits、Dubbo等,但讀著讀著發現越來越難懂,一會從這過來一會跑到那去。甚至懷疑自己技術太差,慢慢也就不愿意再觸碰這部分知識。

而這主要的原因是一個框架隨著時間的發展,它的復雜程度是越來越高的,從最開始只有一個非常核心的點到最后開枝散葉。這就像你自己開發的業務代碼或者某個組件一樣,最開始的那部分核心代碼也許只能占到20%,而其他大部分代碼都是為了保證核心流程能正常運行的。所以這也是你讀源碼費勁的一部分原因。

框架中用到了設計模式嗎?

框架中不僅用到設計模式還用了很多,而且有些時候根本不是一個模式的單獨使用,而是多種設計模式的綜合運用。與大部分小伙伴平時開發的CRUD可就不一樣了,如果都是if語句從上到下,也就算得不上什么框架了。就像你到Spring的源碼中搜關鍵字Adapter,就會出現很多實現類,例如;UserCredentialsDataSourceAdapter。而這種設計模式就是我們本文要介紹的適配器模式。

適配器在生活里隨處可見

如果提到在日常生活中就很多適配器的存在你會想到什么?在沒有看后文之前可以先思考下。

二、適配器模式介紹

詳解Java實踐之適配器模式

適配器模式的主要作用就是把原本不兼容的接口,通過適配修改做到統一。使得用戶方便使用,就像我們提到的萬能充、數據線、MAC筆記本的轉換頭、出國旅游買個插座等等,他們都是為了適配各種不同的口,做的兼容。。

詳解Java實踐之適配器模式

除了我們生活中出現的各種適配的場景,那么在業務開發中呢?

在業務開發中我們會經常的需要做不同接口的兼容,尤其是中臺服務,中臺需要把各個業務線的各種類型服務做統一包裝,再對外提供接口進行使用。而這在我們平常的開發中也是非常常見的。

三、案例場景模擬

詳解Java實踐之適配器模式

隨著公司的業務的不斷發展,當基礎的系統逐步成型以后。業務運營就需要開始做用戶的拉新和促活,從而保障DAU的增速以及最終ROI轉換。

而這時候就會需要做一些營銷系統,大部分常見的都是裂變、拉客,例如;你邀請一個用戶開戶、或者邀請一個用戶下單,那么平臺就會給你返利,多邀多得。同時隨著拉新的量越來越多開始設置每月下單都會給首單獎勵,等等,各種營銷場景。

那么這個時候做這樣一個系統就會接收各種各樣的MQ消息或者接口,如果一個個的去開發,就會耗費很大的成本,同時對于后期的拓展也有一定的難度。此時就會希望有一個系統可以配置一下就把外部的MQ接入進行,這些MQ就像上面提到的可能是一些注冊開戶消息、商品下單消息等等。

而適配器的思想方式也恰恰可以運用到這里,并且我想強調一下,適配器不只是可以適配接口往往還可以適配一些屬性信息。

3.1、場景模擬工程

itstack-demo-design-6-00

└── src

    └── main

        └── java

            └── org.itstack.demo.design

                ├── mq

                │   ├── create_account.java

                │   ├── OrderMq.java

                │   └── POPOrderDelivered.java

                └── service

                    ├── OrderServicejava

                    └── POPOrderService.java

這里模擬了三個不同類型的MQ消息,而在消息體中都有一些必要的字段,比如;用戶ID、時間、業務ID,但是每個MQ的字段屬性并不一樣。就像用戶ID在不同的MQ里也有不同的字段:uId、userId等。同時還提供了兩個不同類型的接口,一個用于查詢內部訂單訂單下單數量,一個用于查詢第三方是否首單。后面會把這些不同類型的MQ和接口做適配兼容。

3.2、場景簡述3.2.1、注冊開戶MQ

public class create_account { private String number; // 開戶編號 private String address; // 開戶地 private Date accountDate; // 開戶時間 private String desc;// 開戶描述 // ... get/set }3.2.2、內部訂單MQ

public class OrderMq { private String uid; // 用戶ID private String sku; // 商品 private String orderId; // 訂單ID private Date createOrderTime; // 下單時間 // ... get/set }3.2.3、第三方訂單MQ

public class POPOrderDelivered { private String uId; // 用戶ID private String orderId; // 訂單號 private Date orderTime; // 下單時間 private Date sku; // 商品 private Date skuName; // 商品名稱 private BigDecimal decimal; // 金額 // ... get/set }3.2.4、查詢用戶內部下單數量接口

public class OrderService { private Logger logger = LoggerFactory.getLogger(POPOrderService.class); public long queryUserOrderCount(String userId){logger.info('自營商家,查詢用戶的訂單是否為首單:{}', userId);return 10L; }}3.2.5、查詢用戶第三方下單首單接口

public class POPOrderService { private Logger logger = LoggerFactory.getLogger(POPOrderService.class); public boolean isFirstOrder(String uId) {logger.info('POP商家,查詢用戶的訂單是否為首單:{}', uId);return true; }}

以上這幾項就是不同的MQ以及不同的接口的一個體現,后面我們將使用這樣的MQ消息和接口,給它們做相應的適配。

四、代碼實現

其實大部分時候接MQ消息都是創建一個類用于消費,通過轉換他的MQ消息屬性給自己的方法。

我們接下來也是先體現一下這種方式的實現模擬,但是這樣的實現有一個很大的問題就是,當MQ消息越來越多后,甚至幾十幾百以后,你作為中臺要怎么優化呢?

4.1、工程結構

itstack-demo-design-6-01

└── src

    └── main

        └── java

            └── org.itstack.demo.design

                └── create_accountMqService.java

                └── OrderMqService.java

                └── POPOrderDeliveredService.java

目前需要接收三個MQ消息,所有就有了三個對應的類,和我們平時的代碼幾乎一樣。如果你的MQ量不多,這樣的寫法也沒什么問題,但是隨著數量的增加,就需要考慮用一些設計模式來解決。

4.2、Mq接收消息實現

public class create_accountMqService { public void onMessage(String message) {create_account mq = JSON.parseObject(message, create_account.class);mq.getNumber();mq.getAccountDate();// ... 處理自己的業務 }}

三組MQ的消息都是一樣模擬使用,就不一一展示了。可以獲取源碼后學習。

五、適配器模式重構代碼

接下來使用適配器模式來進行代碼優化,也算是一次很小的重構。

適配器模式要解決的主要問題就是多種差異化類型的接口做統一輸出,這在我們學習工廠方法模式中也有所提到不同種類的獎品處理,其實那也是適配器的應用。

在本文中我們還會再另外體現出一個多種MQ接收,使用MQ的場景。來把不同類型的消息做統一的處理,便于減少后續對MQ接收。

在這里如果你之前沒要開發過接收MQ消息,可能聽上去會有些不理解這樣的場景。對此,我個人建議先了解下MQ。另外就算不了解也沒關系,不會影響對思路的體會。

再者,本文所展示的MQ兼容的核心部分,也就是處理適配不同的類型字段。而如果我們接收MQ后,在配置不同的消費類時,如果不希望一個個開發類,那么可以使用代理類的方式進行處理。

5.1、工程結構

itstack-demo-design-6-02

└── src

    └── main

        └── java

            └── org.itstack.demo.design

                ├── impl

                │   ├── InsideOrderService.java

                │   └── POPOrderAdapterServiceImpl.java

                ├── MQAdapter,java

                ├── OrderAdapterService,java

                └── RebateInfo,java

適配器模型結構

詳解Java實踐之適配器模式

這里包括了兩個類型的適配;接口適配、MQ適配。之所以不只是模擬接口適配,因為很多時候大家都很常見了,所以把適配的思想換一下到MQ消息體上,增加大家多設計模式的認知。 先是做MQ適配,接收各種各樣的MQ消息。當業務發展的很快,需要對下單用戶首單才給獎勵,在這樣的場景下再增加對接口的適配操作。5.2、代碼實現(MQ消息適配)5.2.1、統一的MQ消息體

public class RebateInfo { private String userId; // 用戶ID private String bizId; // 業務ID private Date bizTime; // 業務時間 private String desc; // 業務描述// ... get/set} MQ消息中會有多種多樣的類型屬性,雖然他們都有同樣的值提供給使用方,但是如果都這樣接入那么當MQ消息特別多時候就會很麻煩。 所以在這個案例中我們定義了通用的MQ消息體,后續把所有接入進來的消息進行統一的處理。5.2.2、MQ消息體適配類

public class MQAdapter { public static RebateInfo filter(String strJson, Map<String, String> link) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {return filter(JSON.parseObject(strJson, Map.class), link); } public static RebateInfo filter(Map obj, Map<String, String> link) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {RebateInfo rebateInfo = new RebateInfo();for (String key : link.keySet()) { Object val = obj.get(link.get(key)); RebateInfo.class.getMethod('set' + key.substring(0, 1).toUpperCase() + key.substring(1), String.class).invoke(rebateInfo, val.toString());}return rebateInfo; }} 這個類里的方法非常重要,主要用于把不同類型MQ種的各種屬性,映射成我們需要的屬性并返回。就像一個屬性中有用戶ID;uId,映射到我們需要的;userId,做統一處理。 而在這個處理過程中需要把映射管理傳遞給Map<String, String> link,也就是準確的描述了,當前MQ中某個屬性名稱,映射為我們的某個屬性名稱。 最終因為我們接收到的mq消息基本都是json格式,可以轉換為MAP結構。最后使用反射調用的方式給我們的類型賦值。5.2.3、測試適配類

編寫單元測試類

@Testpublic void test_MQAdapter() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { create_account create_account = new create_account(); create_account.setNumber('100001'); create_account.setAddress('河北省.廊坊市.廣陽區.大學里職業技術學院'); create_account.setAccountDate(new Date()); create_account.setDesc('在校開戶'); HashMap<String, String> link01 = new HashMap<String, String>(); link01.put('userId', 'number'); link01.put('bizId', 'number'); link01.put('bizTime', 'accountDate'); link01.put('desc', 'desc'); RebateInfo rebateInfo01 = MQAdapter.filter(create_account.toString(), link01); System.out.println('mq.create_account(適配前)' + create_account.toString()); System.out.println('mq.create_account(適配后)' + JSON.toJSONString(rebateInfo01)); System.out.println(''); OrderMq orderMq = new OrderMq(); orderMq.setUid('100001'); orderMq.setSku('10928092093111123'); orderMq.setOrderId('100000890193847111'); orderMq.setCreateOrderTime(new Date()); HashMap<String, String> link02 = new HashMap<String, String>(); link02.put('userId', 'uid'); link02.put('bizId', 'orderId'); link02.put('bizTime', 'createOrderTime'); RebateInfo rebateInfo02 = MQAdapter.filter(orderMq.toString(), link02); System.out.println('mq.orderMq(適配前)' + orderMq.toString()); System.out.println('mq.orderMq(適配后)' + JSON.toJSONString(rebateInfo02));} 在這里我們分別模擬傳入了兩個不同的MQ消息,并設置字段的映射關系。 等真的業務場景開發中,就可以配這種映射配置關系交給配置文件或者數據庫后臺配置,減少編碼。

測試結果

mq.create_account(適配前){'accountDate':1591024816000,'address':'河北省.廊坊市.廣陽區.大學里職業技術學院','desc':'在校開戶','number':'100001'}

mq.create_account(適配后){'bizId':'100001','bizTime':1591077840669,'desc':'在校開戶','userId':'100001'}

mq.orderMq(適配前){'createOrderTime':1591024816000,'orderId':'100000890193847111','sku':'10928092093111123','uid':'100001'}

mq.orderMq(適配后){'bizId':'100000890193847111','bizTime':1591077840669,'userId':'100001'}

Process finished with exit code 0

從上面可以看到,同樣的字段值在做了適配前后分別有統一的字段屬性,進行處理。這樣業務開發中也就非常簡單了。 另外有一個非常重要的地方,在實際業務開發中,除了反射的使用外,還可以加入代理類把映射的配置交給它。這樣就可以不需要每一個mq都手動創建類了。5.3、代碼實現(接口使用適配)

就像我們前面提到隨著業務的發展,營銷活動本身要修改,不能只是接了MQ就發獎勵。因為此時已經拉新的越來越多了,需要做一些限制。

因為增加了只有首單用戶才給獎勵,也就是你一年或者新人或者一個月的第一單才給你獎勵,而不是你之前每一次下單都給獎勵。

那么就需要對此種方式進行限制,而此時MQ中并沒有判斷首單的屬性。只能通過接口進行查詢,而拿到的接口如下;

接口 描述 org.itstack.demo.design.service.OrderService.queryUserOrderCount(String userId) 出參long,查詢訂單數量 org.itstack.demo.design.service.OrderService.POPOrderService.isFirstOrder(String uId) 出參boolean,判斷是否首單兩個接口的判斷邏輯和使用方式都不同,不同的接口提供方,也有不同的出參。一個是直接判斷是否首單,另外一個需要根據訂單數量判斷。 因此這里需要使用到適配器的模式來實現,當然如果你去編寫if語句也是可以實現的,但是我們經常會提到這樣的代碼很難維護。5.3.1、定義統一適配接口

public interface OrderAdapterService { boolean isFirst(String uId);}

后面的實現類都需要完成此接口,并把具體的邏輯包裝到指定的類中,滿足單一職責。

5.3.2、分別實現兩個不同的接口

內部商品接口

public class InsideOrderService implements OrderAdapterService { private OrderService orderService = new OrderService(); public boolean isFirst(String uId) {return orderService.queryUserOrderCount(uId) <= 1; }}

第三方商品接口

public class POPOrderAdapterServiceImpl implements OrderAdapterService { private POPOrderService popOrderService = new POPOrderService(); public boolean isFirst(String uId) {return popOrderService.isFirstOrder(uId); }}

在這兩個接口中都實現了各自的判斷方式,尤其像是提供訂單數量的接口,需要自己判斷當前接到mq時訂單數量是否<= 1,以此判斷是否為首單。

5.3.3、測試適配類

編寫單元測試類

@Testpublic void test_itfAdapter() { OrderAdapterService popOrderAdapterService = new POPOrderAdapterServiceImpl(); System.out.println('判斷首單,接口適配(POP):' + popOrderAdapterService.isFirst('100001')); OrderAdapterService insideOrderService = new InsideOrderService(); System.out.println('判斷首單,接口適配(自營):' + insideOrderService.isFirst('100001'));}

測試結果

23:25:47.076 [main] INFO  o.i.d.design.service.POPOrderService - POP商家,查詢用戶的訂單是否為首單:100001

判斷首單,接口適配(POP):true

23:25:47.079 [main] INFO  o.i.d.design.service.POPOrderService - 自營商家,查詢用戶的訂單是否為首單:100001

判斷首單,接口適配(自營):false

Process finished with exit code 0

從測試結果上來看,此時已經的接口已經做了統一的包裝,外部使用時候就不需要關心內部的具體邏輯了。而且在調用的時候只需要傳入統一的參數即可,這樣就滿足了適配的作用。

六、總結 從上文可以看到不使用適配器模式這些功能同樣可以實現,但是使用了適配器模式就可以讓代碼:干凈整潔易于維護、減少大量重復的判斷和使用、讓代碼更加易于維護和拓展。 尤其是我們對MQ這樣的多種消息體中不同屬性同類的值,進行適配再加上代理類,就可以使用簡單的配置方式接入對方提供的MQ消息,而不需要大量重復的開發。非常利于拓展。 設計模式的學習過程可能會在一些章節中涉及到其他設計模式的體現,只不過不會重點講解,避免喧賓奪主。但在實際的使用中,往往很多設計模式是綜合使用的,并不會單一出現。

以上就是詳解Java實踐之適配器模式的詳細內容,更多關于Java適配器模式的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
丁香五精品蜜臀久久久久99网站| 99国产精品| 一本久道久久久| 日韩欧美国产综合在线一区二区三区| 蜜臀av性久久久久av蜜臀妖精| 亚洲欧美日本日韩| 亚洲狼人国产精品| 亚洲茄子视频| 亚洲日本免费电影| 亚洲国产欧美国产综合一区| 亚洲国产精品ⅴa在线观看| 91丨九色丨国产丨porny| 26uuu色噜噜精品一区| 99久久er热在这里只有精品66| 精品国产人成亚洲区| 成人一道本在线| 欧美成人伊人久久综合网| 成人午夜短视频| 欧美一个色资源| 国产91精品精华液一区二区三区| 91精品国产综合久久精品| 国产精品99久久久久久久女警| 欧美一区二区福利在线| 粉嫩13p一区二区三区| 欧美成人艳星乳罩| 色综合久久综合网97色综合| 欧美国产日韩精品免费观看| 午夜日韩av| 国产女同性恋一区二区| 欧美日韩网站| 日韩伦理av电影| 国产视频一区三区| 午夜精品久久久久久久久久久 | 国产一区不卡在线| 日韩片之四级片| av中文字幕不卡| 中文字幕欧美国产| 亚洲每日更新| 午夜影视日本亚洲欧洲精品| 在线亚洲精品福利网址导航| 激情小说欧美图片| 久久久久国产成人精品亚洲午夜| 91在线观看一区二区| 国产精品久久毛片| 国产模特精品视频久久久久| 国产传媒一区在线| 久久精品无码一区二区三区| 亚洲高清资源综合久久精品| 亚洲成国产人片在线观看| 欧美性色欧美a在线播放| 成人小视频免费在线观看| 欧美经典一区二区| 亚洲中午字幕| 国产寡妇亲子伦一区二区| 国产欧美日韩在线视频| 国产区日韩欧美| 久久精品国产精品亚洲红杏 | 国产日韩一区二区三区在线播放 | 国产·精品毛片| 国产欧美一区二区精品仙草咪| 国产欧美丝祙| 国产一区二区三区四区五区美女| 国产午夜亚洲精品羞羞网站| 国产精品日韩高清| 国产精品一二三在| 国产精品二三区| 一本一本大道香蕉久在线精品| 国产精品亚洲午夜一区二区三区 | 久久精品国产99国产| 精品国精品自拍自在线| 99国产精品久久久久久久| 六月丁香婷婷色狠狠久久| 国产亚洲精品aa| 一道本成人在线| 欧美高清一区| 琪琪久久久久日韩精品| 久久免费偷拍视频| 久久国产精品一区二区三区四区 | 91色视频在线| 亚洲国产日韩精品| 欧美日韩在线观看一区二区| 欧美一区二区三区在线播放 | 亚洲欧洲一区二区在线播放| 久久综合一区| 不卡视频免费播放| 亚洲bt欧美bt精品| 久久这里只有精品6| 亚洲成人直播| 国产成人综合亚洲91猫咪| 专区另类欧美日韩| 欧美精品xxxxbbbb| 亚洲国产一区在线| 国产盗摄精品一区二区三区在线| 亚洲男人电影天堂| 欧美一区日本一区韩国一区| 亚洲精品婷婷| 国产精品18久久久久| 亚洲精品视频在线观看网站| 欧美一级一区二区| 亚洲一区网站| 午夜久久99| 国产一区二区精品久久| 亚洲美女少妇撒尿| 久久综合狠狠综合久久综合88| 久久激情中文| 极品av少妇一区二区| 国产成人精品一区二区三区网站观看| 亚洲一级二级三级| 国产日本亚洲高清| 欧美日产在线观看| 免费在线亚洲| 国内精品久久国产| 国产成人三级在线观看| 亚瑟在线精品视频| 国产精品日日摸夜夜摸av| 日韩一级高清毛片| 91福利在线看| 国产精品免费看| 成人一级视频在线观看| 麻豆精品新av中文字幕| 一区二区三区四区高清精品免费观看| 精品91自产拍在线观看一区| 欧美在线不卡视频| 中文国产一区| 欧美精品18| 不卡av电影在线播放| 韩国精品主播一区二区在线观看| 国产日本欧洲亚洲| 精品免费日韩av| 欧美日高清视频| 日本韩国视频一区二区| 欧美午夜精品久久久久免费视| 高清不卡一二三区| 美女精品自拍一二三四| 亚洲亚洲精品在线观看| 日韩美女啊v在线免费观看| 久久免费视频一区| 欧美一级欧美三级| 欧美色偷偷大香| 久久久水蜜桃av免费网站| 夜久久久久久| 国产主播一区| 欧美jizzhd精品欧美巨大免费| 国产成人一区二区精品非洲| 美腿丝袜一区二区三区| 午夜精品久久久久久久99水蜜桃| 综合久久国产九一剧情麻豆| 国产欧美日韩在线观看| 精品欧美乱码久久久久久 | 日韩国产一二三区| 一区二区三区91| ●精品国产综合乱码久久久久| 欧美激情自拍偷拍| 国产亚洲一区二区三区四区| 日韩精品中文字幕一区二区三区| 国产精品免费丝袜| 中文字幕第一区第二区| 国产午夜精品美女毛片视频| 欧美成人一区二区三区在线观看| 3751色影院一区二区三区| 欧美午夜精品一区二区三区| 在线观看区一区二| 在线精品观看国产| 在线观看视频一区| 欧美在线色视频| 欧美电影一区二区| 欧美日本高清视频在线观看| 欧美日韩日本视频| 欧美精品v日韩精品v韩国精品v| 欧美久久一二三四区| 欧美精品日日鲁夜夜添| 欧美丰满一区二区免费视频| 欧美精品在线观看播放| 717成人午夜免费福利电影| 欧美日韩国产一级| 这里只有精品免费| 欧美成人一区二区| 国产亚洲综合色| 亚洲欧洲在线观看av| 玉米视频成人免费看| 亚洲午夜久久久久久久久久久| 亚洲成人一二三| 日本美女一区二区| 九色综合国产一区二区三区| 看电影不卡的网站| 国产一区二区三区免费| 国产91丝袜在线观看| 91免费在线视频观看| 激情亚洲成人| 国产精品日韩二区| 欧美最猛性xxxxx直播| 欧美喷潮久久久xxxxx| 欧美成人一区二区三区在线观看| 国产日韩欧美高清| 亚洲欧美日韩国产中文在线| 性做久久久久久免费观看| 久久精品国产秦先生| 99热在这里有精品免费| 欧美婷婷久久| 噜噜噜91成人网|