星辰计划03-IOC

控制反转(Inversion of Control,简称IoC)是一种设计原则,主要用于减少软件组件之间的耦合度,使程序的结构更加灵活,易于扩展和维护。IoC的核心理念是将组件之间的控制流和依赖关系的管理权从组件自身转移到一个外部容器或框架中,从而实现组件的解耦和模块化。

IoC的背景和动机

在传统的编程模型中,组件或对象负责创建和管理其依赖对象。这意味着组件必须知道其依赖项的创建细节,这导致了紧密的耦合。当依赖项发生变化时,组件也需要相应的调整,这增加了维护的复杂性和成本。

IoC的作用

IoC通过将控制权转移给一个中央控制器或框架,使得组件可以专注于自己的职责,而无需关心其依赖项是如何被创建、初始化和销毁的。这通常通过依赖注入(Dependency Injection,简称DI)的方式来实现,其中依赖关系在组件之外被管理,并在运行时动态地注入到组件中。

IoC的实现方式

IoC最常见的实现方式是依赖注入(DI),它有三种主要的形式:

  1. 构造函数注入:依赖项通过构造函数传入组件。
  2. 属性注入:依赖项通过setter方法或公开的属性传入组件。
  3. 方法注入:依赖项在组件的方法调用时传入。

IoC的示例

例子1

假设我们有一个应用,其中包含一个Service类,它依赖于一个Database类来进行数据存储。

