适配器模式

这种模式很容易理解,因为现实世界充满了适配器。例如,考虑一个USB到以太网适配器。当一端有以太网接口,另一端有USB接口时,我们需要这个。因为他们彼此不相容。我们使用一个适配器将一个转换为另一个。这个例子非常类似于面向对象的适配器。在设计中,当我们有一个类(客户机)需要某种类型的对象,而有一个对象(Adaptee)提供相同的功能,但公开不同的接口时,就会使用适配器。

null

要使用适配器,请执行以下操作:

  1. 客户端通过使用目标接口调用适配器上的方法向适配器发出请求。
  2. 适配器使用adaptee接口在adaptee上转换该请求。
  3. 客户端接收到呼叫结果,并且不知道适配器的存在。

定义:

适配器模式将一个类的接口转换为客户机期望的另一个接口。Adapter允许由于接口不兼容而无法正常工作的类一起工作。

类图: ad3

客户端只看到目标接口,而不看到适配器。适配器实现目标接口。适配器将所有请求委托给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的一个实例。还有另一种类型叫做类适配器模式,它使用继承而不是组合,但是需要多重继承来实现它。 类适配器模式的类图:

pattern4

这里,适配器(组合)中没有adaptee对象来利用其功能,而是继承adaptee。

由于包括java在内的许多语言都不支持多重继承,并且与许多问题有关,所以我们没有展示使用类适配器模式的实现。

优势:

  • 有助于实现可重用性和灵活性。
  • 客户端类不需要使用不同的接口,并且可以使用多态性在适配器的不同实现之间交换。

缺点:

  • 所有请求都会被转发,因此开销会略有增加。
  • 有时,为了达到所需的类型,需要沿着适配器链进行许多调整。

进一步阅读: Python中的适配器方法

参考资料: 头先设计模式(书)

本文由 苏拉布·库马尔。 如果你喜欢GeekSforgeks,并且想贡献自己的力量,你也可以写一篇文章,然后把你的文章邮寄给评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。

如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享