目录

一、装饰器模式

二、适配器模式

1、类适配器

2、对象适配器

3、适配器模式的优缺点


一、装饰器模式

特点:

  • 在不改变一个对象本身功能的基础上给对象增加新的功能,即功能增强;
  • 如Java IO中的BufferedReader类就是对InputStreamReader类的包装或增强。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

举例:

假如xx去4S店买了一款领克01,它拥有领克车系的所有基础功能,但01却没有LED大灯,因此花点钱可以加装一个。

Demo实现:

/**汽车接口(抽象角色) */
public interface Car {void getCarInfo();
}/** 领克01车型(具体角色) */
public class LynkCar implements Car{@Overridepublic void getCarInfo() {System.out.println("领克车子的基本功能都有了~~~");}
}/**加装LED大灯(装饰角色) */
public class LynkCarDecorate implements Car {// 通过构造器注入private LynkCar lynkCar;public LynkCarDecorate(LynkCar lynkCar) {this.lynkCar = lynkCar;}// 加装LED大灯方法public void addLedBulb() {System.out.println("OK,已加装LED大灯");}// 增强原汽车的功能@Overridepublic void getCarInfo() {System.out.println("给领克车子加个LED大灯吧~~~");this.addLedBulb();}
}

测试:

@Test
void testDecorate() {// 没有装饰器
//    LynkCar lynkCar = new LynkCar();
//    lynkCar.getCarInfo();// 有装饰器LynkCarDecorate lynkCarDecorate = new LynkCarDecorate(new LynkCar());lynkCarDecorate.getCarInfo();
}

结果:

二、适配器模式

特点:

  • 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,像插座转换器、USB转VGA的转接头,220V交流电转5V直流电等都属于生活中的适配器;
  • 适配器(Adapter)有三种类型:类适配器模式(通过继承特性来实现适配器的功能)、对象适配器模式(通过对象组合方式来实现适配器的功能)、接口适配器模式(借助抽象类来实现适配器的功能);
  • 适配器模式也是一种包装模式,具有包装的功能,实际中建议尽量使用对象的适配器模式。

1、类适配器

通过继承方式来实现适配器的功能。

举例:

不同品牌的手机充电接口是不同的,像苹果和华为分别采用的是苹果USB,type-c,为了在充电时满足不同品牌手机的需求,通过一个一线三拖的数据线可以解决这个问题,而这个一线三拖的数据线就是适配器角色。

Demo实现:

/** 苹果手机用苹果数据线 (被适配者)*/
class AppleUSB {public void connection() {System.out.println("使用苹果手机数据线连接...");}
}/** 定义目标接口,有数据线连接的功能 */
interface Target {void connection();
}/** 华为手机是type-c数据线 */
class HuaWeiUSB implements Target {@Overridepublic void connection() {System.out.println("使用华为手机type-c数据线连接...");}
}/** 开发一个一线三拖的数据线(适配器类),继承了被适配类,同时实现标准接口,实现不同USB都能使用 */
class OneToThreeAdapter extends AppleUSB implements Target {@Overridepublic void connection() {System.out.println("插入一线三拖数据线.....");super.connection();}
}

测试:

@Test
void testAdapter() {Target target = new HuaWeiUSB();target.connection();Target adapter = new OneToThreeAdapter();adapter.connection();
}
// 结果如下:
使用华为手机type-c数据线连接...
插入一线三拖数据线.....
使用苹果手机数据线连接...

2、对象适配器

对象适配器与类适配器不同之处在于,类适配器通过继承来完成适配,对象适配器则是通过对象关联来完成。改造上面的oneToThreeAdapter 类,只去实现接口,并将被适配者(苹果USB)作为该适配器的成员属性即可。

/** 一线三拖的数据线 */
class OneToThreeAdapter implements Target {// 将被适配者作为成员属性private AppleUSB apple = new AppleUSB();@Overridepublic void connection() {System.out.println("插入一线三拖数据线.....");apple.connection();}
}

3、适配器模式的优缺点

总结下适配器模式的优点:

  • 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构;
  • 增加了类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用;
  • 灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”

当然,它也是有缺点的:

  • Java是单继承机制,类适配器模式中,一次最多只能适配一个适配者类;
  • 对象适配器模式中,在适配器中置换适配者类的某些方法比较麻烦。

