zoukankan      html  css  js  c++  java
  • 设计模式之装饰者模式

    对一个方法进行增强有三种方式:

    1.继承

    2.装饰者模式(静态代理)

    3.动态代理(cglib)

    由于自定义jdbc连接池中会用到装饰者模式,在这里,我们先来介绍装饰者模式。

    定义:在不必改变原类文件和原类使用的继承情况下,动态的扩展一个对象的功能。

    操作:它是通过创建一个包装对象,也就是用装饰来包裹真实的对象来实现的。

    使用步骤:1.装饰者和被装饰者使用同一个接口或继承同一个类。(这样比较方便重写里面的方法)

         2.装饰者中要有被装饰者的引用  。(这样才能在装饰者的方法中对被装饰者进行增强,并且引用时可以提供一个构造方法,把被装饰者传入装饰者的构造方法中)

            3.对需要增强的方法进行增强。

         4.对不需要增强的方法调用原来的方法。(这里可以采用适配器模式,避免重写多个不需要重写的方法)

    拿车来举例子

    QQ车是一个普通的车,具有跑和停两个方法。

    public class QQ {
    
        public void run(){
            System.out.println("跑");
        }
        public void stop(){
            System.out.println("停");
        }
    }

    目标:使用装饰者类,对QQ车进行增强,让它变成QQ飞车跑 和急刹车停。

    首先需要定义一个接口或者父类,让它具有跑和停的方法,让装饰者类和被装饰者类继承它,这样方便对方法进行重写增强。

    public class Car {
    
        public void run(){}
        
        public void stop(){}
    }

    被装饰类继承父类:

    public class QQ extends Car{
    
        public void run(){
            System.out.println("跑");
        }
        public void stop(){
            System.out.println("停");
        }
    }

    装饰类:

    public class FlyCar extends Car{
        private QQ qq;
        
        public FlyCar() {  
            //因为下面提供了有参的构造方法,所以必须重写无参的构造方法
        }
        
        public FlyCar(QQ qq){
                //提供了有参的构造方法,把被装饰者传入装饰者类中
            this.qq = qq;
        }
        @Override
        public void run() {
            System.out.print("fly car "); //对方法进行增强
            qq.run();
        }
        @Override
        public void stop() {
            System.out.print("急刹车   "); //对方法进行增强
            qq.stop();
        }
    }

    测试代码:

    public class Test {
    
        public static void main(String[] args) {
            QQ qq = new QQ();
            qq.run();
            qq.stop();
            System.out.println("被装饰后:运行结果-----");
            FlyCar f = new FlyCar(new QQ());
            f.run();
            f.stop();
        }
    }

    运行结果:

    跑
    停
    被装饰后:运行结果-----
    fly car 跑
    急刹车   停

    这个例子可以看到:没有改变原来的QQ类,同时也没有定义QQ类的子类来实现扩展。

    优点:

    使用装饰者模式比使用继承更加灵活,因为是一个动态的方式扩展一个对象的功能,在运行时可以选择不同的装饰器,从而实现不同的行为,

    通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。

    低耦合。具体装饰类和具体被装饰类可以独立变化,可以根据需要来增加具体的装饰类和被装饰类,使用时进行组合,原有代码无需改变。符合“开闭原则”。

    六大设计原则之开闭原则:对扩展开放,对修改关闭

    缺点:

    会产生很多小对象,增加系统的复杂性

    排错比较困难,对于多次装饰的对象,寻找错误需要逐级排查,不方便。

    在自定义jdbc连接池中,我们需要对connection的close()方法进行装饰,让它的close()方法归还连接,而不是直接销毁连接。

    使用场景:

    需要扩展一个类的功能,或给一个类添加附加指责。

    动态的给一个对象添加功能,不用可以随时动态的撤销掉。

    需要增加由一些基本功能的排列组合而产生的非常大量的功能,使用继承不太现实

    类定义被隐藏或类定义不能生成子类时。

  • 相关阅读:
    Hibernate执行访问步骤及增删改查
    Tuscany SCA 发布Web Service
    AJAX概述
    WSDL概述与结构
    Android常用的简单代码
    volatile/synchronized
    SOAP概述和结构
    [原]spring学习笔记6.补遗2
    [原]spring学习笔记9.1Spring对Aop的支持AOP基础篇
    [转]转个经典的帖子:说故事学设计模式之Java静态代理模式
  • 原文地址:https://www.cnblogs.com/tonbby/p/9031630.html
Copyright © 2011-2022 走看看