面向对象设计与分析40讲(24)上下文context在软件设计中的应用--依赖注入的典型应用

文章目录

    • 上下文
    • 典型应用
    • context的标准范例

上下文

首先,我们应该谈谈什么是上下文。

上下文(Context)是指某个事件、任务或问题所处的特定环境或情境。它包含了相关的信息、条件、状态和对象,用于帮助理解、解释和处理当前的情况。

在计算机科学中,上下文可以指代以下几个方面:

  1. 程序执行上下文:指程序在执行过程中的当前状态。它包括程序计数器、堆栈、寄存器等信息,用于控制和管理程序的执行流程。
  2. 编程语言中的上下文:指编程语言中代码的执行环境。例如,在 JavaScript 中,函数的执行上下文由函数的作用域、变量、this 指向等组成。
  3. 通信协议中的上下文:指在通信过程中相关的信息和数据。例如,在网络通信中,每个数据包都可能包含一些额外的上下文信息,用于标识发送者、接收者、消息类型等。
  4. 自然语言处理中的上下文:指在理解自然语言文本时,需要考虑文本中前后文的信息,以获得更准确的语义理解。例如,在对话系统中,上下文可以是之前的对话历史或上下文回复。
  5. 用户界面中的上下文:指用户界面中当前的操作环境和状态。例如,在一个图形化界面中,上下文可以包括当前打开的窗口、选中的对象等。

总的来说,上下文提供了周围环境和相关信息来帮助理解和处理当前的问题或任务。它在不同的领域中具有不同的含义和用法,但都起到了关键的作用,提供了必要的背景和条件,以便进行适当的决策和操作。

当谈到依赖注入(Dependency Injection, DI)时,上下文(Context)可以用来传递依赖对象或依赖解析器,以满足组件所需的依赖关系。

比如图形学领域,contex相当于 this 或者 self或者是句柄,用来指向当前绘图环境用到的实例,不同的context还会形成堆栈关系。

对于多线程,协程之类的,需要在切换时保存现场以及相关的参数,相关参数就是context。

在异步回调应用中,上下文(Context)通常用于传递异步任务的状态和结果信息。当一个异步任务被触发后,它会在后台运行,并在完成时通知应用程序。此时,应用程序需要处理这个任务的返回结果,可能需要进行一些后续操作或者将结果显示给用户。

为了方便处理异步任务的结果,通常会使用上下文对象来存储相关信息。当异步任务完成后,它会将结果存储到上下文对象中,并触发一个回调函数来通知应用程序。应用程序可以通过回调函数获取上下文对象中的结果,并进行相应的处理。

对于面向对象的应用程序,尽管application实例只有一个,但是在实际编码中,如果不去定义context,就很容易发现一些工具类或者服务管理器为了写代码方便会被错误实现为单例模式。而实际上,考虑到代码可测性,一个重要的概念就是,依赖是可以被替换的,而单例模式就是难以替换,因此将依赖封装到context里去,就是一种实现技巧。

典型应用

下面我们列举一些典型的应用:

  1. 信号/异常捕获里的上下文信息
#include <signal.h>
#include <ucontext.h>static void sig_handler(int signo, siginfo_t *siginfo, void *context) {// 获取当前线程的 ucontext_t 结构体ucontext_t *ucontext = (ucontext_t *) context;// 访问 ucontext_t 结构体中的相关字段,如 RIP 寄存器printf("Program counter: 0x%llx\n", ucontext->uc_mcontext.gregs[REG_RIP]);// ...
}int main() {struct sigaction act;act.sa_flags = SA_SIGINFO;  // 为了在信号处理函数中获取额外信息,需要设置 SA_SIGINFO 标志位act.sa_sigaction = sig_handler;if (sigaction(SIGSEGV, &act, NULL) < 0) {perror("sigaction");return -1;}// ...
}

在上述示例中,sigaction 函数用于注册一个信号处理函数,当程序接收到 SIGSEGV 信号时,会自动调用 sig_handler 函数。该函数的第三个参数 context 就是 ucontext_t 类型的指针,用于保存程序执行状态的信息。在示例中,我们通过访问 ucontext_t 结构体中的相关字段,比如 RIP 寄存器,来获取程序执行状态的信息。

  1. 服务器的响应
