一文带你厉害Java设计模式中的模板方法

一文带你厉害Java设计模式中的模板方法

什么是模板方法

模板方法是一种设计模式,其基本思路是定义一个算法的框架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法框架的情况下重新定义算法中的某些步骤。

模板方法的结构

模板方法包含两部分:抽象父类和具体实现子类。抽象父类定义了算法的框架,包括一些抽象方法;具体实现子类实现了抽象父类中的抽象方法。

以下是模板方法的结构:

public abstract class AbstractClass {
    protected abstract void primitiveOperation1();
    protected abstract void primitiveOperation2();

    final public void templateMethod() {
        primitiveOperation1();
        primitiveOperation2();
    }
}

public class ConcreteClass extends AbstractClass {
    @Override
    protected void primitiveOperation1() {
        // 具体实现1
    }

    @Override
    protected void primitiveOperation2() {
        // 具体实现2
    }
}

模板方法的优缺点

优点

  1. 提高代码的复用性,将公共部分抽象到父类中,避免重复代码。
  2. 提高扩展性,可以很方便地增加新的算法流程。
  3. 提高安全性,由于模板方法中的算法框架是固定的,避免了子类不当操作造成的风险。

缺点

  1. 需要把算法的框架固定下来,使得算法不能灵活变化。
  2. 继承关系过多,导致程序复杂。

示例1:炒菜模板方法

现在我们来写一个简单的例子,来解释模板方法的使用。

假设我们要用模板方法来实现一个“炒菜”的过程。

首先,我们需要定义一个抽象类Cook,其内部包含了一个炒菜的方法cook(),该方法是一个固定的算法框架。然后,我们再定义一个具体实现类EggplantPork分别实现Cook类,并重写cook()方法,完成炒茄子和炒肉的过程。

下面是示例代码:

public abstract class Cook {
    public final void cook() {
        prepare();
        stir_fry();
        cookRice();
    }

    abstract void prepare();

    abstract void stir_fry();

    void cookRice() {
        System.out.println("煮米饭");
    }
}

public class Eggplant extends Cook {
    @Override
    void prepare() {
        System.out.println("准备茄子");
    }

    @Override
    void stir_fry() {
        System.out.println("炒茄子");
    }
}

public class Pork extends Cook {
    @Override
    void prepare() {
        System.out.println("准备肉");
    }

    @Override
    void stir_fry() {
        System.out.println("炒肉");
    }
}

我们可以通过以下代码来调用:

Cook c1 = new Eggplant();
c1.cook();  // 准备茄子、炒茄子、煮米饭

Cook c2 = new Pork();
c2.cook();  // 准备肉、炒肉、煮米饭

运行结果如下:

准备茄子
炒茄子
煮米饭

准备肉
炒肉
煮米饭

示例2:JDBC模板方法

JDBC模板方法是一种常见的模板方法模式的应用。在JDBC中,我们可以使用模板方法来处理数据库的连接、事务以及SQL语句的执行,提高代码的复用性和可维护性。

下面是一个简单的JDBC模板方法的示例:

public abstract class JdbcTemplate {
    protected abstract String getUrl();
    protected abstract String getUsername();
    protected abstract String getPassword();

