科百科
当前位置: 首页 科技资讯

适配器模式缺点(05.设计模式之适配器模式)

时间:2023-05-21 作者: 小编 阅读量: 3 栏目名: 科技资讯

适配器模式的思想是:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。适配器模式包括3种形式:类适配器模式、对象适配器模式、接口适配器模式。

适配器模式缺点?1.什么是适配器? 2.适配器设计原理 3.springmvc 、mybatis哪些场景使用到适配器? 4.企业级多api版本如何采用适配器重构,我来为大家科普一下关于适配器模式缺点?下面希望有你要的答案,我们一起来看看吧!

适配器模式缺点

1.什么是适配器? 2.适配器设计原理 3.springmvc 、mybatis哪些场景使用到适配器? 4.企业级多api版本如何采用适配器重构

什么是适配器

1.适配器模式是一种结构型设计模式。适配器模式的思想是:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

苹果手机是否可以插入 圆孔耳机,(圆孔)转接头(接入苹果口子)

2.用电器来打个比喻:有一个电器的插头是三脚的,而现有的插座是两孔的,要使插头插上插座,我们需要一个插头转换器,这个转换器即是适配器。

3.适配器模式涉及3个角色:

源(Adaptee):需要被适配的对象或类型,相当于插头。

适配器(Adapter):连接目标和源的中间对象,相当于插头转换器。

目标(Target):期待得到的目标,相当于插座。

适配器模式包括3种形式:类适配器模式、对象适配器模式、接口适配器模式(或又称作缺省适配器模式)。

适配器模式原理图适配器模式应用场景

1.springmvc多个不同controller实现;

2.API多版本控制;

适用场景

  1. 系统需要使用现有的类,而这些类的接口不符合系统的接口。
  2. \2. 想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
  3. 3.类所做的事情相同或相似,但是具有不同接口的时候。

 4.旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但我们不希望手动更改原有类的时候。

 5.使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。

springmvc适配器原理分析

方式一:@Controller/@RequestMapping

方式二:实现HttpRequestHandler接口

方式三:实现Controller接口

适配器模式就是把一个类的接口替换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

springmvc 定义controller方式方式一:

package com.mayikt.controller;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ @RestController public class MayiktController {/*** 访问mayikt** @return*/@RequestMapping("/getMayikt")public String getMayikt() {return "mayikt";} }

方式二:

package com.mayikt.controller;import org.springframework.stereotype.Component; import org.springframework.web.HttpRequestHandler;import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ @Component("/mayiktHttpRequestHandler") public class MayiktHttpRequestHandler implements HttpRequestHandler {@Overridepublic void handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {PrintWriter writer = httpServletResponse.getWriter();writer.print("mayiktHttpRequestHandler");writer.close();} }

方式三:

package com.mayikt.controller;import org.springframework.stereotype.Component; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import org.springframework.web.servlet.view.json.MappingJackson2JsonView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.util.HashMap;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ @Component("/implController") public class MayiktImplController implements Controller {@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {PrintWriter writer = response.getWriter();writer.print("mayikt--MayiktImplController");writer.close();return null;} }

springmvc适配器原理分析

源码解读:

1.springmvc接受请求入口 servlet DispatcherServlet

三种不同方式定义url映射?

用户选择方式2

方式1:

方式2:

方式3:

如何调试源码呢?idea版本

由于Controller的类型不同,有多重实现方式,那么调用方式就不是确定的,如果需要直接调用Controller方法,需要在代码中写成如下形式

package com.mayikt.adapter;import com.mayikt.adapter.impl.AnnotationController; import com.mayikt.adapter.impl.ImplController; import com.mayikt.adapter.impl.RequestHandlerController;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ public class AdapterInvok {public static void invok(Controller controller) {if (controller instanceof AnnotationController) {AnnotationController annotationController = (AnnotationController) controller;annotationController.requestMapping();return;}if (controller instanceof ImplController) {ImplController implController = (ImplController) controller;implController.handleRequest();}if (controller instanceof RequestHandlerController) {RequestHandlerController requestHandlerController = (RequestHandlerController) controller;requestHandlerController.requestHandler();}}public static void main(String[] args) {AdapterInvok.invok(new ImplController());} }

如果是这样写代码的话, 后期增加了一种controller的实现方式的话,我们就需要在方法中增加一个if else,这种形式就使得代码非常不好维护,并且也违反了设计模式中的开闭原则。

