墨风如雪博客

  • 源码小店
  • 传家宝VPS
让AI使用变得如此简单
  1. 首页
  2. java
  3. 设计模式
  4. 正文

设计模式:模板方法模式

2023年 5月 12日 208点热度 0人点赞 0条评论

模板方法设计模式介绍

模板方法设计模式是一种行为型设计模式,它定义了一个算法的骨架,将算法中一些步骤的具体实现延迟到子类中。模板方法模式使得子类可以在不改变算法骨架的情况下重新定义算法中某些步骤的具体实现。

模板方法模式通常包含以下角色:

  1. 抽象类(Abstract Class):定义了一个模板方法,该方法中包含了算法的骨架和一些抽象方法,用于延迟到子类中实现。

  2. 具体类(Concrete Class):实现了抽象类中的抽象方法,并提供算法的具体实现。

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

// 抽象类
public abstract class AbstractClass {
    // 模板方法
    public final void templateMethod() {
        // 调用基本方法
        operation1();
        // 调用钩子方法
        if (hookMethod()) {
            operation2();
        }
        // 调用基本方法
        operation3();
    }

    // 基本方法1
    public abstract void operation1();

    // 基本方法3
    public abstract void operation3();

    // 钩子方法
    public boolean hookMethod() {
        return true;
    }

    // 抽象方法2,由子类实现
    public abstract void operation2();
}

// 具体类
public class ConcreteClass extends AbstractClass {
    public void operation1() {
        System.out.println("ConcreteClass: operation1");
    }

    public void operation2() {
        System.out.println("ConcreteClass: operation2");
    }

    public void operation3() {
        System.out.println("ConcreteClass: operation3");
    }
}

// 测试类
public class TemplateMethodPatternDemo {
    public static void main(String[] args) {
        AbstractClass abstractClass = new ConcreteClass();
        abstractClass.templateMethod();
    }
}

在这个例子中,我们定义了一个抽象类AbstractClass,其中包含了一个模板方法templateMethod()和一些基本方法和钩子方法,用于延迟到子类中实现。然后,我们创建了一个具体类ConcreteClass,继承自AbstractClass,并实现了其中的抽象方法。最后,在客户端应用程序中,我们创建了一个AbstractClass对象,并通过它的模板方法templateMethod()调用算法。

通过模板方法模式,我们可以将算法的骨架与具体的实现分离开来,并允许子类重新定义算法中的某些步骤,从而提高代码的复用性和可维护性。

spring当中的使用

在Spring框架中,模板方法模式被广泛应用,其中最常见的应用是JdbcTemplate类。JdbcTemplate类是Spring框架提供的一个数据库访问工具,它封装了JDBC API,提供了一种更加简单和易用的方式来访问数据库。JdbcTemplate使用模板方法模式实现了数据库操作的统一流程,从而方便了开发人员进行数据库访问。

下面是一个使用Spring的JdbcTemplate类的例子:

// 定义一个 DAO 接口
public interface UserDao {
    void addUser(User user);
    void updateUser(User user);
    void deleteUserById(Long id);
    User getUserById(Long id);
}

// 实现 DAO 接口
@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void addUser(User user) {
        String sql = "INSERT INTO users(id, name, age) VALUES(?, ?, ?)";
        jdbcTemplate.update(sql, user.getId(), user.getName(), user.getAge());
    }

    public void updateUser(User user) {
        String sql = "UPDATE users SET name = ?, age = ? WHERE id = ?";
        jdbcTemplate.update(sql, user.getName(), user.getAge(), user.getId());
    }

    public void deleteUserById(Long id) {
        String sql = "DELETE FROM users WHERE id = ?";
        jdbcTemplate.update(sql, id);
    }

    public User getUserById(Long id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper());
    }
}

// 定义一个行映射器
public class UserRowMapper implements RowMapper<User> {
    public User mapRow(ResultSet rs, int rowNum) throws SQLException {
        User user = new User();
        user.setId(rs.getLong("id"));
        user.setName(rs.getString("name"));
        user.setAge(rs.getInt("age"));
        return user;
    }
}

// 使用 DAO
public class Application {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserDao userDao = context.getBean(UserDao.class);

        // 添加用户
        User user1 = new User(1L, "Alice", 20);
        userDao.addUser(user1);

