适配器模式(Adapter)—山下的养牛场
2015-12-23 19:26
225 查看
适配器模式:
将一个类的接口转换成客户端所期待的接口,从而使因接口不匹配而无法工作的两个类能够在一起工作。
角色列表:
目标角色(Target):期待得到的接口
源角色(Adaptee):需要适配的接口
适配器角色(Adapter):将原接口转换成目标接口,必须是具体类
适配器模式可分为类的适配模式与对象的适配模式,区别是类的适配模式中适配器与原接口是继承关系,对象的适配模式中适配器与原接口是关联关系。
适配器模式最大的问题是一定要理解适配器不是为类添加不具备的方法,而是适配两个功能相近或者相似的接口。
类的适配模式
类图
例子:山下有座养牛场,兽医之前只需要对牛打针,之后为了提高效益,需要对牛进行科学喂养,要根据牛的健康状况进行科学配料,因此需要一个适配器,对兽医进行适配,从而实现兽医既可以打针,还能科学配料。
实现效果如下:
对象的适配模式
类图:
例子:还是山下的养牛场,只不过对兽医的适配器由继承关系改为关联关系。
调用结果如上,但未发现类与对象的适配器有多大不同,最多就是解耦了适配器与适配器角色,使耦合变得松散灵活。
缺醒适配器模式
这个模式感觉作用还是比较实用,简单来说就是具体类不用直接实现接口,以免暴露客户端并不需要的方法,通过继承替代实现,这样就可以屏蔽掉无用的方法。
类图:
例:还是拿养牛场的例子来说明一下,牛场的工人有普通工人,还有车间主任,抽象的工人接口有打卡(daka)、喂牛(weiniu)、发工资(salary)等方法,但是车间主任是不需要打卡与喂牛这些具体的工作的,只要保证每个车间的工作正常运转就可以月底领工资了,因此给工人接口来个缺醒实现,然后车间主任继承这个缺醒实现就可以,然后车间主任只需要每个月领工资就可以了。
如上就是适配器模式的简介了,日常的应用中最熟悉的就是jdbc驱动了,具体功能还需深入了解。
将一个类的接口转换成客户端所期待的接口,从而使因接口不匹配而无法工作的两个类能够在一起工作。
角色列表:
目标角色(Target):期待得到的接口
源角色(Adaptee):需要适配的接口
适配器角色(Adapter):将原接口转换成目标接口,必须是具体类
适配器模式可分为类的适配模式与对象的适配模式,区别是类的适配模式中适配器与原接口是继承关系,对象的适配模式中适配器与原接口是关联关系。
适配器模式最大的问题是一定要理解适配器不是为类添加不具备的方法,而是适配两个功能相近或者相似的接口。
类的适配模式
类图
例子:山下有座养牛场,兽医之前只需要对牛打针,之后为了提高效益,需要对牛进行科学喂养,要根据牛的健康状况进行科学配料,因此需要一个适配器,对兽医进行适配,从而实现兽医既可以打针,还能科学配料。
/** * 目标接口(Target),其会多一个配料(peiLiao)的方法 * @author wang */ public interface VeterinaryTarget { public void daZhen(); public void peiLiao(); } /** * 兽医打针的源角色(Adaptee),此类需要适配 * @author wang */ public class VeterinaryAdaptee { public void daZhen(){ System.out.println("给牛打针"); } } /** * 适配器角色(Adapter) * 它对源角色的没有的方法进行了适配 * @author wang */ public class VeterinaryAdapter extends VeterinaryAdaptee implements VeterinaryTarget{ public void daZhen(){ super.daZhen(); } public void peiLiao(){ System.out.println("根据每天的营养状况配置营养成分不同的饲料"); } } /** * 客户端调用 可以实现目标的两个方法了 * @author wang */ public class Client { public static void main(String[] args){ VeterinaryTarget adapter = new VeterinaryAdapter(); adapter.daZhen(); adapter.peiLiao(); } }
实现效果如下:
对象的适配模式
类图:
例子:还是山下的养牛场,只不过对兽医的适配器由继承关系改为关联关系。
/** * 目标接口(Target),其会多一个配料(peiLiao)的方法 * @author wang */ public interface VeterinaryTarget { public void daZhen(); public void peiLiao(); } /** * 兽医打针的源角色(Adaptee),此类需要适配 * @author wang */ public class VeterinaryAdaptee { public void daZhen(){ System.out.println("给牛打针"); } } /** * 适配器角色(Adapter) * 它对源角色的没有的方法进行了适配 * @author wang */ public class VeterinaryAdapter implements VeterinaryTarget{ private VeterinaryAdaptee veterinaryAdaptee; public VeterinaryAdapter(VeterinaryAdaptee veterinaryAdaptee){ this.veterinaryAdaptee = veterinaryAdaptee; } public void daZhen(){ this.veterinaryAdaptee.daZhen(); } public void peiLiao(){ System.out.println("根据每天的营养状况配置营养成分不同的饲料"); } } /** * 客户端调用 可以实现目标的两个方法了 * @author wang */ public class Client { public static void main(String[] args){ VeterinaryTarget veterinaryAdapter = new VeterinaryAdapter(new VeterinaryAdaptee()); veterinaryAdapter.daZhen(); veterinaryAdapter.peiLiao(); } }
调用结果如上,但未发现类与对象的适配器有多大不同,最多就是解耦了适配器与适配器角色,使耦合变得松散灵活。
缺醒适配器模式
这个模式感觉作用还是比较实用,简单来说就是具体类不用直接实现接口,以免暴露客户端并不需要的方法,通过继承替代实现,这样就可以屏蔽掉无用的方法。
类图:
例:还是拿养牛场的例子来说明一下,牛场的工人有普通工人,还有车间主任,抽象的工人接口有打卡(daka)、喂牛(weiniu)、发工资(salary)等方法,但是车间主任是不需要打卡与喂牛这些具体的工作的,只要保证每个车间的工作正常运转就可以月底领工资了,因此给工人接口来个缺醒实现,然后车间主任继承这个缺醒实现就可以,然后车间主任只需要每个月领工资就可以了。
/** * 工人辛苦啊 需要每天打卡 喂牛 然后每月领工资 * @author wang */ public interface Worker { public void daka(); public void weiniu(); public void salary(); } /** * 工人接口的缺醒实现,什么都不需要做 * @author wang */ public class WorkerImpl implements Worker { public void daka() { // TODO Auto-generated method stub } public void salary() { // TODO Auto-generated method stub } public void weiniu() { // TODO Auto-generated method stub } } /** * 车间主任不用做具体的工作,每个月领工资就行了,当领导就是好啊 * @author wang */ public class Director extends WorkerImpl{ public void salary(){ System.out.println("每月10号发工资"); } }
如上就是适配器模式的简介了,日常的应用中最熟悉的就是jdbc驱动了,具体功能还需深入了解。
相关文章推荐
- CentOS根分区扩容方法
- iOS完全自学手册——[一]Ready?No!
- 2015-12-23日记:稳步的走向稳定与互联网加教育的理念阐述
- IOS开发之MapKit学习笔记
- Xen 和 KVM 下如何关闭 virbr0
- SQL Server完全删除问题
- Objective-C:@class和#import
- VC写的读写配置文件的类
- KVC
- Java 9中新的货币API
- x86_64系统 yum安装i386包
- 关于easyUI在子页面增加显示tabs的一个问题
- python urllib 和urllib2的区别
- 模型驱动开发-GME(The Generic Modeling Environment) - 前言
- VC中CListCtrl设置滚动条在最下边的方法(MSDN中的例子)
- KVO(NSKeyValueObserving)
- Apache启动脚本的建立
- Android实现不重复启动APP的方法
- Unity3D组件手册-Box Collider
- jdbc prepareStatement的运用