设计模式的学习 总结(1)代理模式,适配器模式,外观模式和装饰器模式的异同

原创
2018/12/27 18:06
阅读数 559

一、定义

代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。代理类需要持有一个真实对象,用来对真实对象进行访问。

适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口,使得原本接口不兼容而不能一起工作的那些类可以一起工作。

适配器类提供新的接口给用户调用,同时需要持有一个被适配类的对象,在适配器类的接口方法中,经过自己的特定逻辑后,最终还是会调用被适配的类对象的老接口。

即一个三孔的插头,进过适配器类的处理后,能插进原有的二孔插座里。

外观模式(Facade):我们定义一个中间层(外观类),为客户端提供可以调用的接口。同时该接口可能调用子系统中的一组接口,从而隐藏系统的复杂性。

即在外观类的方法中,对原有系统的接口进行组合和封装,方便使用者使用。外观类需要持有各个子类的对象,通过这些对象调用子系统接口。

装饰器模式(Decorator):原有的类结构不变,但是功能不能满足现有的需求,对原有的功能进行增强。装饰器类需要持有一个被装饰类对象。

二类图

代理模式

可以看到,真实对象和代理类,需要实现一个共同接口,所以他们具有共同的方法。

用户创建一个接口对象,实际上是代理类的实现。就是说用户访问的是代理类对象,执行的是代理类重写的方法。

而一个代理类的构建,需要一个真实对象(可以在构建方法中new一个真实对象,还可以在构建方法中,传入一个真实对象)。代理类可以通过这个真实对象进行交互调用到真实对象的方法。在调用真实对象方法的前后,添加自己的特定逻辑。

Subject subject = new Proxy(new RealSubject());

subject.request();

 

适配器模式

可以看到,首先我们要定义一个目标接口Target,该接口定义了给外部请求者使用的接口。

然后定义一个适配器类Adapter,它实现了目标接口,重写了接口中定义的方法。

然后在适配器类中,我们需要引入一个需要适配的类对象。这里有分歧,可以通过

对象方式引入

就是适配器类Adapter可以定义一个成员属性为需要适配的类的对象Adaptee,在构造方法中new一个或者传入一个需要适配的类的对象。

然后在重写的Request()方法时,去执行自己的特殊逻辑,并通过Adaptee对象,去调用原有的接口方法。

类方式引入

就是适配器类Adapter即实现目标接口Target,又继承需要适配的类Adaptee,然后在用户执行Request()方法时,执行完适配器的逻辑后,

可以通过super.SpecificRequest()的方式,调用到原有的接口方法。

 

这里就会显出代理模式和适配器模式最大的区别,代理模式是与原对象实现同一个接口,而适配器类则是匹配新接口,说白了,实现一个新的接口。

外观模式

定义外观类,和暴露给用户使用的接口方法。

外观类等于新增加了一层,对已有系统接口的封装。

比如用户要实现某个功能,需要调用多个不同类型的接口方法,才能完成用户希望的操作。

这时外观类给用户提供一个接口,用户请求后就可以得到想要的结果,而不同类型的调用,复杂的逻辑,交给外观类处理。

 

外观模式,说白了就是为系统和用户之间, 增加一层接口的封装,由外观类去处理复杂的接口调用和逻辑,最后返回用户想要的结果。就像spring mvc中的controller层一样。

装饰器模式

装饰器类需要和被装饰类,实现同一个接口,并且装饰器类,需要持有一个被装饰类对象。或者装饰器类直接继承被装饰类,

装饰器类是对被装饰类的功能的增强,所以装饰器类可以增加自己的属性和方法,用于功能的增强。

即装饰器类在重写了被装饰类的方法中,不但可以通过持有的被装饰类对象进行原有接口的调用,还可以调用自己的增强方法。

三、总结

代理模式:代理模式主要体现隔离。代理类和真实对象实现同一个接口,拥有共同的方法。代理类持有被代理类对象,访问者无法直接访问到真实对象,只能通过代理类访问真实对象。体现使用中,就是代理类含有的方法名称和入参和被代理类一模一样。

适配器模式:用户访问新接口,适配器不但实现新接口的方法,还持有一个原有接口对象,在实现新接口的方法中,处理自己的特定逻辑,最后调用原有接口方法,达到适配的目的。体现使用中,就是适配器可以定义新的方法名称和入参,然后在方法里经过自己的逻辑处理,再调用被代理类的老方法。

外观模式:增加一层接口的封装,简化使用者的操作。就像spring mvc的service层,service层的一个方法活接口对应一个指定的功能。service层又持有很多 mapper层对象,每个service方法,都通过mapper对象完成了复杂的增删改查工作,但是对controller层来说,它只是调用了service层的一个方法,而根本不知道有mapper层的存在。

装饰器模式:装饰器类是对被装饰类的增强。实现方式有两种:装饰器类和被装饰类,可以实现同一个接口,同时装饰器类持有一个被装饰类对象。也可以让装饰器类直接继承被装饰类。在装饰器类中,增加新的成员属性和方法。比如被装饰类是Circle,它只有一个方法draw(),那么装饰器类CircleDecorator,可以增加一个属性color,并增加setColor()方法,重写draw()方法时,里面添加一行setColor("red")。那么当用户调用修饰器类的draw()方法时,就可以画出一个红色的圆形。体现在使用上,首先如果装饰器类直接继承被装饰类,它是可以通过super.methodA()来调用被装饰器方法的。

装饰器模式与适配器模式的不同:

装饰器模式的目的:调用装饰器方法,增强被装饰类,返回一个比被装饰类功能更强,数据更多的结果(需要调用被装饰类原来的方法)。

实现方式:装饰器类和被装饰类实现同一个接口,并且持有被装饰类对象;或者继承被装饰类。

调用方式:客户端调用的是装饰器的方法,在装饰器的方法里增强被装饰方法。

 

适配器模式的目的:调用适配器的新方法(方法名称和入参都可以和老方法不一样),但是最终要返回老方法的结果。

实现方式:适配器类,直接实现了新的接口和方法,它是通过持有一个被适配类对象当成员变量,或者继承被适配类。然后当客户端调用适配器类的方法时,经过适配器类方法的逻辑处理,最后再调用被适配器类的对象,返回老方法结果。就好比一个service层的方法,调用了另一个service的方法并返回结果。

调用方式:客户端调用的是适配器方法,在适配器的方法里调用被适配方法。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部