#include <iostream>
#include <memory>
#include <string>#include <grpcpp/grpcpp.h>#include "helloworld.grpc.pb.h"using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using helloworld::HelloRequest;
using helloworld::HelloResponse;
using helloworld::Greeter;class GreeterServiceImpl final : public Greeter::Service {Status SayHello(ServerContext* context, const HelloRequest* request, HelloResponse* response) override {std::string prefix("Hello, ");response->set_message(prefix + request->name());return Status::OK;}
};void RunServer() {std::string server_address("0.0.0.0:50051");GreeterServiceImpl service;ServerBuilder builder;builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());builder.RegisterService(&service);std::unique_ptr<Server> server(builder.BuildAndStart());std::cout << "Server listening on " << server_address << std::endl;server->Wait();
}int main(int argc, char** argv) {RunServer();return 0;
}

在 gRPC 的 C++ 中,ServerContext 类提供了许多有用的信息和功能,可以在服务器端访问和控制 RPC 请求。以下是一些 ServerContext 提供的主要功能:

  1. 元数据(Metadata):通过 ServerContext 可以获取到请求中的元数据。元数据是以键值对形式存储的请求附加信息,例如身份验证凭证、客户端信息等。
cppCopy Codeconst grpc::string& GetMetadata(const grpc::string& key)

通过调用 GetMetadata 函数,可以获取特定键的元数据值。例如,可以使用 “authorization” 键来获取身份验证凭证。

  1. 客户端地址(Client Address):ServerContext 还提供了获取客户端 IP 地址和端口号的函数。
cppCopy Codeconst grpc::string& peer() const

通过调用 peer 函数,可以获取客户端的 IP 地址和端口号。

  1. 截止时间(Deadline):ServerContext 还提供了用于获取 RPC 请求截止时间的函数。
cppCopy Codestd::chrono::system_clock::time_point deadline() const

通过调用 deadline 函数,可以获取请求的截止时间。这对于实现超时控制和处理长时间运行的 RPC 请求非常有用。

  1. 调用取消(Cancellation):ServerContext 还提供了用于检查和响应 RPC 请求是否被取消的功能。
cppCopy Codebool IsCancelled() const

通过调用 IsCancelled 函数,可以检查 RPC 请求是否被取消。如果返回 true,则表示请求已被取消。

除了上述功能之外,ServerContext 还提供了其他一些有用的函数和方法,用于控制和访问 RPC 请求的各个方面。可以参考 gRPC 的 C++ API 文档以获取更详细的信息。

context的标准范例

#include <iostream>
#include <string>// 定义上下文类
class Context {
public:Context(const std::string& name) : m_name(name) {}const std::string& getName() const {return m_name;}private:std::string m_name;
};// 定义服务类
class Service {
public:virtual void doSomething(const Context& context) = 0;
};// 实现服务类
class HelloService : public Service {
public:virtual void doSomething(const Context& context) override {std::cout << "Hello, " << context.getName() << "!" << std::endl;}
};// 主函数
int main() {// 创建上下文对象Context context("World");// 使用服务HelloService helloService;helloService.doSomething(context);return 0;
}

在上述示例中,我们定义了一个 Context 类来表示上下文,它包含了一个 name 属性。然后,我们定义了一个 Service 类作为服务接口,其中包含了 doSomething() 方法,它接受一个 Context 对象作为参数。

接着,我们实现了 HelloService 类,它继承自 Service 类,并实现了 doSomething() 方法,在方法中打印出问候语和上下文对象中的名称。

最后,在 main() 函数中,我们创建了一个名为 contextContext 对象,并将其传递给 HelloService 的实例的 doSomething() 方法。这样,就可以在控制台输出 “Hello, World!” 的问候语了。

这是一个非常简单的示例,实际上,在实际开发中,上下文(Context)可能包含更多的属性和方法,以支持特定的场景和需求。

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

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

相关文章