    public final <T> T execute(String sql, RowMapper<T> rowMapper) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // 获取数据库连接
            conn = DriverManager.getConnection(getUrl(), getUsername(), getPassword());
            // 开始事务
            conn.setAutoCommit(false);
            // 执行SQL语句
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            // 处理结果集
            List<T> result = new ArrayList<>();
            while (rs.next()) {
                result.add(rowMapper.mapRow(rs));
            }
            // 提交事务
            conn.commit();
            return result;
        } catch (SQLException e) {
            // 回滚事务
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            throw new RuntimeException(e);
        } finally {
            // 释放资源
            try {
                if (rs != null) rs.close();
                if (ps != null) ps.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

public interface RowMapper<T> {
    T mapRow(ResultSet rs) throws SQLException;
}

我们可以使用以下代码来调用:

String sql = "SELECT id, name FROM person";
List<Person> result = new JdbcTemplate() {
    @Override
    protected String getUrl() {
        return "jdbc:mysql://localhost:3306/test";
    }

    @Override
    protected String getUsername() {
        return "root";
    }

    @Override
    protected String getPassword() {
        return "123456";
    }
}.execute(sql, rs -> {
    Person p = new Person();
    p.setId(rs.getInt("id"));
    p.setName(rs.getString("name"));
    return p;
});

总结:

模板方法是一种十分常用的设计模式,其可以大大减少代码的重复量,同时提高代码的可读性以及可维护性。在实践中,我们可以针对不同情况应用不同的模板方法模式,来达到我们想要的效果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一文带你厉害Java设计模式中的模板方法 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • php实现parent调用父类的构造方法与被覆写的方法

    在PHP中,我们可以通过使用parent关键字来调用父类的构造方法与被覆写的方法。下面,我将详细讲解如何实现这个过程。 调用父类的构造方法 在子类中覆写了父类的构造方法后,如果我们需要调用父类的构造方法,就可以使用parent关键字来完成。 以下是一个示例代码: class Animal { protected $name; public function …

    other 2023年6月27日
    00
  • 翻译qmake文档(三) Creating Project Files

    翻译qmake文档(三) Creating Project Files 在上一篇翻译qmake文档的文章中,我们介绍了qmake文件的基础知识和语法,以及如何指定源文件和头文件等。在本篇文章中,我们将进一步介绍如何创建项目文件。 创建项目文件 在使用qmake创建项目文件之前,需要先了解几个概念: 1. 项目文件 项目文件是一个.qmake文件,用于定义整个…

    其他 2023年3月28日
    00
  • Activity跳转时生命周期跟踪的实例

    下面我将详细讲解“Activity跳转时生命周期跟踪的实例”的完整攻略。 一、背景知识 在 Android 应用中,Activity 生命周期一直是我们开发者们必须要掌握的关键技术点。对 Android 开发者来说,了解 Activity 生命周期就像了解控制流一样重要。在编写 Android 应用程序时,我们需要了解 Activity 被创建、启动、暂停、…

    other 2023年6月27日
    00
  • windows系统搭建WEB服务器详细教程

    下面我给你详细讲解“windows系统搭建WEB服务器详细教程”的完整攻略。该攻略主要分为以下几步: 步骤1:选择合适的Web服务器软件 在Windows系统上,常用的Web服务器软件有IIS、Apache、Nginx等。其中,IIS是Windows系统自带的Web服务器软件,但其功能和灵活性相对较弱,不推荐使用。而Apache和Nginx是开源免费的Web…

    other 2023年6月27日
    00
  • 用python获取列表的最后一个元素

    在Python中,获取列表的最后一个元素可以使用索引或切片。以下是获取列表最后一个元素的详细攻略: 使用索引 可以使用负数索引来获取列表的最后一个元素。例如,如果列表名为my_list,则可以使用以下代码获取最后一个元素: last_element = my_list[-1] 其中,-1表示最后一个元素的索引。 使用切片 可以使用切片来获取列表的最后一个元素…

    other 2023年5月8日
    00
  • cnpm安装失败及解决方案

    以下是关于cnpm安装失败及解决方案的完整攻略,包括常见问题和两个示例说明。 常见问题 1. 安装失败 当使用cnpm安装时,可能会遇到以下错误: npm ERR! code ECONNRESET npm ERR! code EINTEGRITY npm ERR! code ENOENT npm ERR! code ENOTFOUND npm ERR! co…

    other 2023年5月9日
    00
  • log4j.properties 配置(实例讲解)

    下面是 “log4j.properties配置(实例讲解)” 的完整攻略: 什么是log4j.properties? log4j是一个Java语言的日志记录工具,它让我们可以更方便、更高效地记录程序运行时的信息。log4j.properties是log4j的配置文件,它可以设置log4j如何记录日志信息,包括输出到哪些文件、控制台还是网络等等。下面我们来详细…

    other 2023年6月25日
    00
  • 【hyperscan】编译hyperscan 4.0.0

    【hyperscan】编译hyperscan 4.0.0 在编写高效的网络安全应用程序时,使用快速而精确的模式匹配算法是非常重要的。Hyperscan是一款支持使用正则表达式进行高性能扫描的工具包,可以在包括x86、x64和ARM在内的多种平台上运行。在本文中,我们将介绍如何编译最新版本的Hyperscan(4.0.0)。 准备工作 在开始编译之前,需要进行…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部