因此SpringMVC中 定义了一个适配器接口,使得每一种controller都对应一个 适配器类,让适配器代替controller执行对应的方法,这样我们在扩展controller的时候,只需要增加一个对应的适配器类就可以了。

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {if (this.handlerAdapters != null) {for (HandlerAdapter adapter : this.handlerAdapters) {if (adapter.supports(handler)) {return adapter;}}}throw new ServletException("No adapter for handler ["handler"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }

核心组件

1.目标接口(Target):客户端所期待的接口,目标可以使具体的或抽象类, 也可以是接口

2.需要适配的类(Adaptee):需要适配的类或者适配者类

3.适配器(Adapter):通过包装一个需要适配的对象,把原有接口转换成目标接口

模拟springmvc 不同controller实现目标接口(Target)

package com.mayikt.adapter.controller;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ public interface Controller {}

需要适配的类(Adaptee)

package com.mayikt.adapter.controller.impl;import com.mayikt.adapter.controller.Controller; import lombok.extern.slf4j.Slf4j;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ @Slf4j public class AnnotationController implements Controller {public String requestMapping() {log.info("<使用注解@Controller>");return "ok";} }package com.mayikt.adapter.controller.impl;import com.mayikt.adapter.controller.Controller; import lombok.extern.slf4j.Slf4j;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ @Slf4j public class ImplController implements Controller {public void handleRequest() {log.info("<handleRequest>");} }package com.mayikt.adapter.controller.impl;import com.mayikt.adapter.controller.Controller; import lombok.extern.slf4j.Slf4j;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ @Slf4j public class RequestHandlerController implements Controller {public void requestHandler() {log.info("<requestHandler>");} }

适配器(Adapter)

package com.mayikt.adapter;/*** @author songchuanfu* @qq 1802284273* 微信:wx-suagcf*/public interface HandlerAdapter {boolean supports(Object controller);/*** 调用到具体的方法** @param handler*/void handle(Object handler);}package com.mayikt.adapter.impl;import com.mayikt.adapter.HandlerAdapter;import com.mayikt.adapter.controller.impl.AnnotationController;import com.mayikt.adapter.controller.impl.RequestHandlerController;/*** @author songchuanfu* @qq 1802284273* 微信:wx-suagcf*/public class RequestHandlerAdapter implements HandlerAdapter {@Overridepublic boolean supports(Object controller) {return controller instanceof RequestHandlerController;}@Overridepublic void handle(Object handler) {RequestHandlerController requestHandlerController = (RequestHandlerController) handler;requestHandlerController.requestHandler();}}package com.mayikt.adapter.impl;import com.mayikt.adapter.HandlerAdapter;import com.mayikt.adapter.controller.impl.ImplController;import com.mayikt.adapter.controller.impl.RequestHandlerController;/*** @author songchuanfu* @qq 1802284273* 微信:wx-suagcf*/public class ImplHandlerAdapter implements HandlerAdapter {@Overridepublic boolean supports(Object controller) {return controller instanceof ImplController;}@Overridepublic void handle(Object handler) {ImplController implController = (ImplController) handler;implController.handleRequest();}}package com.mayikt.adapter.impl;import com.mayikt.adapter.HandlerAdapter;import com.mayikt.adapter.controller.impl.AnnotationController;/*** @author songchuanfu* @qq 1802284273* 微信:wx-suagcf*/public class AnnotationHandlerAdapter implements HandlerAdapter {@Overridepublic boolean supports(Object controller) {return controller instanceof AnnotationController;}@Overridepublic void handle(Object handler) {AnnotationController annotationController = (AnnotationController) handler;annotationController.requestMapping();}}package com.mayikt.adapter;import com.mayikt.adapter.controller.Controller;import com.mayikt.adapter.controller.impl.AnnotationController;import com.mayikt.adapter.controller.impl.ImplController;import com.mayikt.adapter.impl.AnnotationHandlerAdapter;import com.mayikt.adapter.impl.ImplHandlerAdapter;import com.mayikt.adapter.impl.RequestHandlerAdapter;import java.lang.annotation.Annotation;import java.util.ArrayList;import java.util.List;/*** @author songchuanfu* @qq 1802284273* 微信:wx-suagcf*/public class DispatchServlet {private List<HandlerAdapter> handlerAdapters = new ArrayList<>();public DispatchServlet() {handlerAdapters.add(new AnnotationHandlerAdapter());handlerAdapters.add(new ImplHandlerAdapter());handlerAdapters.add(new RequestHandlerAdapter());}public void doDispatch() {AnnotationController implController = new AnnotationController();HandlerAdapter handlerAdapter = getHandler(implController);if (handlerAdapter == null) {return;}handlerAdapter.handle(implController);}public HandlerAdapter getHandler(Controller controller) {for (HandlerAdapter handlerAdapter :handlerAdapters) {if (handlerAdapter.supports(controller)) {return handlerAdapter;}}return null;}public static void main(String[] args) {new DispatchServlet().doDispatch();}}

模拟api多版本控制

企业中编写了开放接口 MayiktServiceV1. addUser(String userName);

企业中编写了开放接口 MayiktServiceV2. addUserJson(User user);

if("1"==v){

MayiktServiceV1. addUser(String userName);

return ;

}

if("2"==v){

MayiktServiceV2. addUserJson(User user);

return ;

}

if("3"==v){

MayiktServiceV2. addUserJson(User user);

return ;

}

package com.mayikt.adapter2;import lombok.extern.slf4j.Slf4j;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */@Slf4j public class MayiktApiServiceV1 {public String addUser(String userName, Integer age) {log.info("<v1版本>");return "ok";} }package com.mayikt.adapter2;import lombok.extern.slf4j.Slf4j;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ @Slf4j public class MayiktApiServiceV2 {public String addUserObject(MayiktUserEntity mayiktUserEntity) {log.info("<v2版本>");return "ok";} }package com.mayikt.adapter2;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ public class MayiktUserEntity {private String userName;private Integer age;public MayiktUserEntity(String userName, Integer age) {this.userName = userName;this.age = age;} }package com.mayikt.adapter2;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ public interface MayiktApiAdapter {boolean supports(Object api);void invok(Object api); }package com.mayikt.adapter2.impl;import com.mayikt.adapter2.MayiktApiAdapter; import com.mayikt.adapter2.MayiktApiServiceV1; import com.mayikt.adapter2.MayiktApiServiceV2; import com.mayikt.adapter2.MayiktUserEntity;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ public class ApiV2Adapter implements MayiktApiAdapter {@Overridepublic boolean supports(Object api) {return api instanceof MayiktApiServiceV2;}@Overridepublic void invok(Object api) {MayiktApiServiceV2 mayiktApiServiceV2 = (MayiktApiServiceV2) api;mayiktApiServiceV2.addUserObject(new MayiktUserEntity("mayikt", 22));} }package com.mayikt.adapter2.impl;import com.mayikt.adapter2.MayiktApiAdapter; import com.mayikt.adapter2.MayiktApiServiceV1;/** * @author songchuanfu * @qq 1802284273 * 微信:wx-suagcf */ public class ApiV1Adapter implements MayiktApiAdapter {@Overridepublic boolean supports(Object api) {return api instanceof MayiktApiServiceV1;}@Overridepublic void invok(Object api) {MayiktApiServiceV1 mayiktApiServiceV1 = (MayiktApiServiceV1) api;mayiktApiServiceV1.addUser("mayikt", 22);} }

适配器优缺点

优点

更好的复用性:系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。

更好的扩展性:在实现适配器功能的时候,可以扩展自己源的行为(增加方法),从而自然地扩展系统的功能。

缺点

会导致系统紊乱:滥用适配器,会让系统变得非常零乱。例如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。

[

](https://blog.csdn.net/weixin_44688301/article/details/115748540)

相关代码
    推荐阅读
  • 唐三重生最后成神了没(举贤不避亲的唐三重生后)

    终极斗罗最后一册的内容已经更新完毕,小舞陨落后,唐三选择了转世重生。虽然终极斗罗30册并没有交代唐三重生的细节,但是唐三在临走前却交代了诸多事宜给后代和其他神界领导者。为了让自己的儿子和儿媳继承毁灭神王和生命神王的神位,他提出了举贤不避亲。况且二人还是夫妻,唐三将神位传给他们也算是没有辜负毁灭之神和生命女神的嘱托。因此个人以为,唐三并不会将修罗神和海神的神位让给他人继承,而是会留给小舞和自己。

  • 部编四年级语文上册21课古诗三首(部编版四年级语文上册古诗三首课文解析)

    《古诗三首》收录在人教四年级语文上册教材,需要掌握:19个汉字。明确学习目标1、有感情地朗读课文,背诵课文,默写《题西林壁》。与其父苏洵、其弟苏辙并称“三苏”。梅花和雪花相互竞争,都认为自己是最具早春特色的,而且互不认输,这就将早春的梅花与雪花之美别出心裁、生动活泼地表现出来了。

  • 高一语文必修二知识梳理(高一语文必修二知识点整理)

    1945年在苏门达腊被日寇杀害,1952年被中央人民政府追认为革命烈士。1921年第一部小说集《沉沦》问世,1923年《春风沉醉的晚上》、《薄奠》。著有散文集《海星》《竹刀》《囚绿记》等,译著有《罗亭》《鲁宾逊漂流记》等。开创了我国古代诗歌的现实主义创作传统。②相当于“而”。⑤为,成为,引申为充当,充作。引申为承担,承受。

  • 赛鲸电脑桌怎么样(赛鲸床上电脑桌使用感受)

    赛鲸在设计方面与德国Patzak,spinn等多家设计学院合作,设计追求完美,在结构和工艺方面获得多项专利。赛鲸电脑桌设计的三大特点是超易用、超耐用、超稳固。赛鲸电脑桌一个动作完成桌面角度调节。德国设计的支架结构,采用轻钢架。靠结构控制力度和状态,赛鲸电脑桌的耐用性增强。

  • 最强蜗牛吃蘑菇任务攻略(蘑菇有多少种)

    最强蜗牛吃蘑菇任务攻略获得蘑菇的方法:蘑菇宝箱,蘑菇园,每日任务,馆长的头盔,地球晚宴转盘,解锁蜗牛壳,白蝌蚪礼包,氪金礼包。每食用一定数量后可额外增加食盒容量。生命蘑菇,食用后可额外获得四维加成。

  • 啵乐乐韩国进口饮料(韩国进口啵乐乐饮料新品)

    九日冰祖食品出品的啵乐乐牛奶盒装含乳饮料目前已获得啵乐乐品牌正版授权,由山东冰祖食品股份有限公司独家代理。当然,除了可爱爆棚的卡通形象,更重要的是啵乐乐饮料的优异品质。除此之外,啵乐乐牛奶含乳饮料富含人体所需要的各种营养,同时富含维生素A、维生素B1等多种元素。啵乐乐大牌饮品,线下线上均有售目前,啵乐乐牛奶含乳饮料已经问鼎各大市场渠道,备受年轻消费者喜爱。

  • 病毒感染可以引起贫血(这种细菌感染会引发贫血等血液病)

    相关研究表明,幽门螺旋杆菌与某些血液疾病的发生是密切相关的,比如说不明原因的缺铁性贫血。我们说贫血的患者啊,有幽门螺旋杆菌的患者感染率明显高于未感染的患者。再有就是许多研究发现,根除幽门螺旋杆菌后特发性血小板减少性紫癜患者的血小板数会明显增多,并伴随血清血小板抗体,IgG水平的下降,幽门螺旋杆菌可能是部分特发性或者是原发性血小板减少症的这种疾病的致病因素之一。

  • 很甜的小短句(36句微信超火的情话短句)

    36句微信超火的情话短句❤️想牵着你的手给各位来宾敬酒❤️我什么都知道但还是想听你娓娓道来❤️我家的狗挺喜欢你的随我❤️你主动找我的时候我激动的都能做完整套广播体操❤️你是我最爱的宝贝给我甜甜的草莓牛奶也不换❤️不许说我嘴硬。

  • 一年级家长每天需要做什么(一年级家长开学最该做什么)

    就拿小学一年级新生来说,一部分是学区或摇号或其它渠道进了心仪的学校,遂了愿,满心欢喜;一部分是各种原因找找拖拖不情愿进了备份学校,心不甘,心绪惆怅。孩子学习成绩的好坏大多数来自家长的教与养,家长对孩子的教养跟上,孩子会很好。还有就是一定要记得我们上学的目的是什么,让孩子喜欢学习,学会学习,最终学有所成,这才是重中之重,是核心。所以家长在孩子成长上学会抓重点,才能保证孩子的教育正确。

  • 少儿春晚嘉年华演出(2023嘉佳卡通华夏少年少儿春晚特邀小主持人刘思琳)

    活动以权威性、广泛性为原则,旨在向全省范围内选拔具有优秀潜质的未来之星,具有积极向上风貌的儿童优秀节目和演员,最终登上《华夏少年》少儿春节联欢晚会的舞台,通过嘉佳卡通卫视的播出展示给全国人民。哈喽大拇指语言艺术特邀优秀小主持人刘思琳同学,经过严格选拔,入选嘉佳卡通《华夏少年》少儿春节联欢晚会的主持人。据悉,嘉佳卡通卫视《华夏少年》少儿春节联欢晚会将于2023年1月21日播出。