word2vec,BERT,GPT相关概念

词嵌入&#xff08;Word Embeddings&#xff09; 词嵌入通常是针对单个词元&#xff08;如单词、字符或子词&#xff09;的。然而&#xff0c;OpenAI 使用的是预训练的 Transformer 模型&#xff08;如 GPT 和 BERT&#xff09;&#xff0c;这些模型不仅可以为单个词元生成嵌入…

Graylog 中日志级别及其对应的数字

在 Graylog 中&#xff0c;日志级别 level 通常使用数字表示&#xff0c;数字越低表示日志级别越高。以下是常见的日志级别及其对应的数字表示&#xff1a; DEBUG&#xff08;调试&#xff09;&#xff1a;对应数字 7。INFO&#xff08;信息&#xff09;&#xff1a;对应数字 …

全志V3s之Kernel移植

1、安装一些依赖&#xff1a; sudo apt install gcc flex bison libssl-dev bc kmod2、下载源码&#xff1a; Linux的kernel官网&#xff1a;Kernel官网&#xff0c;可以直接去荔枝派的Github仓库下载&#xff1a;荔枝派的Github仓库 git clone -b zero-5.2.y --depth 1 htt…

剑指 Offer(第2版)面试题 33:二叉搜索树的后序遍历序列

剑指 Offer&#xff08;第2版&#xff09;面试题 33&#xff1a;二叉搜索树的后序遍历序列 剑指 Offer&#xff08;第2版&#xff09;面试题 33&#xff1a;二叉搜索树的后序遍历序列解法1&#xff1a;递归 剑指 Offer&#xff08;第2版&#xff09;面试题 33&#xff1a;二叉搜…

高空抛物屡禁不止?智能分析视频监控如何保障空中安全?

日前&#xff0c;长春高空抛物事件已经落下帷幕&#xff0c;此事件的爆出一时间轰动全网&#xff0c;周某漠视他人生命的行为令人愤怒&#xff0c;而年轻女孩的生命也被无情剥夺。为什么高空抛物事件如此频繁&#xff0c;还屡禁不止呢&#xff1f;面对这样令人痛心的新闻作为智…

锁--07_1----插入意向锁-Insert加锁过程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 插入意向锁MySQL执行插入Insert时的加锁过程MySQL官方文档MySQL insert加锁流程1.加插入意向锁2.判断插入记录是否有唯一键3. 插入记录并对记录加X锁插入意向锁----…

Vue 3与Composition API:入门指南

Vue 3是Vue框架的最新版本&#xff0c;它引入了Composition API&#xff0c;这是一个全新的API&#xff0c;与Vue 2的Options API有很大的不同。下面是Vue 3和Composition API的一些重要变化和使用要点&#xff1a; 1. **Setup函数** - 在Vue 3中&#xff0c;每个页面的入口…

统一观测丨使用 Prometheus 监控 Memcached 最佳实践

作者&#xff1a;啃唯 Memcached 简介 Memcached 是什么&#xff1f; Memcached 是一个免费开源、高性能、分布式内存对象缓存系统&#xff0c;支持将任意数据类型的 chunk 数据以键值对的方式存储。本质上 Memcached 是通用于所有的应用的&#xff0c;但最初用于存储被经常…

GD32F4标准外设库

学习目标 了解标准库来源熟悉模板搭建流程掌握在已有模板基础下进行开发学习内容 标准外设库获取 标准固件库获取我们可以从官网进行下载。 下载链接:兆易创新GigaDevice-资料下载兆易创新GD32 MCU 找到 GD32F4xx Firmware Library 这个压缩包 下载完成后,进行解压,解压…

【期末复习向】n元gram的应用

当 n 1 时&#xff0c; 即出现 在 第 i 位 上 的基 元 w i 独 立于 历 史 。 一元文法也 被 写 为 uni-gram 或 monogram&#xff1b; 当 n 2 时 , 2-gram ( bi-gram ) 被称 为 1 阶 马 尔 可夫 链&#xff1b; 当 n 3 时 , 3-gram( tri-gram ) 被称为 2 阶马尔 可 夫 链 &am…

