`
wangchao_17915566
  • 浏览: 169492 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

了解适配器模式

阅读更多

     客户端通过类的接口访问提供的服务,一般现有类可提供用户的所需功能,而有时不能满足用户的期望。例如有两个毫无关联的类组合在一起使用,要么就是修改各自的接口,但是在不修改各自接口的前提下,应该怎么做呢?使用Adapter模式,使得原本需要修改接口的才能在一起工作的两个类可以通过此模式不进行修改接口,在一起工作。

     举个例子,面包制作商可以制作面包,蛋糕制作商可以制作蛋糕,某工厂以前请了面包制作商只做面包,而现在还要制作蛋糕。

     传统方法 增加一个蛋糕制作的接口,并且在实现中增加制作蛋糕的实现。

public interface MakeFactory{
	String getCake();
	String getBread();
}

 实现:

public class MakeFactoryImpl implements MakeFactory{

	public String getBread() {
		// TODO Auto-generated method stub
		return null;
	}

	public String getCake() {
		// TODO Auto-generated method stub
		return null;
	}

}

 这样就ok了。

但是想想,以前他是做面包的,有做面包的一套体制,如果再把做蛋糕加进去,工序有可能会乱。并且无法工作。

这样我们可以通过Adapter模式。

   

/**
 * Adaptee 被适配器
 * */
public class MakeBread {
	public String getBread(){
		System.out.println("++++++bread++++");
		return "bread";
	};
}

 以前我只有一个面包房,现在我还要蛋糕房

public interface MakeFactory{
	String getCake();
	String getBread();
}

  

 最后看看如何通过适配器模式,将不相连的两个类配在一起工作。

/**
 * Adapter 适配器
 * */
public class MakeCake extends MakeBread implements MakeFactory {
	public String getCake() {
		System.out.println("++++++cake++++");
		return "cake";
	};
}

 

这样做,我们的MakeFactory工厂就可以有条不紊的进行制作。

我们测试一下

public class Client {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		MakeCake m = new MakeCake();
		m.getCake();
		m.getBread();
	}
}

 

测试结果

++++++cake++++
++++++bread++++

 

从这里不难看出,此接口可以满足用户的需要。

分享到:
评论
27 楼 yuanyao 2009-06-04  
看了回复,收获不少....
26 楼 uu22 2009-04-22  
悟!!!!!!
25 楼 zpoop 2009-04-20  
个人觉得,实际上方法重载的复用,也是一种适配方式。
24 楼 liyun_1981 2009-01-20  
wuwanli0228 写道
独孤求学 写道
运行机制有点看不明白, 还望解释下

清楚点说。
定义了接口,接口里边有定义个方法供下边实现类实现,(我不太了解适配器模式,不知道为什么作者会写2个方法,我试过写一个方法getCake()就可以。)然后定义了MakeBread定义了getBread方法。再写一个类实MakeFactory接口并继承了MakeBread类。
后边Client实现类里边的
public static void main(String[] args) {  
       MakeCake m = new MakeCake();  //创建子类对象
      m.getCake();                   //调用了子类自己的方法
       m.getBread();                 //子类对象既是父类对象,用到了运行时多态的特性。调用了父类的方法;
}
不太熟悉设计模式只能从入门级别给你说下。。如果不对还望指点;


晕死!你对类继承和多态的概念都没搞清楚嘛!子类继承父类,并不是“子类对象既是父类对象”,而是父类中的非private成员变量和方法都给了子类,子类自己可以调用他们。再说一下多态,子类重写继承自父类的方法或者定义父类中申明的abstract方法才是多态的表现!
23 楼 KimHo 2008-12-17  
看了后,获益匪浅,谢谢楼主的分享
22 楼 wuwanli0228 2008-12-16  
独孤求学 写道
运行机制有点看不明白, 还望解释下

清楚点说。
定义了接口,接口里边有定义个方法供下边实现类实现,(我不太了解适配器模式,不知道为什么作者会写2个方法,我试过写一个方法getCake()就可以。)然后定义了MakeBread定义了getBread方法。再写一个类实MakeFactory接口并继承了MakeBread类。
后边Client实现类里边的
public static void main(String[] args) {  
       MakeCake m = new MakeCake();  //创建子类对象
      m.getCake();                   //调用了子类自己的方法
       m.getBread();                 //子类对象既是父类对象,用到了运行时多态的特性。调用了父类的方法;
}
不太熟悉设计模式只能从入门级别给你说下。。如果不对还望指点;
21 楼 wuwanli0228 2008-12-16  
yunhaifeiwu 写道
wuwanli0228 写道
你好我是初学者也是才在这个网站上注册的。我想问下Makecake m=new Makecake();然后就可以调用下面的方法了。m.makeBread();
m.makeCake();是不是用子类对象就是父类对象实现的?我是初学者,请回复下。讲的越明白越好。



你说的这个m.makeCake(),楼主的例子中好像没有这个方法。对于你的提问也就莫名奇妙了。

 public class MakeCake extends MakeBread implements MakeFactory {  
     public String getCake() {  
         System.out.println("++++++cake++++");  
         return "cake";  
     };  
} 


MakeFactory 接口有两种方法  getBread 和 getCake.
上面代码中MakeCake类实现了MakeFactory 接口。要实现一个接口,则必须全部实现接口的方法。

在MakeCake类中,显示实现了getCake方法。而getBread 方法,是由MakeCake的父类(即MakeBread )中的getBread 方法隐示实现。

也就是说,楼主用了继承与接口实现了适配器。但是正如我前面所说的,这种方式是一种不太好的方式,至少会影响对设计模式的深入理解。同时也违反了设计模式的原则,如果不是特殊情况下,这种方式少用为妙。如果是学设计模式,应掌握通过对象注入的实现方式。

==================================================================

下面是给你的参考建议:
1  认真阅读java面向对象的基本概念。弄清继承、接口、对象的含义。在你的提问中,反映出在这些方面还欠缺一些。
2  对于设计模式,你应掌点掌握适配器模式。但楼主这种方式,你只能了解即可。我前面介绍了适配器模式的另一种方式。姑且叫对象注入吧。
3 强调:对象注入要认真研究揣磨。什么访问者模式、命令模式、职责链模式、组合模式、观察者模式等,从实现角度上看,基本可分成:对象注入+数据结构。事实上"对象注入+数据结构"能弄出千变万化的模式出来。

以上是个人观点,仅供参考。


那是我按照楼主的意思自己在myeclipse里边写了个。其实makeCake(),在楼主的代码里是getCake,mackeBread是楼主的getBread其实我明白了是运用了类的运行时多态性是吧?谢谢楼上的哥们的建议。做了几个项目后发现基础的那些不经常用的都忘了。呵呵。见笑
20 楼 fjlyxx 2008-12-14  
我的认识是适配器模式 其实就是一个补救的模式。适配对象应该是接口,功能让是两个原本不能通讯的接口进行通讯。
其实就是现实生活中的翻译。 个人的肤浅认识。所以LZ例子中抓住类的实现去说明适配器也许会让人费解,说明白适配器只要抓住需要适配的两个接口就可以了。因为你需要适配的不一定是两个JAVA类 也有可能是 一个XML片段,一个BYTE数组等。
19 楼 yunhaifeiwu 2008-12-14  
wuwanli0228 写道
你好我是初学者也是才在这个网站上注册的。我想问下Makecake m=new Makecake();然后就可以调用下面的方法了。m.makeBread();
m.makeCake();是不是用子类对象就是父类对象实现的?我是初学者,请回复下。讲的越明白越好。



你说的这个m.makeCake(),楼主的例子中好像没有这个方法。对于你的提问也就莫名奇妙了。

 public class MakeCake extends MakeBread implements MakeFactory {  
     public String getCake() {  
         System.out.println("++++++cake++++");  
         return "cake";  
     };  
} 


MakeFactory 接口有两种方法  getBread 和 getCake.
上面代码中MakeCake类实现了MakeFactory 接口。要实现一个接口,则必须全部实现接口的方法。

在MakeCake类中,显示实现了getCake方法。而getBread 方法,是由MakeCake的父类(即MakeBread )中的getBread 方法隐示实现。

也就是说,楼主用了继承与接口实现了适配器。但是正如我前面所说的,这种方式是一种不太好的方式,至少会影响对设计模式的深入理解。同时也违反了设计模式的原则,如果不是特殊情况下,这种方式少用为妙。如果是学设计模式,应掌握通过对象注入的实现方式。

==================================================================

下面是给你的参考建议:
1  认真阅读java面向对象的基本概念。弄清继承、接口、对象的含义。在你的提问中,反映出在这些方面还欠缺一些。
2  对于设计模式,你应掌点掌握适配器模式。但楼主这种方式,你只能了解即可。我前面介绍了适配器模式的另一种方式。姑且叫对象注入吧。
3 强调:对象注入要认真研究揣磨。什么访问者模式、命令模式、职责链模式、组合模式、观察者模式等,从实现角度上看,基本可分成:对象注入+数据结构。事实上"对象注入+数据结构"能弄出千变万化的模式出来。

以上是个人观点,仅供参考。

18 楼 wuwanli0228 2008-12-14  
你好我是初学者也是才在这个网站上注册的。我想问下Makecake m=new Makecake();然后就可以调用下面的方法了。m.makeBread();
m.makeCake();是不是用子类对象就是父类对象实现的?我是初学者,请回复下。讲的越明白越好。
17 楼 qiuxy295111 2008-12-13  
要了解适配器模式,可以看看java.io包,像InputStreamWriter这些类都是适配器的典型例子,简单来说就是让InputStream拥有Writer接口的方法
16 楼 wangchao_17915566 2008-12-11  
谢谢大家的意见,让我领悟不少
15 楼 puroc 2008-12-10  
刚才看了一些适配器模式的资料。LZ写的例子是对的。这是类的适配器模式,而不是对象的适配器模式。我之前了解的都是对象的适配器模式。刚刚了解到,类的适配器模式有一个缺点,即要适配的类不是一个,而是多个的时候。用类的适配器模式就没发实现了。因为只能继承一个类。(不过我个人感觉,继承一个类,只是为了得到它里面的方法,感觉怪怪的。还是对象适配器模式容易理解一些。)
14 楼 puroc 2008-12-09  
LZ这个例子不是Adapter模式。而且有问题。

public class MakeCake extends MakeBread implements MakeFactory {  
     public String getCake() {  
         System.out.println("++++++cake++++");  
         return "cake";  
     };  
 } 


这段代码,MakeCake为什么要继承MakeBread呢?难道只是为了获得MakeBread的getBread方法吗?MakeCake和MakeBread应该是并列关系,不应该是继承关系,不应该为了获得某个类的方法,就继承那个类。比如:想使用工具类中的方法,就去继承工具类,这是不对的。
13 楼 卧底在人间 2008-12-09  
楼主举的这个例子 十分的不好  可能用不恰当来说 最合适

就比如说  说话都有 有歧义的时候

你举的这个例子 就有歧义~

你说的这个东西  我觉得就是  时下  什么  jsf啊  Spring之类里面 提到的
Ioc  反转控制 依赖注入之类的东西~
12 楼 etongg 2008-12-09  
adapter, proxy, facade有什么异同呢?
11 楼 youfengkai 2008-12-09  
yunhaifeiwu 写道
    楼主的例子中,使用了类继承得到Bread.

     在设计模式的三大原则中:违反了第二原则。因此个人认为,楼主这个实现方法,会严重影响到对适配器模式的深入理解。事实上,看UML图,类Adapter 与类Adaptee是依赖关系,而Adapter中的request方法的注释,更明确的指出,在这个方法里调用了adapter对象的SpecitcRequest方法。

    设计模式几大原则:(出自李建忠讲义)
================================
• 针对接口编程,而不是针对实现编程
– 客户无需知道所使用对象的特定类型,只需要知道对象拥有客户所期望
的接口。
• 优先使用对象组合,而不是类继承
– 类继承通常为“白箱复用”,对象组合通常为“黑箱复用”。继承在某种程度
上破坏了封装性,子类父类耦合度高;而对象组合则只要求被组合的对
象具有良好定义的接口,耦合度低。
• 封装变化点
– 使用封装来创建对象之间的分界层,让设计者可以在分界层的一侧进行
修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合。
• 使用重构得到模式——设计模式的应用不宜先入为主,一上来就使用
设计模式是对设计模式的最大误用。没有一步到位的设计模式。敏捷
软件开发实践提倡的“Refactoring to Patterns”是目前普遍公认的最好
的使用设计模式的方法。

==================================
我所举的是对象组合,而非类继承。 也许有人会认为我所举的,没有针对接口,这里简化了。(它在我的认知世界体系中,支撑着对框架的理解)
    

讲得很好,严重同意!
而楼主的例子看起来不是适配器模式阿,适配器模式是要组合来实现的
10 楼 yunhaifeiwu 2008-12-08  
    楼主的例子中,使用了类继承得到Bread.

     在设计模式的三大原则中:违反了第二原则。因此个人认为,楼主这个实现方法,会严重影响到对适配器模式的深入理解。事实上,看UML图,类Adapter 与类Adaptee是依赖关系,而Adapter中的request方法的注释,更明确的指出,在这个方法里调用了adapter对象的SpecitcRequest方法。

    设计模式几大原则:(出自李建忠讲义)
================================
• 针对接口编程,而不是针对实现编程
– 客户无需知道所使用对象的特定类型,只需要知道对象拥有客户所期望
的接口。
• 优先使用对象组合,而不是类继承
– 类继承通常为“白箱复用”,对象组合通常为“黑箱复用”。继承在某种程度
上破坏了封装性,子类父类耦合度高;而对象组合则只要求被组合的对
象具有良好定义的接口,耦合度低。
• 封装变化点
– 使用封装来创建对象之间的分界层,让设计者可以在分界层的一侧进行
修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合。
• 使用重构得到模式——设计模式的应用不宜先入为主,一上来就使用
设计模式是对设计模式的最大误用。没有一步到位的设计模式。敏捷
软件开发实践提倡的“Refactoring to Patterns”是目前普遍公认的最好
的使用设计模式的方法。

==================================
我所举的是对象组合,而非类继承。 也许有人会认为我所举的,没有针对接口,这里简化了。(它在我的认知世界体系中,支撑着对框架的理解)
    
9 楼 yunhaifeiwu 2008-12-08  
下面摘自李建忠(当年MSDN,CSDN请的讲师)的讲义
===========================

引:在现实环境中,经常需要“引用现在的一些对象”到新的环境中去,但是新的环境中的要求的接口是“这些存在对象”不满足的。
意图:将一个类的接口转换成用户所需要的接口。适配器模式使哪些原本因接口而不能一起工作的类可以一起工作。
===========================

对了,这是讲c#的。有的网友别迂腐到讲c#的设计模式,就不能用到java中了。要是这样,我只能无语。


在上面的UML类图中,Target表成了一个类。实际中,这个要么是一个接口(java中的interface,与李建忠讲义的意图中的接口的概念有点不一样。)。Adaptee就是第三方提供的类。而客户中的代码,不希望直接使用这个第三方类的,于是通过Adapte使用。抛掉Target,就是前面我说的大轮子套小轮子。


适配器从实现的角度上看,是把一个类实例(假如叫objA),注入到另一个类(假定这个类叫类B)中,在这个类B中的方法,使用前面所说的类的实例(即objA)的方法。

从适配器意图上看:它是解决两套接口标准不同的问题。举个例子:
假定有个第三方类叫Man(即人),定义并实现了一个方法叫 feed (吃饭),而这个方法中没有任何参数了。客户不能改变第三方的类的源代码,但是由于实际需要,它想要在这Man的feed方法中加入一个参数---吃饭时间。这时如何办呢?
就是另定义一个类FMan,也定义一个方法,这个方法有一个参数---吃饭时间,在这个类(即FMan)中需要传入Man的实例,在FMan的feed方法里,调用Man实例的feed方法。


在这个适配器中,适配器的实现角度,可以进行总结,推广,再进行新的定义,就会发现这个适配器的内涵,博大精深。如果喜欢佛家之悟的朋友,可把接口、抽象类、适配器模式,联合起来进行观察体会,找出他们的相同点、不同点,会发现这个适配器,真的像机器中的螺丝,它把各个部件有机的组合在一起了。这是一个高度抽象的东东,如果要讲清,需要定义一大套的词语的含义。关于这个适配器模式,就到此为止吧。
8 楼 yunhaifeiwu 2008-12-08  
wangchao_17915566 写道
tou3921 写道

当初第一次看到时真的感觉蛮震撼的。。。。

人嘛,都是在不断学习中进步的,错了能改就好了,也同样感谢帮助和指导



javaeye中所有人像你这种想法就对了。

相关推荐

    适配器模式源代码

    通过阅读和理解这个源代码,我们可以更深入地了解适配器模式的原理和应用,提升我们的设计能力,使我们在面对类似问题时能更从容地利用设计模式来优化代码结构和提高代码复用性。同时,这也是学习和实践面向对象设计...

    设计模式——适配器模式

    通过阅读博客文章《设计模式——适配器模式》(链接:https://wjy320.iteye.com/blog/2042323),我们可以深入了解适配器模式的实现细节,包括具体的代码示例以及在实际项目中的应用案例。这个博客可能会讨论如何在...

    适配器模式

    博客链接(https://ylxy3058.iteye.com/blog/2226113)可能提供了更深入的适配器模式的实践案例或源码分析,建议参考学习,以深入了解适配器模式的实现细节和应用场景。 至于"cygoattest"这个压缩包子文件的文件...

    C#设计模式—适配器模式应用实例

    首先,让我们了解适配器模式的基本组成部分: 1. **目标(Target)**:这是客户端需要调用的接口。在C#中,这通常是一个抽象类或接口。 2. **适配者(Adaptee)**:这是需要适配的旧接口或类,它可能是一个第三方库...

    适配器模式资料

    通过阅读文档,你可以了解适配器模式的基本原理和设计思想;通过查看代码示例,你可以学习如何在实践中实现适配器模式,包括类适配器和对象适配器的代码结构和用法。 总结一下,适配器模式是一种重要的设计模式,...

    .Net设计模式_适配器模式

    适配器模式是一种在软件工程中广泛使用的结构型设计模式,它的主要目的是为了让不兼容的接口之间能够进行通信。在.NET开发中,适配器模式扮演着重要角色,尤其是在处理不同系统、库或组件间的集成时。这个".Net设计...

    设计模式——适配器模式(adapter)

    在阅读文章《设计模式——适配器模式(adapter)》时,你可以期待了解到更多关于适配器模式的实战案例、优缺点分析以及如何在实际项目中有效利用这一模式来解决问题。同时,提供的`adapter`压缩包文件可能包含示例...

    设计模式之适配器模式与外观模式demo

    适配器模式和外观模式是两种非常重要的设计模式,它们在实际项目中有着广泛的应用。本资源提供了一个关于这两种模式的实战示例,帮助我们更好地理解和应用它们。 适配器模式(Adapter Pattern)的主要目的是将两个...

    iOS适配器模式.zip

    [刚刚上传的demo运行有问题,重新传了个新的],这个的一个iOS的适配器模式的实例代码,目前就是一个简单的demo,后期还会更新适配器在 MVC,MVP,MVVM中的使用,demo对应着简书:https://www.jianshu.com/p/e2ebcf19098f,...

    设计模式实验报告-适配器模式.docx

    通过本实验,我们深入了解了适配器模式的概念及其两种实现方式——对象适配器和类适配器。实验中,我们不仅学习了如何设计和实现适配器,还通过具体的示例理解了适配器模式的实际应用价值。这种模式能够有效地提升...

    设计模式:结构型-适配器模式

    适配器模式可以分为三种类型:类适配器模式、对象适配器模式和接口适配器模式。 类适配器模式中,适配器类通过继承适配者类并实现目标接口来实现适配。例如,在手机充电的例子中,充电器(VoltageAdapter)继承了...

    设计模式--适配器模式

    适配器模式是一种常用的设计模式,它在软件工程中扮演着重要的角色,特别是在解决系统间的兼容性和接口不匹配问题时。适配器模式的核心思想是将一个类的接口转换成客户希望的另一个接口,使原本由于接口不兼容而无法...

    适配器模式DEMO

    通过这个DEMO,开发者不仅可以学习适配器模式的基本概念,还能了解到如何在实际编码中应用这一模式,从而提升软件设计的灵活性和可维护性。在分析和理解DEMO的过程中,建议关注以下几个关键点: 1. 适配器类的结构...

    设计模式适配器模式讲解

    在深入讨论适配器模式之前,我们首先需要了解几个基本的概念: - **目标角色(Target)**:这是客户端期望的接口。所有适配后的对象都应该实现这个接口。 - **源角色(Adaptee)**:需要被适配的类。它的接口不符合...

    适配器模式和桥接模式共26页.pdf.zip

    适配器模式与桥接模式是软件设计模式中的两种重要结构型模式,它们在软件开发中起到了关键的作用,帮助开发者解决系统组件之间的兼容性问题和解耦问题。这两种模式都是为了实现不同接口间的协同工作,但各有其独特的...

    [结构型模式] head first 设计模式之适配器模式(Adapter)

    在阅读《Head First设计模式》中的适配器模式章节时,你会了解到如何根据具体需求选择适当的适配器类型,以及如何有效地实现适配器以达到预期的效果。通过案例分析和实际代码示例,书中的讲解会让你对适配器模式有...

    通用数据适配器的用法

    通过分析这个示例,我们可以更清晰地了解适配器模式在实际项目中的应用。 适配器模式在Java、C#、Python等编程语言中都有广泛的应用。在Java中,可以使用接口或继承来实现适配器;在C#中,可以使用接口和委托;而在...

Global site tag (gtag.js) - Google Analytics