【模板方法设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

这篇具有很好参考价值的文章主要介绍了【模板方法设计模式详解】C/Java/JS/Go/Python/TS不同语言实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介

模板方法模式(Template Method Pattern)也叫模板模式,是一种行为型模式。它定义了一个抽象公开类,包含基本的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构,只是重定义该算法的某些特定步骤。不同的子类以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。以此基于公共的模板,来实现实现不同的功能。

模板模式适用于一些复杂操作进行步骤分割、抽取公共部分由抽象父类实现、将不同的部分在父类中定义抽象实现、而将具体实现过程由子类完成。对于有多个子类具有共有的方法,且逻辑相同,可以考虑作为模板方法。

作用

  1. 相同的部分父类给出统一的模板,子类大量复用,从而节省代码,复用逻辑。
  2. 封装不变部分,扩展可变部分,行为由父类控制,子类灵活实现,便于维护和扩展。

实现步骤

  1. 创建一个抽象的模板类,定义基本流程,同时定义一些基本方法供子类去实现。
  2. 创建多个子类继承抽象模板,覆盖父类的相关动作和方法。

UML

 
template-pattern.png

Java代码

抽象模板类

// GameTemplate.java 定义抽象模板类,有抽象方法和具体方法
public abstract class GameTemplate {

   // 抽象方法待子类来实现
   abstract void init();

   abstract void start();

   abstract void end();

   // 可复用的算法流程
   public void play() {

      System.out.println(this.getClass().getSimpleName() + "::play()");

      // 初始化游戏
      init();

      // 开始游戏
      start();

      // 结束游戏
      end();
   }

}

具体业务类,继承抽象模板

// Basketball.java  定义子类覆写父类抽象方法
public class Basketball extends GameTemplate {

   @Override
   void init() {
      System.out.println("Basketball::init() [Basketball Game Initialized! Start playing.]");
   }

   @Override
   void start() {
      System.out.println("Basketball::start() [Basketball Game Started. Enjoy the game!]");
   }

   @Override
   void end() {
      System.out.println("Basketball::end() [Basketball Game Finished!]");
   }

}
// Football.java 定义子类覆写父类抽象方法
public class Football extends GameTemplate {

   @Override
   void init() {
      System.out.println("Football::init() [Football Game Initialized! Start playing.]");
   }

   @Override
   void start() {
      System.out.println("Football::start() [Football Game Started. Enjoy the game!]");
   }

   @Override
   void end() {
      System.out.println("Football::end() [Football Game Finished!]");
   }

}
// Tennis.java 定义子类覆写父类抽象方法
public class Tennis extends GameTemplate {

   @Override
   void init() {
      System.out.println("Tennis::init() [Tennis Game Initialized! Start playing.]");
   }

   @Override
   void start() {
      System.out.println("Tennis::start() [Tennis Game Started. Enjoy the game!]");
   }

   @Override
   void end() {
      System.out.println("Tennis::end() [Tennis Game Finished!]");
   }

   // 在调用父类play之前,如果要执行自己的行为,也可以覆盖父类方法
   // 先执行自己的,再调用父类的方法
   @Override
   public void play() {
      System.out.println("Tennis::play() [Tennis Game play!]");
      super.play();
   }
}

测试调用

    /**
     * 模板方法模式就是当子类具备类似行为的时候,让子类共用一套流程
     * 创建一个公共模板,确定公用流程和操作动作,子类覆盖具体的动作
     */
    GameTemplate football = new Football();
    football.play();

    System.out.println("===");
    GameTemplate basketball = new Basketball();
    basketball.play();

    System.out.println("===");
    GameTemplate tennis = new Tennis();
    tennis.play();

C语言代码

头文件

// func.h

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

typedef struct GameTemplate GameTemplate;
typedef struct Football Football;
typedef struct Basketball Basketball;
typedef struct Tennis Tennis;

// 定义抽象模板,包括各种动作和公共流程
typedef struct GameTemplate
{
  char name[50];
  void (*init)(GameTemplate *game);
  void (*start)(GameTemplate *game);
  void (*end)(GameTemplate *game);
  void (*play)(GameTemplate *game);
} GameTemplate;
void template_play(GameTemplate *game);
GameTemplate *game_template_constructor(char *name);

