700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 设计模式-结构型模式讲解下(装饰者 外观 代理)

设计模式-结构型模式讲解下(装饰者 外观 代理)

时间:2018-08-17 11:54:31

相关推荐

设计模式-结构型模式讲解下(装饰者 外观 代理)

一、结构型设计模式

上篇,我们讲解了结构型设计模式的适配器、桥接、组合、享元模式。

文章地址:/qq_43692950/article/details/120248267

这篇文章我们讲解下 结构型设计模式的装饰者、外观、代理模式。

二、装饰者模式

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。它是作为现有的类的一个包装。

装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

举个例子:还是用上篇文章例子中的绘画不同的形状的例子,加入系统中有画各种形状的功能,但随着功能后期的演化,需要画出带有边框的各种形状,那么此时就可以采用装饰者设计模式来做增强。

下面使用程序演示下上面的例子:

定义形状接口

public interface Shape {void draw();}

定义圆形的实现

public class Circle implements Shape {@Overridepublic void draw() {System.out.println("开始画圆形!");}}

定义矩形的实现

public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("开始画矩形!");}}

定义装饰器的抽象模板

public abstract class ShapeDecorator implements Shape {protected Shape decoratedShape;public ShapeDecorator(Shape decoratedShape){this.decoratedShape = decoratedShape;}@Overridepublic void draw(){decoratedShape.draw();} }

定义具体的边框装饰器

public class BorderShapeDecorator extends ShapeDecorator {public BorderShapeDecorator(Shape decoratedShape) {super(decoratedShape);}@Overridepublic void draw() {decoratedShape.draw(); setRedBorder(decoratedShape);}private void setRedBorder(Shape decoratedShape){System.out.println("画边框!");}}

演示

public class demo {public static void main(String[] args) {Shape circle = new Circle();circle.draw();Shape shape = new BorderShapeDecorator(new Circle());shape.draw();Shape shape1 = new BorderShapeDecorator(new Rectangle());shape1.draw();}}

上面可以看出再不改变原先类的基础上,做了画边框的效果,对原有做增强,使用装饰者设计模式,可以大大提高系统的可扩展性。

三、外观模式

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。它向现有的系统添加一个接口,来隐藏系统的复杂性。

这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。

它的优点是可以减少系统相互依赖、提高灵活性、提高了安全性。但是它不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。

举个例子:还是画各种图形的例子,比如要画圆形、矩形、三角形,没画一种图像都要拿到对应的抽象,并调用绘制方法,如果要画的形状过多,这么多的抽象就不好管理了,而如果使用外观设计模式,提供一个统一的抽象,在这个抽象中就可以完成上面不同的绘制,这样就方便了我们的管理。

下面使用程序演示下上面的例子:

定义形状的接口

public interface Shape {void draw();}

定义圆形的实例

public class Circle implements Shape {@Overridepublic void draw() {System.out.println("开始画圆!");}}

定义矩形的实例

public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("开始画矩形!");}}

定义三角形的实例

public class Triangle implements Shape {@Overridepublic void draw() {System.out.println("开始画三角形!");}}

定义一个外观类,并调用上面的功能

public class ShapeFacade {private Shape circle;private Shape rectangle;private Shape square;public ShapeFacade() {circle = new Circle();rectangle = new Rectangle();square = new Triangle();}public void drawCircle(){circle.draw();}public void drawRectangle(){rectangle.draw();}public void drawSquare(){square.draw();}}

演示

public class demo {public static void main(String[] args) {ShapeFacade shapeFacade = new ShapeFacade();shapeFacade.drawCircle();shapeFacade.drawRectangle();shapeFacade.drawSquare();}}

外观设计模式还是比较容易理解的,就是把多个功能统一整个到一个对象中,由这个对象再去调用具体的类和方法。

四、代理设计模式

通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理。既(AOP微实现) 。

代理有分静态代理和动态代理,静态代理就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。而动态代理是在我们使用时,动态的生成代理对象,他是在内存中构建代理对象的。

举个例子,在做数据库操作时,一般我们都会在事物中做SQL的操作,那就需要在操作前开启事物,操作后如果成功就需要提交事物,如果代用代理设计模式,就可以将事物开启提交逻辑放在代理类中,被代理的类,只需要关注业务逻辑即可。

我们以支付和事物为例演示下,代理模式

1. 采用静态代理,实现上面例子

定义支付接口

public interface PayInterFace {void pay();}

定义微信支付实现

public class WxPay implements PayInterFace {@Overridepublic void pay() {System.out.println("支付中...");}}

定义支付的代理类

public class PayProxy implements PayInterFace {private WxPay pay;public PayProxy(WxPay pay) {this.pay = pay;}@Overridepublic void pay() {System.out.println("事物开始!");pay.pay();System.out.println("提交事物!");}}

演示

public class demo {public static void main(String[] args) {PayInterFace pay = new PayProxy(new WxPay());pay.pay();}}

上面的静态代理,可以看出,我们需要对每个被代理对象设计一个代理类,如果代理的功能非常多,那就需要开发人员写特别多的代理类,下面可以看下动态代理的使用。

2. 采用动态代理,实现上面例子

这里使用JDK自带的动态代理来实现

还是上面的例子,我们再定义一个支付宝的支付实现

public class ZfbPay implements PayInterFace {@Overridepublic void pay() {System.out.println("支付宝支付中...");}}

定义代理对象,采用jdk的 InvocationHandler 接口

public class PayProxy implements InvocationHandler {private Object object;public PayProxy(Object object) {this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("事物开始!");Object result = method.invoke(object, args);System.out.println("提交事物!");return result;}}

演示

public class demo {public static void main(String[] args) {PayInterFace pay = (PayInterFace) Proxy.newProxyInstance(PayInterFace.class.getClassLoader(),new Class[]{PayInterFace.class},new PayProxy(new WxPay()));pay.pay();PayInterFace pay1 = (PayInterFace) Proxy.newProxyInstance(PayInterFace.class.getClassLoader(),new Class[]{PayInterFace.class},new PayProxy(new ZfbPay()));pay1.pay();}}

上面使用一个代理类,代理了多个对象,相对于静态代理,是代码更简介,灵活性也更高。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。