这种模式很容易理解,因为现实世界充满了适配器。例如,考虑一个USB到以太网适配器。当一端有以太网接口,另一端有USB接口时,我们需要这个。因为他们彼此不相容。我们使用一个适配器将一个转换为另一个。这个例子非常类似于面向对象的适配器。在设计中,当我们有一个类(客户机)需要某种类型的对象,而有一个对象(Adaptee)提供相同的功能,但公开不同的接口时,就会使用适配器。
要使用适配器,请执行以下操作:
- 客户端通过使用目标接口调用适配器上的方法向适配器发出请求。
- 适配器使用adaptee接口在adaptee上转换该请求。
- 客户端接收到呼叫结果,并且不知道适配器的存在。
定义:
适配器模式将一个类的接口转换为客户机期望的另一个接口。Adapter允许由于接口不兼容而无法正常工作的类一起工作。
类图:
客户端只看到目标接口,而不看到适配器。适配器实现目标接口。适配器将所有请求委托给Adaptee。
例子:
假设您有一个带有fly()和makeSound()方法的Bird类。还有一个带有squeak()方法的ToyDuck类。假设您缺少ToyDuck对象,并且希望使用Bird对象代替它们。Birds有一些类似的功能,但实现了不同的接口,所以我们不能直接使用它们。所以我们将使用适配器模式。我们的客户是ToyDuck,adaptee是Bird。
下面是它的Java实现。
// Java implementation of Adapter pattern interface Bird { // birds implement Bird interface that allows // them to fly and make sounds adaptee interface public void fly(); public void makeSound(); } class Sparrow implements Bird { // a concrete implementation of bird public void fly() { System.out.println( "Flying" ); } public void makeSound() { System.out.println( "Chirp Chirp" ); } } interface ToyDuck { // target interface // toyducks dont fly they just make // squeaking sound public void squeak(); } class PlasticToyDuck implements ToyDuck { public void squeak() { System.out.println( "Squeak" ); } } class BirdAdapter implements ToyDuck { // You need to implement the interface your // client expects to use. Bird bird; public BirdAdapter(Bird bird) { // we need reference to the object we // are adapting this .bird = bird; } public void squeak() { // translate the methods appropriately bird.makeSound(); } } class Main { public static void main(String args[]) { Sparrow sparrow = new Sparrow(); ToyDuck toyDuck = new PlasticToyDuck(); // Wrap a bird in a birdAdapter so that it // behaves like toy duck ToyDuck birdAdapter = new BirdAdapter(sparrow); System.out.println( "Sparrow..." ); sparrow.fly(); sparrow.makeSound(); System.out.println( "ToyDuck..." ); toyDuck.squeak(); // toy duck behaving like a bird System.out.println( "BirdAdapter..." ); birdAdapter.squeak(); } } |
输出:
Sparrow... Flying Chirp Chirp ToyDuck... Squeak BirdAdapter... Chirp Chirp
说明: 假设我们有一只会发声的鸟,还有一只会吱吱叫的塑料玩具鸭。现在假设我们的客户更改了要求,他希望toyDuck比? 简单的解决方案是,我们只需将实现类更改为新的适配器类,并告诉客户机将bird的实例(它想要squeak())传递给该类。 之前: ToyDuck ToyDuck=新塑料玩具鸭(); 之后: ToyDuck ToyDuck=新的鸟捕捉器(麻雀); 你可以看到,只要改变一行,toyDuck现在就可以发出唧唧唧唧的声音了!!
对象适配器与类适配器 我们在上面实现的适配器模式称为对象适配器模式,因为适配器持有adaptee的一个实例。还有另一种类型叫做类适配器模式,它使用继承而不是组合,但是需要多重继承来实现它。 类适配器模式的类图:
这里,适配器(组合)中没有adaptee对象来利用其功能,而是继承adaptee。
由于包括java在内的许多语言都不支持多重继承,并且与许多问题有关,所以我们没有展示使用类适配器模式的实现。
优势:
- 有助于实现可重用性和灵活性。
- 客户端类不需要使用不同的接口,并且可以使用多态性在适配器的不同实现之间交换。
缺点:
- 所有请求都会被转发,因此开销会略有增加。
- 有时,为了达到所需的类型,需要沿着适配器链进行许多调整。
进一步阅读: Python中的适配器方法
参考资料: 头先设计模式(书)
本文由 苏拉布·库马尔。 如果你喜欢GeekSforgeks,并且想贡献自己的力量,你也可以写一篇文章,然后把你的文章邮寄给评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。
如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论