【设计模式系列】5.装饰器模式和适配器模式相关推荐

  1. 【Java设计模式系列】装饰器模式(Decorator Pattern)

    简介 一般有两种方式可以给一个类或对象新增行为: 继承 子类在拥有自身方法同时还拥有父类方法.但这种是静态的,用户无法控制增加行为的方式和时机. 关联 将一个类的对象嵌入另一个对象,由另一个对象决定是 ...

  2. Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

  3. java中装饰器_Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

  4. 设计模式之【装饰器模式】

    和表妹去喝奶茶 表妹:哥啊,我想喝奶茶. 我:走啊,去哪里喝? 表妹:走,我带你去,我经常去的那家,不但好喝,还可以自由搭配很多小料.我每次都是不同的搭配,换着喝,嘻嘻. 我:你倒是挺会喝的嘛~ 你看 ...

  5. java-IO流(5)-IO流中的设计模式(装饰器模式和适配器模式)的介绍

    目录 1装饰器模式 1.1定义 1.2代码实现 1.3装饰器特点 1.4装饰器在IO流中的使用 2配适器模式 2.1Adapter适配器 2.2代码实例 2.3适配器特点 2.4适配器优缺点 2.5适 ...

  6. 装饰器模式和适配器模式

    装饰器模式 装饰器模式(Decorator )允许向一个现有的对象添加新的增强功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 一般的,我们为了扩展一个类经常使 ...

  7. 设计模式篇——初探装饰器模式

    文章目录 1.装饰器模式介绍 2.装饰器模式类图 3.装饰器模式Demo实现(一个小镇的拉面馆) 4.装饰器模式总结 装饰器模式介绍:装饰器模式可以在不修改任何底层代码的情况下,给对象赋予新的职责(程 ...

  8. Java设计模式之《装饰器模式》及应用场景

    一.概述 装饰器模式作用是针对目标方法进行增强,提供新的功能或者额外的功能. 不同于适配器模式和桥接模式,装饰器模式涉及的是单方,和代理模式相同,而且目标必须是抽象的. 而实际上,装饰器模式和代理模式 ...

  9. Java设计模式之《装饰器模式》

    一.概述 装饰器模式作用是针对目标方法进行增强,提供新的功能或者额外的功能. 不同于适配器模式和桥接模式,装饰器模式涉及的是单方,和代理模式相同,而且目标必须是抽象的. 而实际上,装饰器模式和代理模式 ...

最新文章

  1. POJ 2828-Buy Tickets(线段树上二分)
  2. Android系统默认Home应用程序(Launcher)的启动过程源码分析
  3. AEAI ESB路由转换机制说明
  4. TCP/IP和UDP的区别
  5. 使用easyUI 格式化datagrid列
  6. jwt-cli:一个用于解码JSON Web令牌(JWT令牌)的Shell库
  7. python爬取知乎live_Python爬虫从入门到放弃(十九)之 Scrapy爬取所有知乎用户信息(下)...
  8. 4011-基于邻接表的深度优先遍历(C++,取巧做法)
  9. html 轮播_Axure教程:使用动态面板实现轮播图
  10. cmake mysql 参数_MySQL cmake编译时这些参数是什么意思?-问答-阿里云开发者社区-阿里云...
  11. mysql day of week_在MySQL中按day_of_week排序
  12. 韩顺平Java学习 面向对象【高级】(笔记)
  13. Android 圆形进度条
  14. Elasticsearch分布式架构原理图
  15. 树莓派与笔记本电脑连接屏幕共享(通过热点)
  16. ModelNet10/40数据集的下载及dataset代码分析
  17. 什么事MVC?什么是MVC!
  18. 在eclipse中安装Jess
  19. 华硕rt-n16无线打印服务器,华硕无线路由器RT-N16解决无线信号难题
  20. min4 vs mini5 一定要买 iPad mini5,听我一一道来。

热门文章

  1. vue elementUI 之 this.$confirm 用法
  2. Github pages 同步到Gitee pages 并自动更新Gitee pages
  3. R-CNN、Fast R-CNN、Faster R-CNN
  4. 卡尔曼滤波 | Matlab实现卡尔曼滤波(Kalman Filtering)仿真
  5. 【学习笔记】前端入门自学笔记(二)
  6. PageRank算法(网页排名算法)初步理解
  7. [转](2条消息) 分享8个有趣的python小玩具
  8. U盘安装Linux Centos7
  9. jquery-1.10.2.min.map 404 (Not Found)问题及解决
  10. k8s资源清单注解大全