设计模式笔记(十三)– 适配器模式

​适配器模式(Adapter Pattern)用于将类的接口转换成不同的形式。


问题提出

假设我们要创建一个移动应用程序,它用于给拍的照片或加载的图片应用各种各样的滤镜。

创建类Image。

创建接口Filter,并定义apply方法。

创建VividFilter类,实现Filter接口。

接着,创建类ImageView,它有image属性和apply方法。

然后在main中创建ImageView对象,并应用VividFilter滤镜。

现在,假设有一个第三方滤镜库,它有数十个漂亮的滤镜,我们不想从头编写这些滤镜,我们想重用这些滤镜。

我们来模拟下。

创建包avaFilters,表示第三方滤镜库。再在其下创建类Caramel模拟某个第三方滤镜,它有方法init(),render(Image image)。

我们尝试应用这个Caramel滤镜,将提示错误,因为第三方的Caramel没有实现Filter接口,不被接受。

解决这个问题,就要用到适配器模式(Adapter Pattern)了。

利用适配器模式,我们可以转接类的接口,以适应我们的需要。


解决方案

当前我们的结构是这样的。

我们不能使用Caramel类是因为该类没有实现Filter接口,它是我们从第三方库引入的,我们不能改变它的源代码。

因此,我们先在图中移除VividFilter类,添加一个CamamelFilter类,该类实现了Filter接口。

CaramelFilter类持有caramel对象,我们将要应用滤镜的图像通过CaramelFilter传递给caramel。

这就是适配器模式(Adapter Pattern)。

适配器模式非常有用,当我们要使用一个现有类但该类的接口形式不符合我们的要求时,就可以使用该模式。

在图中,CaramelFilter类充当了适配器角色,而Caramel则是要适配的对象。


代码实现

适配器模式的代码非常简单。

创建类CaramelFilter实现Filter接口,它有一个caramel对象,在apply方法里,调用caramel的方法,这里是init()和render(image)。

在Main里测试结果。

应用滤镜:(new CaramelAdapter(new Caramel()))。

很简单。

我们这里使用了组合的方式,即CamamelAdapter类由caramel对象组成。还可以使用继承方法来实现,我们来看一下。

我们修改CaramelAdapter,它除了实现Filter接口还继承于Caramel类,这样我们可以去掉caramel对象。在Main里,滤镜应用是:(new CaramelAdapter())。

然而,使用继承不如使用组合灵活,因为Java不支持多重继承,一个类只能拥有一个父类。

记住这个原则:优先使用组合而不是继承


小结

适配器模式(Adapter Pattern)用于将类的接口转换成不同的形式。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注