// 定义子类覆写父类抽象方法
typedef struct Football
{
  char name[50];
  void (*init)(Football *game);
  void (*start)(Football *game);
  void (*end)(Football *game);
  void (*play)(Football *game);
} Football;
Football *football_constructor(char *name);

// 定义子类覆写父类抽象方法
typedef struct Basketball
{
  char name[50];
  void (*init)(Basketball *game);
  void (*start)(Basketball *game);
  void (*end)(Basketball *game);
  void (*play)(Basketball *game);
} Basketball;
Basketball *basketball_constructor(char *name);

// 定义子类覆写父类抽象方法
typedef struct Tennis
{
  char name[50];
  void (*init)(Tennis *game);
  void (*start)(Tennis *game);
  void (*end)(Tennis *game);
  void (*play)(Tennis *game);
} Tennis;
Tennis *tennis_constructor(char *name);

抽象模板类

// game_template.c 定义抽象模板类,有抽象方法和具体方法
#include "func.h"

// 定义抽象模板类的公共部分,这里用struct替代

// 抽象方法待子类来实现
void template_init(GameTemplate *game) {}
void template_start(GameTemplate *game)
{
  printf("\r\n GameTemplate::start() [GameTemplate Initialized! Start playing.]");
}
void template_end(GameTemplate *game) {}

// 可复用的算法流程
void template_play(GameTemplate *game)
{
  printf("\r\n GameTemplate::play() [name=%s]", game->name);

  // 初始化游戏
  game->init(game);

  // 开始游戏
  game->start(game);

  // 结束游戏
  game->end(game);
}

GameTemplate *game_template_constructor(char *name)
{
  // printf("\r\n game_template_constructor() [构建GameTemplate]");
  GameTemplate *game = (GameTemplate *)malloc(sizeof(GameTemplate));
  strcpy(game->name, name);
  game->init = &template_init;
  game->start = &template_start;
  game->end = &template_end;
  game->play = &template_play;
  return game;
}

具体业务类,继承抽象模板

// basketball.c  定义子类覆写父类抽象方法
#include "func.h"

// 定义子类覆写父类抽象方法
void basketball_init(Basketball *game)
{
  printf("\r\n Basketball::init() [Basketball Game Initialized! Start playing.]");
}

void basketball_start(Basketball *game)
{
  printf("\r\n Basketball::start() [Basketball Game Started. Enjoy the game!]");
}

void basketball_end(Basketball *game)
{
  printf("\r\n Basketball::end() [Basketball Game Finished!]");
}

Basketball *basketball_constructor(char *name)
{
  printf("\r\n basketball_constructor() [构建Basketball]");
  GameTemplate *template = game_template_constructor(name);
  Basketball *game = (Basketball *)template;
  game->init = &basketball_init;
  // 如果不覆盖则使用基类的函数
  // game->start = &basketball_start;
  game->end = &basketball_end;
  return game;
}
// football.c 定义子类覆写父类抽象方法
#include "func.h"

// 定义子类覆写父类抽象方法
void football_init(Football *game)
{
  printf("\r\n Football::init() [Football Game Initialized! Start playing.]");
}

void football_start(Football *game)
{
  printf("\r\n Football::start() [Football Game Started. Enjoy the game!]");
}

void football_end(Football *game)
{
  printf("\r\n Football::end() [Football Game Finished!]");
}

Football *football_constructor(char *name)
{
  printf("\r\n football_constructor() [构建Football]");
  GameTemplate *template = game_template_constructor(name);
  Football *game = (Football *)template;
  game->init = &football_init;
  game->start = &football_start;
  game->end = &football_end;
  return game;
}
// tennis.c 定义子类覆写父类抽象方法
#include "func.h"

// 定义子类覆写父类抽象方法
void tennis_init(Tennis *game)
{
  printf("\r\n Tennis::init() [Tennis Game Initialized! Start playing.]");
}

void tennis_start(Tennis *game)
{
  printf("\r\n Tennis::start() [Tennis Game Started. Enjoy the game!]");
}

void tennis_end(Tennis *game)
{
  printf("\r\n Tennis::end() [Tennis Game Finished!]");
}

// 在调用父类play之前,如果要执行自己的行为,也可以覆盖父类方法
void tennis_play(Tennis *game)
{
  // 先执行自己的内容,再调用基类的函数
  printf("\r\n Tennis::play() [Tennis Game Play!]");
  template_play((GameTemplate *)game);
}

