zoukankan      html  css  js  c++  java
  • java设计模式之模板模式以及钩子方法使用

     正文前先来一波福利推荐:

     福利一:

    百万年薪架构师视频,该视频可以学到很多东西,是本人花钱买的VIP课程,学习消化了一年,为了支持一下女朋友公众号也方便大家学习,共享给大家。

    福利二:

    毕业答辩以及工作上各种答辩,平时积累了不少精品PPT,现在共享给大家,大大小小加起来有几千套,总有适合你的一款,很多是网上是下载不到。

    获取方式:

    微信关注 精品3分钟 ,id为 jingpin3mins,关注后回复   百万年薪架构师 ,精品收藏PPT  获取云盘链接,谢谢大家支持!

    -----------------------正文开始---------------------------

    1、使用背景

      模板方法模式是通过把不变行为搬到超类,去除子类里面的重复代码提现它的优势,它提供了一个很好的代码复用平台。当不可变和可变的方法在子类中混合在一起的时候,

    不变的方法就会在子类中多次出现,这样如果摸个方法需要修改则需要修改很多个,虽然这个这个问题在设计之初就应该想好。这个时候模板方法模式就起到了作用了,

    通过模板方法模式把这些重复出现的方法搬到单一的地方,这样就可以帮助子类摆脱重复不变的纠缠。

    2、已Spring中的  JdbcTemplate 使用模板模式为例  说明其优越之处;

    方法 execute(StatementCallback<T> sc) 方法公共方法,里边封装了可复用代码;

    参数StatementCallback是一个接口 接口方法是 doInStatement() 该方法是实现不同操作的方法;也就是不同的实现在这里呈现;

    public <L> L execute(StatementCallback<L> action)
        {
              
            try{ 
                        1. 加载驱动 
                        2. 建立连接 
                        3. 获取Statement stmt
                4. 拼接参数

    }
    catch(Exception e) { }

    try{

      synchronized (this) //使用同步锁 保护线程安全
      {
        return action.doInStatement(session);
      }
    }
    catch (HibernateException ex)
    {
      
    throw new Exception(ex);
    }
    catch (SQLException ex) {
    }

    finally{ 7. 销毁连接 } } }
    @Override
    public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
        Assert.notNull(sql, "SQL must not be null");
        Assert.notNull(rse, "ResultSetExtractor must not be null");
        if (logger.isDebugEnabled()) {
            logger.debug("Executing SQL query [" + sql + "]");
        }
        //匿名内部类
        class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
            @Override
            public T doInStatement(Statement stmt) throws SQLException {
                ResultSet rs = null;
                try {
                    rs = stmt.executeQuery(sql);
                    ResultSet rsToUse = rs;
                    if (nativeJdbcExtractor != null) {
                        rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
                    }
                    return rse.extractData(rsToUse);
                }
                finally {
                    JdbcUtils.closeResultSet(rs);
                }
            }
            @Override
            public String getSql() {
                return sql;
            }
        }
        //真正执行的方法
        return execute(new QueryStatementCallback());
    }

    调用query方法的时候 会执行execute方法,该方法为模板方法,然后因为该方法内部调用传入的 StatementCallback 接口的 doInStatement 方法 但是该方法可以在query方法中通过传入匿名内部类,自定义使用; 完全符合模板模式的使用;

    1、使用钩子方法对模板不同行为进行控制

    下面以一个汽车的例子来说明钩子方法的使用:

    public abstract class HummerModel {
        protected abstract void start(); //发动
        protected abstract void stop();  //停止
        protected abstract void alarm(); //鸣笛
        protected abstract void engineBoom(); //轰鸣
        final public void run() { //车总归要跑
            this.start();
            this.engineBoom();
            if(this.isAlarm()) {//想让它叫就叫,不想就不叫        
                this.alarm();
            }
            this.stop();
        }
        protected boolean isAlarm() { //我们加了一个判断方法,默认返回true
            return true;
        }
    }
    public class HummerH1 extends HummerModel {
     
        private boolean alarmFlag = true; //判断标记
        @Override
        public void start() {
            System.out.println("H1发动……");
        }
     
        @Override
        public void stop() {
            System.out.println("H1停止……");
        }
     
        @Override
        public void alarm() {
            System.out.println("H1鸣笛……");
        }
     
        @Override
        public void engineBoom() {
            System.out.println("H1轰鸣……");
        }
        
        @Override
        protected boolean isAlarm() { //覆写isAlarm方法,返回判断标记
            return this.alarmFlag;
        }
        
        public void setAlarm(boolean isAlarm) { //设置判断标记
            this.alarmFlag = isAlarm;
        }
        
    }
    这段代码中,我们在模板方法中增加了判断标记,然后子类对外提供一个public接口setAlarm来让外界设置这个判断标记,这个判断标记就像是开关一样,想让它ture和false都行。
    这个isAlarm方法俗称钩子方法。有了钩子方法的模板方法模式才算完美,使得我们的控制行为更加的主动,更加的灵活。

    
    
    
  • 相关阅读:
    Django
    MySql、Mongodb和Redis的区别
    数据库读写分离之配置Django实现数据库读写分离
    MySQL数据库优化
    01--web框架本质 wsgiref模块介绍
    CI上传图片 The filetype you are attempting to upload is not allowed.
    微信小程序 swiper和video的autoplay设置冲突问题
    关于手机端页面使用border-radius:50%不能使用div变为圆形问题
    微信小程序支付获取params的时候使用JsApiPay失败
    小程序使用笔记
  • 原文地址:https://www.cnblogs.com/gxyandwmm/p/9375843.html
Copyright © 2011-2022 走看看