Java设计模式之适配器模式(Adapter)
这个总结的挺好的,为了加深印象,我自己再尝试总结一下
1.定义:
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
(太官方了,不太好理解,
其实就是要用到两个不相关的类/接口,但是又没有源代码,或者不想修改源代码,而增加一个类来完成合并使用的目的)
2.实现这个目的有两个方法,继承或者组合
2.1.使用继承(就是所谓的类适配器模式)
2.2.使用组合(所谓的对象适配器模式)
案例: 公司招员工,要求会讲中、英、法、日四国语言,同时还很会编程的员工。
招聘要求类 JobNeedSkill 接口:
- package design.pattern.adapter2;
- public interface JobNeedSkill {
- void speakChinese();
- void speakEnglish();
- void speakJapanese();
- void speakFrench();
- void goodCoding();
- }
而这里有个工人,技术超一流,可惜只会说中文。
Worker类:
- package design.pattern.adapter2;
- public class Worker {
- public void goodCoding(){
- System.out.println("我编程也挺牛的哦");
- }
- public void speakChinese(){
- System.out.println("我只会说中文呢,能不能请我啊");
- }
- }
招聘测试类 Test:
- package design.pattern.adapter2;
- public class Test {
- //招聘员工
- public static void hireWorker(JobNeedSkill worker){
- System.out .println("恭喜你,你被录用了,展示一下你的技能吧");
- System.out .println("===============================");
- worker.speakChinese();
- worker.speakEnglish();
- worker.speakFrench();
- worker.speakJapanese();
- worker.goodCoding();
- }
- public static void main(String[] args){
- //我是个只会说中文的工人 ,但我编程好
- Worker me = new Worker();
- //我们需要一个会说四国语言的员工
- // hireWorker(me);//直接招聘是不行了,再给他配个步步高点读机吧
- /*
- * 以上代码为初始状态,后面的代码是后面根据需求增加的
- * */
- //有步步高点读机,这是使用了继承的方式,类的适配模式
- TheManHasBuBuGao bbg = new TheManHasBuBuGao();
- hireWorker(bbg);
- System.out.println("*****************\r\n");
- //这个自带助理的,是使用了组合的方式,是对象的适配模式
- WorkerHasAssistant gfs = new WorkerHasAssistant(me);
- hireWorker(gfs);
- }
- }
很明显,一开始的时候发现,尽管这个人技术很牛,但是只会说中文这一点,实在让人觉得可惜,
别说我们公司不能招聘了,就连eclipse都提示错误了:
不过他的技术的确非常符合我们公司的需要,怎么办呢,咋取舍呢······
如果,如果他有一台 “步步高点读机呢”
TheManHasBuBuGao类:
- package design.pattern.adapter2;
- //这里使用了继承的方式
- public class TheManHasBuBuGao extends Worker implements JobNeedSkill{
- @Override
- public void speakJapanese() {
- System.out.println("妈妈再也不用担心我的日语了");
- }
- @Override
- public void speakFrench() {
- System.out.println("哪里不会就点哪里,这样法语也随便搞定了");
- }
- @Override
- public void speakEnglish() {
- System.out.println("So Easy.");
- }
- }
这样问题就解决了,步步高点读机就是好!
不过他说他没有步步高点读机,但是他有一个贴身翻译助理
WorkerHasAssistant类:
- package design.pattern.adapter2;
- public class WorkerHasAssistant implements JobNeedSkill{
- //这个人有自己的助理翻译,这里是使用了组合的方式
- private Worker worker;
- //在构造方法中传进来
- public WorkerHasAssistant(Worker worker){
- this.worker = worker;
- }
- @Override
- public void goodCoding() {
- worker.goodCoding();
- }
- @Override
- public void speakChinese() {
- //worker会说,直接用worker
- worker.speakChinese();
- }
- @Override
- public void speakEnglish() {
- //英语他不会说,这就要助手出马翻译了
- System.out.println("我是他的翻译,他说 Hello World.");
- }
- @Override
- public void speakJapanese() {
- //日语他也不会说,这还是要助手出马翻译了
- System.out.println("八嘎");
- }
- @Override
- public void speakFrench() {
- //每错,他英语也不行
- System.out.println("He can say English too.");
- }
- }
最后运行的效果是:
把文章看完是个好习惯,
在最后还要特别说明一下,适配器模式还有一种默认缺省的用法,这个目的跟上面的略微不同,但做法是一致的,
都是增加了一个适配类,哈哈(别跟别的设计模式搞混了哦,同时这种用法在Swing开发里经常用到)
Skill 接口:
- package design.pattern.adapter2;
- public interface Skill {
- void sing();
- void dance();
- void fly();
- void cry();
- //.......一大堆方法
- }
如果 Person类直接实现 Skill接口,就会变成这样:
- package design.pattern.adapter2;
- public class Person implements Skill{
- @Override
- public void sing() {
- // TODO Auto-generated method stub
- }
- @Override
- public void dance() {
- // TODO Auto-generated method stub
- }
- @Override
- public void fly() {
- // TODO Auto-generated method stub
- }
- @Override
- public void cry() {
- // TODO Auto-generated method stub
- }
- }
必须同时实现Skill接口中的所有方法,但其实我们关注的只是其中某一个方法而已,
所以,这时候就可以增加一个中间类SkillAdapter,这个类也实现了Skill接口,并实现了所有方法,不过是空实现:
- package design.pattern.adapter2;
- public class SkillAdapter implements Skill{
- @Override
- public void sing() {
- // TODO Auto-generated method stub
- }
- @Override
- public void dance() {
- // TODO Auto-generated method stub
- }
- @Override
- public void fly() {
- // TODO Auto-generated method stub
- }
- @Override
- public void cry() {
- // TODO Auto-generated method stub
- }
- }
而我们在继承这个中间类(Adapter),再重写我们所关注的方法就可以了,而无需做过多无谓的操作:
- package design.pattern.adapter2;
- public class NewPerson extends SkillAdapter{
- public void sing(){
- System.out.println("我只会唱歌,别的我都不会了");
- }
- }
最后再总结一下:
因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构(也就是去改代码),
除了这种默认缺省的适配器外,前面的例子都是在没办法情况下的办法而已。
Java设计模式之适配器模式(Adapter)的更多相关文章
- java设计模式之六适配器模式(Adapter)
适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题.主要分为三类:类的适配器模式.对象的适配器模式.接口的适配器模式.首先,我们来看看类的适配器模 ...
- 夜话JAVA设计模式之适配器模式(adapter pattern)
适配器模式:将一个类的接口,转换成客户期望的另一个接口,让不兼容的接口变成兼容. 1.类适配器模式:通过多重继承来实现适配器功能.多重继承就是先继承要转换的实现类,再实现被转换的接口. 2.对象适配器 ...
- Java设计模式之适配器模式(Adapter Pattern)
Adapter Pattern的作用是在不改变功能的前提下转换接口.Adapter分为两类,一类是Object Adapter, 还有一类是Class Adapter.因为Class Adapter的 ...
- 怎样让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)
怎样让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 标签: 设计模式初涉 概念相关 定义: 适配器模式把一个类的接口变换成client所期待的还有一种接口,从而 使原本因接 ...
- java设计模式5——适配器模式
java设计模式5--适配器模式 1.结构型模式介绍 1.1.作用 从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题. 分类: 适配器模式 代理模式 桥接模式 装饰模式 组合模式 ...
- 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)
原文:乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabc ...
- 8.3 GOF设计模式二: 适配器模式 Adapter
GOF设计模式二: 适配器模式 Adapter 为中国市场生产的电器,到了美国,需要有一个转接器才能使用墙上的插座,这个转接 器的功能.原理?复习单实例模式 SingleTon的三个关键点 ...
- Java设计模式之适配器模式(项目升级案例)
今天是我学习Java设计模式中的第三个设计模式了,但是天气又开始变得狂热起来,对于我这个凉爽惯了的青藏人来说,又是非常闹心的一件事儿,好了不管怎么样,目标还是目标(争取把23种Java设计模式接触一遍 ...
- Java设计模式----初识适配器模式
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...
随机推荐
- RAD Studio Demo Code和几个国外FMX网站 good
FireMonkey X – Amazing overview of FireMonkey FMX Feeds – All your FireMonkey news in one place FMX ...
- jquery datepicker 中文
<script type="text/javascript"> jQuery(function(){ $.datepicker.regional['zh-CN'] = ...
- [Erlang00]:gen_server:reply/2
--- gen_server:reply/2 reply(Client, Reply) –> Result Types: Client - see below Repl ...
- MongoDB高级知识-易扩展
MongoDB高级知识-易扩展 应用程序数据集的大小正在以不可思议的速度增长.随着可用宽带的增长和存储器价格的下跌,即使是一个小规模的应用程序,需要存储的数据也可能大的惊人,甚至超出了很多数据库的处理 ...
- struts2官方 中文教程 系列二:Hello World项目
先贴个本帖的地址,免得其它网站被爬去了struts2入门系列二之Hello World 即 http://www.cnblogs.com/linghaoxinpian/p/6898779.html ...
- PHP程序执行流程
1, PHP文件一定放在服务器的,但是PHP中不同的内容会在不同的地方执行.下图演示了浏览器请求一个php页面的流程. 2,时序图如下所示,在浏览器中输入url后,首先去本机hosts文件中解析ip地 ...
- [ActionScript 3.0] 对数组中的元素进行排序Array.sort()的方法
对数组中的元素进行排序. 此方法按 Unicode 值排序. (ASCII 是 Unicode 的一个子集.) 默认情况下,Array.sort()按以下方式进行排序: 1. 排序区分大小写(Z优先于 ...
- python学习笔记之使用threading模块实现多线程(转)
综述 Python这门解释性语言也有专门的线程模型,Python虚拟机使用GIL(Global Interpreter Lock,全局解释器锁)来互斥线程对共享资源的访问,但暂时无法利用多处理器的优势 ...
- 基于Java软引用机制最大使用JVM堆内存并杜绝OutOfMemory
题记:说好的坚持一周两篇文章在无数琐事和自己的懒惰下没有做好,在此表达一下对自己的不满并对有严格执行力的人深表敬意!!!! -------------------------------------- ...
- linux使用rsync、inotify-tools实现多台服务器文件实时同步
需求:将本地192.168.1.10上的/data/wwwroot目录同步到 1.来源服务器上安装rsync.inotify-tools yum -y install rsync yum -y ins ...