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

适配器模式缺点(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)

相关代码
    推荐阅读
  • 武林外传白展堂被冤枉第几集(武林外传删减剧情曝光)

    观众们则是在第四面墙的位置,观看这出情景喜剧。于是,白展堂凭借自己的身手,挟持住导演,要其拿出解药,治好同福众人的疯病。甚至直言要把沙溢辞了,让其来演白展堂。白展堂则不耐烦,掐住导演,问其为何让李大嘴怀孕。此人认为,对付白展堂这种精神病人,最好是按照他的思路走下去。在拍戏时,沙溢明显心不在焉,被导演怒斥。只有死亡,才能反抗所谓的剧本。连扇几巴掌后,白展堂放弃自杀的念头,这才恢复了对自己身体的控制。

  • 女人取什么名字财运好(女孩招财的名字推荐)

    下面内容希望能帮助到你,我们来一起看看吧!金媛“金”字既能作为姓氏也可以用作名字里,代表着高贵、财运好的意思,而“媛”常用作女孩名字里指为温柔、有气质的意思。晓元“晓”字常指为晓得、明白的意思,后来用作人名为美丽、大方的意思,而“元”在古时经常是元宝的意思,代表着金钱。

  • 吃什么头发长得快又密 吃什么头发长得快又密又多

    补充植物蛋白脱发者的头发中氮氨酸、胱氨酸明显减少。因此,患者应多吃大豆、黑芝麻、玉米等富含蛋氨酸、胱氨酸的食品。所以要少吃肝类、肉类等食品,因这些食品中的酸性物质容易引起酸毒素过多。蔬菜和水果是碱性食物,能中和酸性毒素,可以适当多吃。补碘女性头发的光泽与甲状腺的作用有关,补碘能增强甲状腺的功能,有利于头发健美。脱发女性可多吃海带、紫菜、牡蛎等食品。

  • 内马尔跟姆巴佩为什么闹掰了(姆巴佩诚恳发言引热议)

    关于姆巴佩和内马尔之间的矛盾,从上赛季就关注大巴黎的球迷应该都明白。而到了本赛季姆巴佩获得了顶级合约成为了大巴黎老大之后,更是公开希望俱乐部能够清洗掉内马尔。至少在这个赛季下半段,姆巴佩还是想要好好的和内马尔合作搭档,两人一起带领大巴黎在欧冠上取得好成绩。但前提是在拜仁的第二轮欧冠比赛中两人需要及时复出带队取胜。

  • 防溺水条幅内容(防溺水条幅标语)

    下面更多详细答案一起来看看吧!防溺水条幅内容严密防范,坚决遏制学生溺水事故发生。强化教育,增强青少年儿童的安全意识。加强领导,切实落实预防溺水安全措施。生命只有一次,安全伴君一生。生命仅一次,水火无情谊。强化安全教育,防止溺水事件发生。珍爱生命,坚决不下水游泳。关爱生命旅程,预防溺水,注意交通安全。如果你想变成死鱼一条,就请在此处下水。

  • 女儿哭着不想上幼儿园(孩子哭着说不想去幼儿园)

    鼓励学生说出在学校遇到的不开心的事,并及时给学生做心理疏导,如果学生在学校被欺负,学生家长要想办法让他们表达出来,这样学生家长才能知道如何疏导学生,避免学生以后对上学产生厌烦的心理。如果发现学生不适合这所学校,及时为学生更换学校,这种事情学生家长最好不要犹豫,换一个环境,给学生带来的伤害会更小。

  • 成为产品经理之前的那些事(产品经理成长的)

    而对应的成本线则是“交付可用产品”。如果我们把产品质量分为“可用、好用、易用”,那“可用”就是最低要求。所以,满足“可用”要求的产品,至少要保证合理的流程设计、严谨的信息架构、满足基本体验的交互设计以及完整的功能结构。

  • 张翰和古力娜扎一路坎坷(古力娜扎张翰分手)

    就像当年以国外街头一吻高调宣布恋情一样,古力娜扎和张翰今天由双方工作室出面,宣布已于今年10月中旬和平分手。古力娜扎和张翰作为事业正处于上升期的男女明星,双方各自对自己的事业有追求,今年,二人皆在娱乐圈交出了不错的成绩单。对于二人的决定,古力娜扎的粉丝们率先表态:艺人,只是娜扎的职业,并不是她人生的全部。

  • 亚马逊品牌备案需要什么(关于亚马逊品牌备案相关卖家常见问题答疑)

    关于亚马逊品牌备案相关卖家常见问题答疑最近有不少卖家在询问关于品牌备案相关的问题,我们今天就整理了卖家关心的关于品牌备案的相关问题那么卖家问到的问题是什么呢?情况分析:卖家的名字是A,拥有品牌B1,B2,两个品牌,都是用法人名字进行注册的。

  • 桃胶泡多久才能煮 桃胶泡多久才能煮熟

    桃胶泡多久才能煮建议最少泡12个小时最好。女性吃桃胶有什么好处美容养颜桃胶中含有大量的植物胶原蛋白以及维生素,这些物质具有很好的防衰老作用,适量食用可以是人体皮肤细嫩有光泽,女性食用之后具有一定美容养颜的作用。降血糖桃胶中含有大量的不饱和脂肪酸、多糖等营养成分,其中不饱和脂肪酸与多糖中的单糖具有很好的控制人体血糖的作用,女性适量食用具有一定降血糖作用。