传统方式
// Service.java
public class Service {private Database db;public Service() {this.db = new Database(); // 紧耦合}public void doWork() {db.saveData();}
}// Database.java
public class Database {public void saveData() {// 数据库逻辑}
}
使用IoC
// Service.java
public class Service {private Database db;public Service(Database db) { // 构造函数注入this.db = db;}public void doWork() {db.saveData();}
}// 使用Spring框架的示例
@Service
public class Service {private final Database db;@Autowiredpublic Service(Database db) {this.db = db;}public void doWork() {db.saveData();}
}

在IoC模式下,Service不再负责Database的实例化,而是由一个容器(如Spring框架)负责创建Database实例,并将其注入到Service中。这样,Service和Database之间就实现了松耦合,提高了代码的可测试性和可维护性。

IoC不仅限于依赖注入,它还涉及到控制流程的反转,即应用程序的控制流不是由调用者直接控制,而是由外部容器来控制。这种设计有助于构建更加健壮和灵活的系统架构。

例子2
传统编程模式的例子

考虑一个简单的登录功能,其中有两个类:LoginService和UserRepository。LoginService负责处理用户的登录请求,而UserRepository负责从数据库中读取用户信息。

public class LoginService {private UserRepository userRepository;public LoginService() {this.userRepository = new UserRepository(); // 创建依赖}public boolean login(String username, String password) {User user = userRepository.getUser(username);return user != null && user.getPassword().equals(password);}
}public class UserRepository {public User getUser(String username) {// 假设这是从数据库获取用户信息的代码return new User(username, "password");}
}

在这个例子中,LoginService负责创建UserRepository实例,这导致了紧耦合,因为LoginService需要知道UserRepository的创建细节。

使用IoC的例子

如果我们使用IoC,LoginService将不再负责创建UserRepository实例。相反,一个外部的容器(如Spring框架)将负责实例化和管理这些依赖关系。这通常通过依赖注入(Dependency Injection,DI)来实现。

public class LoginService {private UserRepository userRepository;public LoginService(UserRepository userRepository) {this.userRepository = userRepository;}public boolean login(String username, String password) {User user = userRepository.getUser(username);return user != null && user.getPassword().equals(password);}
}// 假设现在有Spring框架管理这些bean
@Configuration
public class AppConfig {@Beanpublic UserRepository userRepository() {return new UserRepository();}@Beanpublic LoginService loginService(UserRepository userRepository) {return new LoginService(userRepository);}
}

IoC总结

在这个IoC的例子中,LoginService不再负责创建UserRepository实例。相反,Spring框架根据AppConfig配置创建UserRepository实例,并将其注入到LoginService中。这样,LoginService不再需要知道UserRepository是如何创建的,也不需要关心其生命周期管理,这实现了控制流程的反转,交由spring来控制依赖的创建注入,而不是应用程序组件本身去创建依赖。

通过这种方式,IoC不仅减少了组件间的耦合,还使得组件更容易进行单元测试和替换,因为它们不再硬编码其依赖关系,而是通过外部容器动态注入。这种模式促进了模块化和可插拔的设计,使得系统更加灵活和可维护。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构-4.1.特殊矩阵的压缩存储

一.一维数组的存储结构: 1.知道一维数组的起始地址,就可以求出任意下标对应的元素所在的地址; 2.注:如果数组下标从1开始,上述公式的i就要改为i-1; 3.数组里的元素类型相同,因此所占空间也相同…

转码第 188 天-高德算法实习面经分享

最近已有不少大厂都在秋招宣讲了,也有一些在 Offer 发放阶段。 节前,我们邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对新人如何快速入门算法岗、如何准备面试攻略、面试常考点、大模型项目落地经验分享等热门话题进行了深入的讨论。…

嵌入式 ADC基础知识

在现实世界中,常见的信号大都是模拟量,像温度、声音、气压等,但在信号的处理与传输中,为了减少噪声的干扰,较多使用的是数字量。因此我们经常会将现实中的模拟信号,通过 ADC 转换为数字信号进行运算、传输、…

6.2 微服务 负载均衡 架构模式 分类和应用实践

微服务 负载均衡 架构模式 分类 目录概述需求: 设计思路实现思路分析1.1. 微服务架构概述2.2. 负载均衡概念3.3. 负载均衡架构模式3.1 客户端负载均衡 架构模式 要点3.2 服务器端负载均衡 架构模式3.3 代理负载均衡 架构模式 4.4.负载均衡算法3.4 DNS负载均衡 架构模…

通信工程学习:什么是FTP文件传输协议

FTP:文件传输协议 FTP(File Transfer Protocol,文件传输协议)是一种用于在网络上交换文件的协议,它定义了文件传输时使用的命令和响应。作为最古老的互联网协议之一,FTP至今仍被广泛使用,并在网…

PCL 投影滤波器

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 投影滤波 2.1.2 可视化 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接: PCL点云算法与项目实战案例汇总(长期更新) 一、…

算法课习题汇总(3)

循环日程表 设有N个选手进行循环比赛,其中N2M,要求每名选手要与其他N−1名选手都赛一次,每名选手每天比赛一次,循环赛共进行N−1天,要求每天没有选手轮空。 例如4个人进行比赛: 思路: 把表格…

20道面试题001

常考语法就是指针,指针与数组、指针与字符串、指针与结构体、指针与函数之间的关系与使用, 以上课为准,辅助《深度理解C指针》这本书。 1. 指针与数组 定义: 数组名在表达式中通常被视为指向数组首元素的指针。 访问元素: 可以通过指针访问数…

递归函数设计技巧

目录 1.路飞吃桃子的问题--应试难度 2.弹簧板问题--应试难度 3.递归实现指数型枚举--校招难度 4.递归实现组合型枚举--校招难度 5.递归实现排列型枚举--校招难度 1.路飞吃桃子的问题--应试难度 我们可以说下两个案例,反正是最后一天的时候,只剩下了一…

pnpm在monorepo架构下不能引用其他模块的问题

一、研究背景 monorepo架构项目目录结构: - common- index.ts- ... - main- index.ts- ... - web- vue-demo- ... pnpm在monorepo架构下使用以下命令 pnpm -F main add common # or pnpm --filter main add common 并不能在main/index.ts中使用common/index.ts…

从概念到使用全面了解Llama 3 这个迄今为止最强大的开源模型

概述 mate最近发布了 Llama3,下一代最先进的开源大语言模型(LLM)。正如本文的综合评论所述,Llama 3 以其前身奠定的基础为基础,旨在增强 Llama 2 成为 ChatGPT 重要开源竞争对手的能力 Llama 2:深入探讨 C…

Spring Boot驱动的足球青训俱乐部管理解决方案

1 绪论 1.1研究背景 随着科技的发展,计算机的应用,人们的生活方方面面都和互联网密不可分。计算机的普及使得人们的生活更加方便快捷,网络也遍及到我们生活的每个角落,二十一世纪信息化时代的到来,随着社会科技的不断…

中国电信解锁万亿参数大模型:TeleAI的创新与突破

首个由万卡集群训练出来的万亿参数大模型,已被一家央企解锁。 具体而言,为了推动纯国产人工智能的探索,带来这条新路径的正是中国电信人工智能研究院(TeleAI)。 该研究院由中国电信集团的CTO、首席科学家兼院长李学龙…

docker零基础入门教程

注意 本系列文章已升级、转移至我的自建站点中,本章原文为:Docker入门 目录 注意1.前言2.docker安装3.docker基本使用4.打包docker镜像5.docker进阶 1.前言 如果你长期写C/C代码,那你应该很容易发现C/C开源项目存在的一个严重问题&#xff…

【React】入门Day01 —— 从基础概念到实战应用

目录 一、React 概述 二、开发环境创建 三、JSX 基础 四、React 的事件绑定 五、React 组件基础使用 六、组件状态管理 - useState 七、组件的基础样式处理 快速入门 – React 中文文档 一、React 概述 React 是什么 由 Meta 公司开发,是用于构建 Web 和原生…

XFTP-8下载安装教程

下载地址 https://www.xshell.com/zh/free-for-home-school/ 新建XFTP文件夹 安装过程 选择新建的文件夹 此处默认即可 填写信息提交注册 点击生成的链接 点击后来,完成安装

WebRTC Connection Negotiate解决

最近有个项目 ,部署之后一直显示,查了一些资料还是没有解决,无奈只有自己研究解决? 什么是内网穿透? 我们访问我们自己的官网产品页面,我们的服务器是一个单独的个体,有独立的公网ip&#xf…

Redis实现每日签到(大数据量)

PHP语言使用Redis NoSQL服务器二进制数据类型实现大数据情况下签到功能 目录 问题 解决方式 封装签到类 功能调用 总结 问题 实现用户每日签到功能不难,但随着用户量上升之后,不论是存储还是判断对数据量来说都很麻烦;假如每天有100万用…

文心一言 VS 讯飞星火 VS chatgpt (359)-- 算法导论24.3 1题

一、在图 24-2上运行Dijkstra算法,第一次使用结点 s s s作为源结点,第二次使用结点 z z z作为源结点。以类似于图 24-6 的风格,给出每次while循环后的 d d d值和 π π π值,以及集合 S S S中的所有结点。如果要写代码&#xff0c…

使用容器启动的zk无法暴露3888问题解决

1. 问题描述 zk配置如下: 我通过容器启动了一个zk,通过-p 参数暴露了2181和3888端口,容器启动脚本如下: #!/bin/shdocker rm -f myzookeeper1docker run -p 12181:2181 -p 13888:3888 --name myzookeeper1 --restart always …