2024 年科技领域的重大创新思想

智能能源网格、语音先行的伴侣应用、可编程药品、针对儿童的 AI 工具。我们向 a16z 的超过 40 位合作伙伴征询了他们认为将在 2024 年成为创新动力的重要理念。 美国的活力 21 世纪的公共安全 技术的发展不仅提升了我们的生活标准&#xff0c;也提高了我们对安全社会的期待。…

人工智能多模态:看、听、说,智能感知的全方位融合

导言 人工智能多模态技术是指通过整合视觉、听觉、语言等多个感知模态的信息&#xff0c;实现对丰富、多样化数据的理解与处理。本文将深入研究人工智能多模态的技术原理、应用场景以及对未来感知智能的影响。 1. 简介 人工智能多模态技术通过整合多个感知模态的信息&#xff…

后缀数组模板之高度数组

高度数组 1.理解相关数组的含义 rk[i]&#xff1a;表示原始下标为i的后缀字符串排序后对应的下标&#xff08;也就是原始下标为i的后缀字符串排序后为第rk[i]小&#xff09; height[i]&#xff1a;表示排名为i和i-1的后缀字符串的最长公共前缀的长度&#xff0c;注意这里的i是…

红帽认证RHCE9.0版本2023年12月的红帽9.0版本RHCSA题⽬+答案,本人已过,全国通用

红帽认证9版本2023年12月的红帽9.0版本RHCSA题⽬答案&#xff0c;本人已过&#xff0c;全国通用 需要完整的RHCSA和RHCE的考试答案的题目以及RHCE9考试的模拟环境和考试笔记教材的请添加微信&#xff0c;需备注来自csdn&#xff0c;不然通不过 1、配置⽹络设置? 将?node1?…

「Verilog学习笔记」RAM的简单实现

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1ns module ram_mod(input clk,input rst_n,input write_en,input [7:0]write_addr,input [3:0]write_data,input read_en,input [7:0]read_addr,output reg…

关于uview-ui的u-tabs标签滑块不居中的问题

在uniapp中&#xff0c;打开文件 uni_modules/uview-ui/components/u-tabs/u-tabs.vue 然后在style中添加以下代码即可 /deep/ .u-tabs__wrapper__nav__line {left: 18rpx; } 之前效果图&#xff1a; 之后效果图&#xff1a; 注意&#xff0c;代码中的18rpx需要自行调整

语音机器人话术设计重点

要使用语音机器人&#xff0c;首先得要先准备一套业务的话术脚本&#xff0c;这个话术脚本的设计&#xff0c;可能直接决定了语音机器人后续的使用效果。这个脚本的编写一般不是机器人厂家直接能完成的&#xff0c;只有业务的使用方&#xff0c;他们才最了解自己的业务&#xf…

报错“找不到mfc100u.dll,程序无法继续执行”的解决方法,完美解决

在软件操作过程中&#xff0c;部分用户可能遇到"计算机缺失mfc140u.dll导致无法启动程序"的困扰。这种情况常常发生在启动某特定应用&#xff0c;特别是需要VC Redistributable支持的软件时。以下为详尽解决策略&#xff0c;让用户轻松应对这类技术难题&#xff0c;重…

LeetCode-739. 每日温度【栈 数组 单调栈】

LeetCode-739. 每日温度【栈 数组 单调栈】 题目描述&#xff1a;解题思路一&#xff1a;单调栈&#xff0c;顺序遍历数组维护单调递减栈&#xff0c;在出栈的时候得出答案。可以参考[LeetCode-503. 下一个更大元素 II【栈 数组 单调栈】](https://blog.csdn.net/qq_45934285/a…

【1】自动化测试环境配置(ARM服务器)

想要从事 or 了解自动化测试开发、装备开发的小伙伴&#xff0c;本专栏内容将从0到1学习如何针对ARM服务器产品进行自动化测试平台的搭建&#xff0c;包括&#xff1a;测试界面的实现&#xff08;GUI&#xff09;、测试项的功能实现&#xff08;压力测试、接口测试、版本更新&a…