经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
大话设计模式笔记(十四)の适配器模式
来源:cnblogs  作者:callmeDevil  时间:2019/8/5 10:13:11  对本文有异议

举个栗子

问题描述

不同国家的人在NBA打球,但都是用英文交流。

简单实现

Player

  1. /**
  2. * 球员
  3. * Created by callmeDevil on 2019/8/4.
  4. */
  5. public abstract class Player {
  6. protected String name;
  7. public Player(String name){
  8. this.name = name;
  9. }
  10. // 发起进攻
  11. public abstract void attack();
  12. // 转回防守
  13. public abstract void defense();
  14. }

Forwards

  1. /**
  2. * 前锋
  3. * Created by callmeDevil on 2019/8/4.
  4. */
  5. public class Forwards extends Player {
  6. public Forwards(String name){
  7. super(name);
  8. }
  9. @Override
  10. public void attack() {
  11. System.out.println(String.format("前锋 %s 进攻", name));
  12. }
  13. @Override
  14. public void defense() {
  15. System.out.println(String.format("前锋 %s 防守", name));
  16. }
  17. }

Center

  1. /**
  2. * 中锋
  3. * Created by callmeDevil on 2019/8/4.
  4. */
  5. public class Center extends Player {
  6. // 代码与前锋相似
  7. }

Guards

  1. /**
  2. * 后卫
  3. * Created by callmeDevil on 2019/8/4.
  4. */
  5. public class Guards extends Player {
  6. // 代码与前锋相似
  7. }

测试

  1. public class Test {
  2. public static void main(String[] args) {
  3. Player b = new Forwards("巴蒂尔");
  4. b.attack();
  5. Player m = new Guards("麦克格雷迪");
  6. m.attack();
  7. Player ym = new Center("姚明");
  8. // 姚明问:attack 和 defense 是什么意思?
  9. ym.attack();
  10. ym.defense();
  11. }
  12. }

测试结果

  1. 前锋 巴蒂尔 进攻
  2. 后卫 麦克格雷迪 进攻
  3. 中锋 姚明 进攻
  4. 中锋 姚明 防守

存在问题

姚明刚到NBA时可能英文还不太好,也就是说听不懂教练的战术安排,attach 和 defense 不知道什么意思,因此这样实现会有问题,需要一个中英翻译。

适配器模式

定义

将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

分类

主要分为类适配器模式对象适配器模式。由于类适配器模式通过多重继承对一个接口与另一个接口进行匹配,而 Java 等语言不支持多重继承,也就是一个类只有一个父类,所以这里主要讲的是对象适配器

UML图

代码实现

ForeignCenter

  1. /**
  2. * 外籍中锋
  3. * Created by callmeDevil on 2019/8/4.
  4. */
  5. public class ForeignCenter {
  6. // 外籍中锋球员的姓名故意用属性而不是构造方法来区别与三个球员的不同
  7. private String name;
  8. // 表明外籍中锋只懂中文“进攻”(注意:举例效果,实际上千万别用这种方式编程)
  9. public void 进攻(){
  10. System.out.println(String.format("外籍中锋 %s 进攻", name));
  11. }
  12. // 表明外籍中锋只懂中文“防守”(注意:举例效果,实际上千万别用这种方式编程)
  13. public void 防守(){
  14. System.out.println(String.format("外籍中锋 %s 防守", name));
  15. }
  16. public String getName() {
  17. return name;
  18. }
  19. public void setName(String name) {
  20. this.name = name;
  21. }
  22. }

Translator

  1. /**
  2. * 翻译者
  3. * Created by callmeDevil on 2019/8/4.
  4. */
  5. public class Translator extends Player{
  6. // 声明并实例化一个内部“外籍中锋”对象,表明翻译者与外籍球员有关联
  7. private ForeignCenter wjzf = new ForeignCenter();
  8. public Translator(String name){
  9. super(name);
  10. wjzf.setName(name);
  11. }
  12. @Override
  13. public void attack() {
  14. // 翻译者将“attack”翻译为“进攻”告诉外籍中锋
  15. wjzf.进攻();
  16. }
  17. @Override
  18. public void defense() {
  19. // 翻译者将“defense”翻译为“防守”告诉外籍中锋
  20. wjzf.防守();
  21. }
  22. }

测试

  1. public class Test {
  2. public static void main(String[] args) {
  3. Player b = new Forwards("巴蒂尔");
  4. b.attack();
  5. Player m = new Guards("麦克格雷迪");
  6. m.attack();
  7. Player ym = new Translator("姚明");
  8. // 翻译者告诉姚明,教练要求你既要“进攻”又要“防守”
  9. ym.attack();
  10. ym.defense();
  11. }
  12. }

测试结果

  1. 前锋 巴蒂尔 进攻
  2. 后卫 麦克格雷迪 进攻
  3. 外籍中锋 姚明 进攻
  4. 外籍中锋 姚明 防守

总结

  • 系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配。
  • 适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
  • 使用已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。
  • 两个类所做的事情相同或相似,但是具有不同的接口时要使用它。
  • 客户代码可以统一调用同一接口就行了,这样可以更简单、直接、紧凑。
  • 在双方都不太容易修改的时候再使用适配器模式适配。

原文链接:http://www.cnblogs.com/call-me-devil/p/11298653.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号