        // 更新用户
        User user2 = new User(1L, "Bob", 25);
        userDao.updateUser(user2);

        // 获取用户
        User user3 = userDao.getUserById(1L);
        System.out.println(user3);

        // 删除用户
        userDao.deleteUserById(1L);
    }
}

// 定义配置类
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        // 配置数据源
    }

    @Bean
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(dataSource());
    }

    @Bean
    public UserDao userDao() {
        return new UserDaoImpl();
    }
}

在这个例子中,我们定义了一个DAO接口UserDao和其实现类UserDaoImpl,其中使用了Spring的JdbcTemplate类来访问数据库。JdbcTemplate类使用模板方法模式实现了数据库操作的统一流程,从而方便了开发人员进行数据库访问。通过在配置类中注入JdbcTemplate和DataSource对象,我们可以在DAO实现类中直接使用JdbcTemplate对象来执行数据库操作。

Spring的JdbcTemplate类是模板方法模式的一个典型应用,它将数据库操作的过程抽象成一个模板方法,并将一些基本方法和钩子方法延迟到子类中实现。通过使用JdbcTemplate类,我们可以方便地进行数据库访问,同时避免了一些重复的代码和错误处理逻辑。

过度设计的后果

过度使用模板方法设计模式可能会引发以下问题:

  1. 破坏封装性:模板方法设计模式需要将算法的骨架封装在抽象类中,而将具体的实现延迟到子类中实现。如果过度使用模板方法设计模式,可能会导致抽象类中的代码变得过于复杂,从而破坏了封装性,使得系统难以理解和维护。

  2. 限制扩展性:模板方法设计模式将算法的骨架固定在抽象类中,而将具体的实现延迟到子类中实现。如果需要对算法进行扩展,可能需要修改抽象类的代码,从而影响到所有的子类。这样的设计可能会限制系统的扩展性,使得系统难以应对变化和需求的变化。

  3. 降低代码的灵活性:模板方法设计模式需要将算法的骨架固定在抽象类中,而将具体的实现延迟到子类中实现。这种设计可能会使得代码的灵活性降低,并且难以应对不同的算法和需求的变化。

  4. 多层继承问题:如果过度使用模板方法设计模式,可能会导致多层继承的问题。由于子类需要继承抽象类中的方法,而抽象类又继承自其他的抽象类,这可能会导致类层次结构变得过于复杂,从而影响系统的可维护性和可扩展性。

因此,在使用模板方法设计模式时,需要谨慎使用,并避免过度使用。需要根据具体的场景和需求进行设计和选择,保证设计的可维护性、可扩展性和灵活性。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: java 介绍 教程 模板方法设计模式 设计模式
最后更新:2023年 5月 10日

墨风如雪

一个热爱生活,热爱分享的程序员

打赏 点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

墨风如雪

一个热爱生活,热爱分享的程序员

最新 热点 随机
最新 热点 随机
腾讯混元MT-7B:打破参数迷思,重塑机器翻译版图 瑞士AI宣言:Apertus如何定义开放大模型 月之暗面Kimi K2-0905:代码与创意的新篇章? 谷歌“蕉”傲登场!AI生图告别“走钟”时代 2025,AI世界模型新篇章:腾讯混元Voyager展望 单GPU秒产一分钟!MAI-Voice-1,微软语音AI的“核爆”时刻?
别再卷万亿参数了,这个4B模型正把AI工作站塞进你的手机全球最佳开放模型!OpenAI开源GPT-OSS,AI界迎来巨变!声音即影像:昆仑万维SkyReels-A3如何叩响内容创作的革命前夜9B参数硬撼72B,GLM-4.1V凭什么搅动AI江湖?2B参数掀翻巨头牌桌:昆仑万维UniPic 2.0的“四两拨千斤”天工V2发布:AI终于撕掉了“纯文本”的标签
Java中的多线程编程 9B参数硬撼72B,GLM-4.1V凭什么搅动AI江湖? java spring 当中后置处理器 Java中的构造器(构造方法)和this关键字 java IOC框架Google Guice的(超详细总结) 无缝衔接设备跨平台本地AI好助手:OllamaTalk 部署教程与深度解析
标签聚合
java 大模型 spring deepseek 算法 教程 设计模式 AI

COPYRIGHT © 2023 墨风如雪博客. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang