设计模式:模板模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

简介:

模板模式,它是一种行为型设计模式,它定义了一个操作中的算法的框架,将一些步骤延迟到子类中实现,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
通俗地说,模板模式就是将某一行为制定一个框架,然后子类填充细节。比如说做菜,流程通常就是洗菜、切菜、炒菜等步骤,那么这个流程就可以看作是一个模板,而具体做什么菜由子类来实现。

模板模式的使用场景:
1、一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。这种情况下,可以将一些通用的算法逻辑放在一个抽象类中,然后通过子类来提供具体的实现。
2、各子类中公共的行为被提取出来并集中到一个公共的父类中,从而避免代码重复。这种情况下,可以将一些共同的行为放在一个父类中,然后通过继承和多态来实现相似的功能,避免在多个子类中重复编写相同的代码。

例如,在网络销售商品中,模板流程大体为:上架商品-下订单-发快递-收货,如果需要退货还需进行退货流程。这种情况下,可以将发快递和退货等公共流程提取出来放到一个父类中,然后通过子类来实现具体的流程。

模板模式的创建步骤如下:
1、定义抽象类:定义一个抽象类,将要执行的操作封装在方法中。这些方法应该是一个模板方法,包含一些基本的操作步骤。
2、定义模板方法:在抽象类中定义一个模板方法,该方法指定了算法的骨架,并调用其他方法实现具体的操作步骤。模板方法通常是一些基本的流程控制结构,如循环、条件语句等。
3、实现抽象方法:在抽象类中定义一些抽象方法,这些方法将在子类中被实现。这些方法通常是一些具体的操作步骤,如数据处理、界面渲染等。
4、创建子类:创建具体的子类,并实现抽象类中的抽象方法。这些方法将根据实际需求进行定制。
5、实例化对象:在客户端代码中实例化一个对象,并调用模板方法开始执行算法。
这些步骤是模板方法模式的核心。在实际应用中,可以根据具体的需求进行修改和扩展。例如,可以添加更多的抽象方法来细化算法的步骤,或者使用不同的继承结构来组织代码。

模板模式的优点,主要包括:
1、封装不变部分:通过将不变的行为放在父类中,可以减少子类的重复代码,并将这些不变的行为在多个子类中复用。
2、提取公共代码:模板模式可以在多个子类中复用公共代码,使得代码更加简洁、易于维护和修改。
3、行为由父类控制,子类实现:模板模式使得行为的变化更加容易适应,因为行为的变化可以在父类中定义和控制,而子类只需要实现具体的行为即可。
4、提高可复用性:模板模式使得算法的框架可以在多个应用中使用,提高了代码的可复用性。
5、提高可维护性:模板模式使得代码的结构更加清晰,易于维护和理解。

模板模式的缺点,主要包括:
1、类的数量增加:为了实现模板方法,需要在父类中定义一个抽象方法,并且每个子类都需要实现该方法,这样就导致类的数量增加,从而增加了系统的复杂度。
2、继承的固有缺点:如果父类添加了新的抽象方法,所有子类都需要增加该方法,这就增加了代码的维护难度。另外,如果一个子类需要同时实现其他接口或继承其他类,就需要编写更多的代码。
3、实现难度增加:模板方法模式需要开发者自行设计算法框架和流程控制,如果算法较为复杂,实现难度就会增加。
4、不够灵活:模板方法模式相对固定,不够灵活,不能够很好地适应变化。如果需要修改算法框架,就需要修改所有子类的实现,工作量较大。


示例:

一、C#模板模式

在C#中,我们可以使用抽象类或接口来实现模板模式。以下是一个使用抽象类的示例:

public abstract class AbstractTemplate  
{  public void TemplateMethod()  {  Console.WriteLine("Subclass must implement steps");  }  public abstract void SpecificStep();  
}  public class ConcreteTemplate : AbstractTemplate  
{  public override void SpecificStep()  {  Console.WriteLine("This is a specific step");  }  
}
//可以这样使用模板模式:
public static void Main(string[] args)  
{  AbstractTemplate template = new ConcreteTemplate();  template.TemplateMethod(); // This will call SpecificStep and print "This is a specific step"  
}