Tennis *tennis_constructor(char *name)
{
  printf("\r\n tennis_constructor() [构建Tennis]");
  GameTemplate *template = game_template_constructor(name);
  Tennis *game = (Tennis *)template;
  game->init = &tennis_init;
  game->start = &tennis_start;
  game->end = &tennis_end;
  game->play = &tennis_play;
  return game;
}

测试调用

#include "../src/func.h"

int main(void)
{
  printf("test start:\r\n");
  /**
   * 模板方法模式就是当子类具备类似行为的时候,让子类共用一套流程
   * 创建一个公共模板,确定公用流程和操作动作,子类覆盖具体的动作
   */
  Football *football = football_constructor("football");
  football->play(football);

  printf("\r\n ===");
  Basketball *basketball = basketball_constructor("basketball");
  basketball->play(basketball);

  printf("\r\n ===");
  Tennis *tennis = tennis_constructor("basketball");
  tennis->play(tennis);
}

更多语言版本

不同语言设计模式源码:https://github.com/microwind/design-pattern文章来源地址https://www.toymoban.com/news/detail-429312.html

到了这里,关于【模板方法设计模式详解】C/Java/JS/Go/Python/TS不同语言实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【迭代器设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    迭代器模式(Iterator Pattern),是一种结构型设计模式。给数据对象构建一套按顺序访问集合对象元素的方式,而不需要知道数据对象的底层表示。 迭代器模式是与集合共存的,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像Java中的Collection,List、Set、Map等

    2023年04月17日
    浏览(29)
  • 【享元设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    享元模式(Flyweight Pattern),是一种结构型设计模式。主要用于减少创建对象的数量,以减少内存占用和提高性能。它摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,让你能在有限的内存容量中载入更多对象。 当程序需要生成数量巨大的相似

    2023年04月10日
    浏览(23)
  • 【访问者设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    访问者模式(Visitor Pattern)是一种行为型模式。它封装一个访问者类,把各元素类的操作集合起来,目的是将数据结构与数据操作分离。在不改变原有元素类数据结构的前提下,改变了元素类的执行算法。 当某些较为稳定的东西(数据结构或算法),不想直接被改变但又想扩

    2024年02月02日
    浏览(57)
  • 【备忘录设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    备忘录模式(Memento Pattern)是一种结构型设计模式。这种模式就是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并放在外部存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。 备忘录模式

    2023年04月20日
    浏览(52)
  • 【观察者设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    观察者模式(Observer Pattern)是一种行为型模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 观察者模式使用三个类Subject、Observer和Client。Subject对象带有绑定观察者到Client对象和从Client对象解绑观察

    2023年04月21日
    浏览(60)
  • 【中介者设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    中介者模式(Mediator Pattern)是一种行为型模式。它限制对象之间的直接交互,它用一个中介对象来封装一系列的动作,以让对象之间进行交流。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 当一些对象和其他对象紧密

    2023年04月19日
    浏览(27)
  • 【解释器设计模式详解】C/Java/Go/JS/TS/Python不同语言实现

    解释器模式(Interpreter Pattern)是一种行为型设计模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式常被用在 SQL 解析、符号处理引擎等。 解释器模式常用于对简单语言的编译或分析实例中,为了掌握好它的结构与实现,必须先了解编译原理中的

    2023年04月12日
    浏览(25)
  • js设计模式:模板方法模式

    父类定义一个整体的模板框架,将具体的方法行为定义到子类中。 模板方法主要是封装行为中的固定部分,同时允许子类对方法进行扩展

    2024年02月22日
    浏览(27)
  • Java设计模式 (一) 模板方法设计模式

    什么是模板方法设计模式? 模板方法设计模式是一种行为型设计模式,它定义了一个算法的骨架,并将一些步骤的具体实现延迟到子类中。模板方法模式可以帮助确保在算法的不同部分中保持一致性,同时也允许子类根据需要进行具体实现。 模板方法模式的关键特点包括:

    2024年02月12日
    浏览(26)
  • java设计模式学习之【模板方法模式】

    设想你正在准备一顿晚餐,无论你想做意大利面、披萨还是沙拉,制作过程中都有一些共同的步骤:准备原料、加工食物、摆盘。这里,整个烹饪流程就像一个模板,而具体的菜肴则在这个模板的基础上添加了特有的步骤。在软件开发中,我们经常遇到类似的情况,某些过程

    2024年02月03日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包