首页 > 编程知识 正文

适配器模式和策略模式区别,flume适配器设计

时间:2023-05-04 08:54:04 阅读:136725 作者:237

适配器模式APP场景第三方登录-单适配器第三方登录-在各种设计模式适配器模式的源代码中找到

应用场景

适配器模式一般是在软件的出厂阶段出现的模式,为了与不同的类兼容,制作了与数据线转换头等概念相似的接口,命名一般为xxxx适配器。

例如,我们常见的第三方登录,在系统最初设计时,也许只需要用户名和密码就可以登录。 后来,随着qq、微信、手机登录的普及,登录方式也变多了。 此时,需要适配器模式。 在不改变原始登录逻辑的情况下,与新的第三方登录进行匹配。

第三方登录-单个适配器。让我们来看看第一阶段的代码。 没有第三方登录时的原始实现逻辑如下

/** *系统的原始登录逻辑*/public class SiginService { /** *注册*/publicresultmsgregist (string username,String password ) member.setpassword(password; returnnewresultmsg(200,“注册成功”,member ); (/)登录(/publicresultmsglogin (string username,String password ) ) /用户名密码正确的Member member=new Member ) member.setpassword(password; returnnewresultmsg(200,“登录成功”,member ); }} /** *用户* /公共类成员{ privatestring username; 私有字符串密码; 公共字符串获取名称((return username ); } publicvoidsetusername (string username ) { this.username=username; }公共字符串获取密码() { return password; } publicvoidsetpassword (string password ) { this.password=password; }} /** *回复消息*/publicclassresultmsg { private int code; 私有字符串msg; 私有对象数据; publicresultmsg(intcode,String msg,Object data ),{ this.code=code; this.msg=msg; this.data=data; }公共获取代码() ) {返回代码; }publicvoidsetcode(intcode ) { this.code=code; }公共字符串getmsg () { return msg; }publicvoidsetmsg(stringmsg ) { this.msg=msg; }公共对象获取数据() { return data; }publicvoidsetdata(objectdata ) { this.data=data; }这里的三方匹配逻辑就是一个例子,在实际的实现中可能有几种方式。 例如,qq登录有qq许可证、扫描码、qq账户密码登录等几种方式。 具体实现可能通过token进行许可,也可能在绑定qq帐户时绑定雪花ID等,但重点在于设计模式的结构,而不是具体实现。 因此,现在,如果我们的业务目前有与第三方-QQ登录兼容的需求,则简单假设合适的逻辑,我们需要一个适配器

/** *第三方登录适配器*/publicclasssinginforthirdadapterextendssiginservice { publicresultmsgloginforqq (stringqname,ssqiname

d String userName = qqName + "qq"; String password = qqPassword + "qq"; // 2.0 调用原本的登录逻辑 return super.login(userName, password); }

其实适配器模式就是上面这么简单,单纯的适配器模式的话到这里已经够了。
但是实际业务场景中不会出现这么简单单一的需求,我们要考虑的全面一点,比如日后万一业务又需要支持微信怎么办、需要支持手机登录怎么办。所以往往是多种设计模式结合起来,灵活运用的。

第三方登录-多种设计模式

如果我们现在要支持微信、手机登录之类的,对上面的代码做如下这样的修改,也是可以用的。但是很显然违背了我们的开闭原则,不利于拓展,耦合性太高了

public class SinginForThirdAdapter extends SiginService { public ResultMsg loginForQQ(String qqName,String qqPassword) { // 1.0 假设QQ登录独有的适配逻辑,是通过qq账号密码得到userName和password String userName = qqName + "qq"; String password = qqPassword + "qq"; // 2.0 调用原本的登录逻辑 return super.login(userName, password); } public ResultMsg loginForWechat(String openId) { dosomething.... } public ResultMsg loginForTelphone(String telphone, String code) { dosomething.... }}

这里其实很容易想到另一个设计模式-策略模式,一个功能的实现对应多种策略,如果有通用的实现逻辑,我们还可以引入类似模板方法模式的概念,把策略模式的父类从接口变成抽象类。如果里面的对象创建逻辑略复杂可优化的话,还可以考虑单例模式(一般较少用到)、几种工厂模式(较多用到)、原型模式这些创建型模式。

/** * 结合策略模式、工厂模式、适配器模式 */public class PassportForThirdAdapter extends SiginService implements IPassportForThird { public ResultMsg loginForQQ(String id) { return processLogin(id,LoginForQQAdapter.class); } public ResultMsg loginForWechat(String id) { return processLogin(id,LoginForWechatAdapter.class); } public ResultMsg loginForTelphone(String telphone, String code) { return processLogin(telphone,LoginForTelAdapter.class); } private ResultMsg processLogin(String key,Class<? extends LoginAdapter> clazz){ try{ // 适配器不一定要实现接口 LoginAdapter adapter = clazz.newInstance(); // 判断传过来的适配器是否能处理指定的逻辑 if(adapter.support(adapter)){ return adapter.login(key,adapter); } }catch (Exception e){ e.printStackTrace(); } return null; }} /** * 方便拓展 */public interface IPassportForThird { /** * QQ登录 * @param id * @return */ ResultMsg loginForQQ(String id); /** * 微信登录 * @param id * @return */ ResultMsg loginForWechat(String id); /** * 手机号登录 * @param telphone * @param code * @return */ ResultMsg loginForTelphone(String telphone, String code);} /** * 在适配器里面,这个接口是可有可无,不要跟模板模式混淆 * 模板模式一定是抽象类,而这里仅仅只是一个接口 */public interface LoginAdapter { /** * 判断适配器是否适配 */ boolean support(Object adapter); ResultMsg login(String id,Object adapter);} /** * qq登录适配器 */public class LoginForQQAdapter implements LoginAdapter { public boolean support(Object adapter) { return adapter instanceof LoginForQQAdapter; } public ResultMsg login(String id, Object adapter) { // 1.0 QQ登录独有的适配逻辑 // 2.0 调用原本的登录逻辑 }} /** * 手机登录适配器 */public class LoginForTelAdapter implements LoginAdapter { public boolean support(Object adapter) { return adapter instanceof LoginForTelAdapter; } public ResultMsg login(String id, Object adapter) { return null; }} /** * 微信登录适配器 */public class LoginForWechatAdapter implements LoginAdapter { public boolean support(Object adapter) { return adapter instanceof LoginForWechatAdapter; } public ResultMsg login(String id, Object adapter) { return null; }}

当然,上面的结构还不是最佳的,随着我们具体逻辑的注入,可优化可调整的地方会更多,需要灵活一点。

适配器模式源码中的体现

其实只要在源码中找Adapter结尾的就好了…
比如前面学习委派模式的时候,DispatcherServlet中,就有使用到适配器模式的地方

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。