二、java模板模式

模板模式通常通过以下方式实现:

public abstract class AbstractTemplate {  public void templateMethod() {  System.out.println("AbstractTemplate says:");  doSomething();  doSomethingElse();  }  public abstract void doSomething();  public abstract void doSomethingElse();  
}  public class ConcreteTemplate extends AbstractTemplate {  public void doSomething() {  System.out.println("ConcreteTemplate says:");  // specific behavior  }  public void doSomethingElse() {  System.out.println("ConcreteTemplate says:");  // specific behavior  }  
}
public class Client{public static void Main(String[] args){AbstractTemplate template = new ConcreteTemplate();template.templateMethod();	}
}

三、javascript模板模式

在JavaScript中,模板模式的实现方式如下:

function Person(name, age) {  this.name = name;  this.age = age;  
}  Person.prototype.sayHello = function() {  return `Hello, my name is ${this.name} and I am ${this.age} years old.`;  
};  const person1 = new Person("Alice", 25);  
const person2 = new Person("Bob", 30);  console.log(person1.sayHello()); // 输出:Hello, my name is Alice and I am 25 years old.  
console.log(person2.sayHello()); // 输出:Hello, my name is Bob and I am 30 years old.

四、C++模板模式

C++模板可以分为函数模板和类模板。函数模板定义了一个通用的函数框架,可以接受不同的参数类型,并生成相应的函数实现。类模板则定义了一个通用的类,可以接受不同的数据类型作为成员变量类型,并生成相应的类实现。

下面是一个使用C++函数模板的示例:

template <typename T>  
T add(T a, T b) {  return a + b;  
}  int main() {  int sum = add<int>(1, 2); // 使用整数类型参数  double avg = add<double>(1.0, 2.0); // 使用浮点数类型参数  return 0;  
}

在上面的示例中,函数模板 add 可以接受任意类型的参数 a 和 b,并返回它们的和。在 main 函数中,我们使用整数类型和浮点数类型分别调用 add 函数,生成相应的代码实现。

除了函数模板,C++还支持类模板。类模板可以定义一个通用的类,可以接受不同的数据类型作为成员变量类型,并生成相应的类实现。下面是一个使用C++类模板的示例:
 

template <typename T>  
class Array {  
public:  Array(int size) : size_(size), data_(new T[size]) {}  ~Array() { delete[] data_; }  T& operator[](int index) { return data_[index]; }  
private:  int size_;  T* data_;  
};  int main() {  Array<int> int_array(10); // 使用整数类型参数  Array<double> double_array(5); // 使用浮点数类型参数  return 0;  
}

在上面的示例中,类模板 Array 可以接受任意类型的参数 T 作为成员变量类型,并生成相应的类实现。在 main 函数中,我们使用整数类型和浮点数类型分别创建 Array 类的对象,生成相应的代码实现。

五、python模板模式

在python中有两种方式实现模板模式。
1、使用装饰器来扩展函数的行为来实现。装饰器可以在不修改函数代码的情况下添加新的行为。下面是一个简单的例子:

def template_method(func):  def wrapper(*args, **kwargs):  print("Before the function is called.")  result = func(*args, **kwargs)  print("After the function is called.")  return result  return wrapper  @template_method  
def add(x, y):  return x + y  print(add(2, 3))

在这个例子中,template_method 是一个装饰器,它定义了一个框架,在调用函数之前和之后打印一些信息。add 函数被装饰器装饰,因此它继承了装饰器的行为。当我们调用 add 函数时,它将在调用之前和之后打印信息,并返回函数的结果。

2、使用抽象基类(ABC)和多态来实现。抽象基类定义了一个通用的接口,子类必须实现这个接口。多态允许使用不同的子类来扩展父类的行为。下面是一个使用抽象基类和多态的例子:

from abc import ABC, abstractmethod  class Shape(ABC):  def draw(self):  pass  class Circle(Shape):  def draw(self):  print("Drawing circle")  class Rectangle(Shape):  def draw(self):  print("Drawing rectangle")  def draw_shape(shape):  shape.draw()  if __name__ == "__main__":  shapes = [Circle(), Rectangle()]  for shape in shapes:  draw_shape(shape)

在这个例子中,Shape 是一个抽象基类,它定义了一个 draw 方法,子类必须实现这个方法。Circle 和 Rectangle 是 Shape 的子类,它们分别实现了 draw 方法。draw_shape 函数是一个模板方法,它接受一个 Shape 对象作为参数,并调用其 draw 方法。在主程序中,我们创建了一个包含不同形状的列表,并使用 draw_shape 函数来绘制它们。由于它们都继承自 Shape 类,因此它们都可以被 draw_shape 函数接受并正确绘制。

六、go模板模式

在Go语言中,没有直接称为"模板模式"的设计模式,但是有一种类似的行为可以通过使用函数和闭包来实现。
在Go语言中,可以通过定义一个父类和一个子类来实现类似模板方法模式的行为。父类可以包含一个或多个函数,这些函数可以调用子类的方法来实现算法的某些步骤。子类可以继承父类的函数,并重写其中的一些方法来改变算法的行为。

下面是一个简单的示例代码,实现类似模板方法模式的行为:

package main  import "fmt"  type Parent struct{}  func (p *Parent) Algorithm() {  fmt.Println("Parent's Algorithm")  p.Step1()  p.Step2()  
}  func (p *Parent) Step1() {  fmt.Println("Parent's Step 1")  
}  func (p *Parent) Step2() {  fmt.Println("Parent's Step 2")  
}  type Child struct {  Parent  
}  func (c *Child) Step1() {  fmt.Println("Child's Step 1")  
}  func main() {  child := &Child{}  child.Algorithm() // Output: Parent's Algorithm, Child's Step 1, Parent's Step 2  
}

七、PHP模板模式

在PHP中,模板模式通常使用模板引擎来实现。

模板引擎是一种独立的中间件,用于处理模板和生成最终的输出。它负责解析模板文件,将动态数据与模板文件中的占位符进行替换,并将最终的输出发送给客户端。PHP中有很多流行的模板引擎,如Smarty、Twig和Blade等。

下面是一个简单的示例,演示了如何使用PHP模板模式:

//创建模板文件(template.php):
<html>  
<head>  <title>{{ title }}</title>  
</head>  
<body>  <h1>{{ message }}</h1>  
</body>  
</html>
//创建PHP脚本(script.php):
<?php  
// 加载并配置模板引擎(以Twig为例)  
require_once 'vendor/autoload.php'; // 根据实际情况加载Composer依赖项  
$loader = new \Twig\Loader\FilesystemLoader('path/to/templates');  
$twig = new \Twig\Environment($loader);  // 准备动态数据  
$data = [  'title' => 'Welcome',  'message' => 'Hello, world!'  
];  // 渲染模板并输出结果  
echo $twig->render('template.php', $data);

在上面的示例中,我们使用了Twig模板引擎来解析和渲染模板文件。在script.php中,我们首先加载并配置了Twig引擎,然后准备了一个包含动态数据的数组。最后,我们使用Twig的render方法将动态数据与模板文件进行替换,并将最终的输出发送给客户端。

《完结》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/115516.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

✔ ★【备战实习(面经+项目+算法)】 10.22学习时间表(算法刷题:4道)

✔ ★【备战实习&#xff08;面经项目算法&#xff09;】 坚持完成每天必做如何找到好工作1. 科学的学习方法&#xff08;专注&#xff01;效率&#xff01;记忆&#xff01;心流&#xff01;&#xff09;2. 每天认真完成必做项&#xff0c;踏实学习技术 认真完成每天必做&…

简单易用的操作界面,让你轻松制作电子期刊

随着互联网的发展&#xff0c;电子期刊已经成为了越来越多人的选择。FLBOOK在线制作电子杂志平台作为一款简单易用的操作界面&#xff0c;为用户提供了制作电子期刊的便利。 但是你知道如何使用FLBOOK在线制作电子杂志平台制作一本电子期刊吗&#xff1f; 1.点击开始创作&#…

Spring boot 集成 xxl-job

文章目录 xxl-job 简介引入xxl-job依赖配置xxl-job config添加properties文件配置BEAN模式&#xff08;方法形式&#xff09;步骤一&#xff1a;执行器项目中&#xff0c;开发Job方法&#xff1a;步骤二&#xff1a;调度中心&#xff0c;新建调度任务 xxl-job 简介 官网:https:…

k8s----11、service

services 1、概述2、存在的意义2.1 服务发现2.2 负载均衡 3、pod与service的关系4、service 三种类型4.1 、 ClusterIP4.2 、NodePort4.3 、LoadBalancer 1、概述 Service 是 Kubernetes 最核心概念&#xff0c;通过创建 Service,可以为一组具有相同功能的容器应 用提供一个统…

YOLOV8目标检测——最全最完整模型训练过程记录

文章目录 前言1 下载yolov8&#xff08;[网址](https://github.com/ultralytics/ultralytics)&#xff09;2 配置conda环境3 用pycharm打开文件3 训练自己的YOLOV8数据集4 run下运行完了之后没有best.pt文件5 导出为onnx文件6 yolov8应用完整案例&#xff08;免费且包含源代码、…

iOS上架App Store的全攻略

​ 第一步&#xff1a;申请开发者账号 在开始将应用上架到App Store之前&#xff0c;你需要申请一个开发者账号。 1.1 打开苹果开发者中心网站&#xff1a;Apple Developer 1.2 使用Apple ID和密码登录&#xff08;如果没有账号则需要注册&#xff09;&#xff0c;要确保使用…

基于Python实现的快速的仿手写文字的图片生成器项目源码

Quick Hand &#x1f4dd; 介绍 快速的仿手写文字的图片生成器。 完整代码下载地址&#xff1a;基于Python实现的快速的仿手写文字的图片生成器 界面预览&#xff1a; &#x1f52e; 使用说明 原理&#xff1a;首先&#xff0c;在水平位置、竖直位置和字体大小三个自由度上…

uniapp开发微信小程序,webview内嵌h5,h5打开pdf地址,解决方案

根据公司要求&#xff0c;让我写一个h5&#xff0c;后续会嵌入到合作公司的微信小程序的webview中&#xff0c;如果是自己公司微信小程序&#xff0c;可以采取先下载下来pdf&#xff0c;然后通过wx.openDocument&#xff0c;进行单纯的预览操作&#xff0c;这个可以根据这个老哥…

C语言里的static变量其他语言是看不上还是学不去?

C语言里的static变量其他语言是看不上还是学不去? static变量在C语言中被用于具有静态存储期的局部变量或全局变量。它有以下几个特点&#xff1a; 1. 静态存储期&#xff1a;static变量在程序执行时分配内存&#xff0c;直到程序结束才会释放&#xff0c;其生命周期与程序的…

aarch64 rpmbuild openstack wallaby neutron 打包rpm笔记

基本信息 源码地址&#xff1a; openstack-neutron: Neutron is an OpenStack project to provide "network connectivity as a service" between interface devices (e.g., vNICs) managed by other OpenStack services - Gitee.com git clone -b Multi-Version_O…

【JS的设计模式一】

本文参考书籍 《JavaScript设计模式与开发实践》 在 JavaScript 编程中&#xff0c;this 关键字总是让人感到迷惑&#xff0c;Function.prototype.call 和 Function.prototype.apply 这两个方法也有着广泛的运用。我们有必要在学习设计模式之前先理解 这几个概念。 this Java…

Windows 95 的辉煌诞生历史

1992 年 2 月&#xff0c;Windows 3.1 的研发即将结束&#xff0c;而 Windows 团队正忙得不亦乐乎地计划他们的下一盘大棋。到了 3 月 5 日&#xff0c;他们终于悠哉悠哉地敲定了战略大计&#xff1a;横扫桌面、笔记本、移动设备以及时髦的触控笔设备。至于那些高大上的服务器和…

测吧(北京)科技有限公司项目总监王雪冬一行访问计算机学院探讨合作

3月15日&#xff0c;测吧&#xff08;北京&#xff09;科技有限公司&#xff08;以下简称测吧&#xff09;项目总监王雪冬来到计算机学院对校企合作、学生就业、学生竞赛等一系列工作进行了深入研讨&#xff0c;并向计算机学院颁发了优秀组织单位和优秀指导老师奖。会议由黄曼绮…

当年很流行,现在已经淘汰的前端技术有哪些?

近几年&#xff0c;前端技术真可谓是飞速发展&#xff0c;不断有新的技术涌现&#xff0c;爆火的前端框架 Astro&#xff0c;前端运行时 Bun&#xff0c;构建工具 Vite 等都给前端提供了强大动力。当然&#xff0c;也有很多前端技术随着技术的发展不再需要使用&#xff0c;有了…

【产品运营】产品需求应该如何管理

产品项目在进行时经常会有一些需求需要实现&#xff0c;需求是产品更新迭代的动力&#xff0c;需求也是从用户诉求转化而来&#xff1b;在做需求管理时&#xff0c;我们需要判断一个需求的优先级等方面&#xff0c;对产品进行优化&#xff1b; 目录&#xff1a; 一、 为什么要…

FFT64点傅里叶变换verilog蝶形运算,代码和视频

名称&#xff1a;FFT64点verilog傅里叶变换 软件&#xff1a;Quartus 语言&#xff1a;Verilog 代码功能&#xff1a; 使用verilog代码实现64点FFT变换&#xff0c;使用蝶形运算实现傅里叶变换 演示视频&#xff1a;http://www.hdlcode.com/index.php?mhome&cView&…

【计算机网络】应用层协议--HTTP协议及HTTP报文格式

目录 1、HTTP是什么 2、HTTP请求与响应 3、HTTP请求的两种方法(get和post)及区别 (面试题) 4、几种常见的错误的说法 5、HTTP协议的特点 6、应用场景 7、HTTP报文格式 8、面试题&#xff1a;HTTP常见的状态码都有哪些&#xff1f; 1、HTTP是什么 HTTP协议是在Web上进行…

C# 关于托管调试助手 “FatalExecutionEngineError“:“运行时遇到了错误。解决方案

托管调试助手 “FatalExecutionEngineError”:“运行时遇到了错误。此错误的地址为 0x740161f8&#xff0c;在线程 0x1174 上。错误代码为 0xc0000005。此错误可能是 CLR 中的 bug&#xff0c;或者是用户代码的不安全部分或不可验证部分中的 bug。此 bug 的常见来源包括用户对 …

微信native-v3版支付对接流程及demo

1.将p12证书转为pem证书&#xff0c;得到商户私钥 openssl pkcs12 -in apiclient_cert.p12 -out apiclient_cert.pem -nodes 密码是&#xff1a;商户id 2.将获取到的apiclient_cert.pem证书&#xff0c;复制出这一块内容&#xff0c;其他的不要 3.下载这个工具包 https://gi…

macOS Sonoma 桌面小工具活学活用!

macOS Sonoma 虽然不算是很大型的改版&#xff0c;但当中触目的新功能是「桌面小工具」&#xff08;Widget&#xff09;。如果我们的萤幕够大&#xff0c;将能够放更多不同的Widget&#xff0c;令用户无须开App 就能显示资讯&#xff0c;实在相当方便。 所有iPhone Widget 也能…