使用适配器模式将异构系统同构化
2022/1/26 23:34:49
本文主要是介绍使用适配器模式将异构系统同构化,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
使用适配器模式将异构系统同构化
- 需求
- 用户模块现状
- 用户服务接口、实现以及我们自己的用户对象
- 客户新提供的用户接口以及用户对象
- 思考
- 改造
- 测试
- 适配器模式
- 总结
适配器模式是一个我们会在不知不觉间使用的模式。
需求
假设本来我们的系统运行良好,已经上线。同时,我们的系统中包含了一个用户模块,可以用来查询用户。项目上线一段时间后,客户要求我们将用户系统对接到客户提供的用户系统上…这,怎么办呢?
用户模块现状
用户服务接口、实现以及我们自己的用户对象
- 用户服务接口:
/** * 用户查询Service * @author skyline */ public interface IUserService { /** * 通过用户名查询用户 * @param name * @return */ UserDTO getByName(String name); /** * 展示所有用户 * @return */ List<UserDTO> listAll(); }
- 我们自己的用户服务的实现
/** * 我的用户服务 */ public class MyUserService implements IUserService{ private final Map<String,UserDTO> userDTOMap; public MyUserService(){ userDTOMap = new HashMap<>(); init(); } private void init() { UserDTO zhangsan = new UserDTO(); zhangsan.setAge(18); zhangsan.setDept("部门A"); zhangsan.setName("zhangsan"); userDTOMap.put("zhangsan", zhangsan); UserDTO lisi = new UserDTO(); lisi.setAge(19); lisi.setDept("部门B"); lisi.setName("lisi"); userDTOMap.put("lisi", lisi); UserDTO wangwu = new UserDTO(); wangwu.setAge(20); wangwu.setDept("部门A"); wangwu.setName("wangwu"); userDTOMap.put("wangwu", wangwu); } @Override public UserDTO getByName(String name) { return userDTOMap.get(name); } @Override public List<UserDTO> listAll() { return new ArrayList<>(userDTOMap.values()); } }
- 我们自己的用户对象
/** * 用户对象 */ public class UserDTO { private String name; private Integer age; private String dept; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getDept() { return dept; } public void setDept(String dept) { this.dept = dept; } @Override public String toString() { return "UserDTO{" + "name='" + name + '\'' + ", age=" + age + ", dept='" + dept + '\'' + '}'; } }
客户新提供的用户接口以及用户对象
- 用户新提供的用户服务
/** * 假设这是来自OA sdk的一个类 * @author skyline */ public class OAUserService { private final Map<String,OAUserDTO> userDTOMap; public OAUserService() { userDTOMap = new HashMap<>(); init(); } private void init() { OAUserDTO zhangsan = new OAUserDTO(); zhangsan.setAge(18); zhangsan.setDeptName("部门A"); zhangsan.setLoginName("zhangsan"); userDTOMap.put("zhangsan",zhangsan); OAUserDTO lisi = new OAUserDTO(); lisi.setAge(19); lisi.setDeptName("部门B"); lisi.setLoginName("lisi"); userDTOMap.put("lisi",lisi); OAUserDTO wangwu = new OAUserDTO(); wangwu.setAge(20); wangwu.setDeptName("部门A"); wangwu.setLoginName("wangwu"); userDTOMap.put("wangwu",wangwu); } public OAUserDTO queryUser(String userName){ return userDTOMap.get(userName); } public List<OAUserDTO> getAllUser(){ return new ArrayList<>(userDTOMap.values()); } }
- 客户新提供的用户对象
/** * OA用户对象 */ public class OAUserDTO { private String loginName; private Integer age; private String deptName; public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
思考
- 这个需求虽然只是改造用户模块,但是由于用户模块会被各种其他模块调用,如果直接将
UserDTO
以及IUserService
都替换掉,那将会是一个影响巨大的改造,同时将引入极大的不确定性。 - 基于上面的考虑,我们需要尽可能的复用
UserDTO
和IUserService
- 写一个新的
IUserService
的实现,来调用客户提供的用户接口OAUserService
- 将用户提供的用户对象
OAUserDTO
想办法转换成UserDTO
改造
提供一个类,将IUserService
、UserDTO
、OAUserService
以及OAUserDTO
关联起来。
/** * OA用户服务适配器 * @author skyline */ public class OAUserServiceAdapter implements IUserService{ private final OAUserService oaUserService; public OAUserServiceAdapter() { oaUserService = new OAUserService(); } @Override public UserDTO getByName(String name) { OAUserDTO oaUserDTO = oaUserService.queryUser(name); return convert(oaUserDTO); } private UserDTO convert(OAUserDTO oaUserDTO) { UserDTO userDTO = new UserDTO(); userDTO.setName(oaUserDTO.getLoginName()); userDTO.setDept(oaUserDTO.getDeptName()); userDTO.setAge(oaUserDTO.getAge()); return userDTO; } @Override public List<UserDTO> listAll() { List<OAUserDTO> allUser = oaUserService.getAllUser(); return allUser.stream().map(this::convert).collect(Collectors.toList()); } }
在上面的改造中,OAUserServiceAdapter
实现了IUserService
接口,但是内部的业务逻辑委托给OAUserService
处理,当OAUserService
处理完毕后,再通过convert
方法将OAUserDTO
转换成UserDTO
。这样,只要IUserService
在实例化时使用OAUserServiceAdapter
的实例,系统的用户模块就可以无缝迁移到客户提供的新模块上。
测试
一开始的时候,系统使用内置的用户模块:
改造完毕后,系统使用客户提供的新模块,但是业务代码却不需要做调整:
适配器模式
适配器模式是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
总结
- 适配器模式分为类适配器和对象适配器,上面的列子中这两种适配器思想都得到了体现。
- 适配器模式满足开闭原则,代码改造量小,同时相当灵活。
- 过多的使用适配器容易导致系统复杂度上升,同时对象适配器也容易产生非常多的零散对象。
- 如果可能的话,从长远来看,适当的对整体系统重构要好于使用适配器模式。
这篇关于使用适配器模式将异构系统同构化的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南