C#(14)七大原则
前言
其实在面向对象设计里,程序猿们互相约定好一些原则,即七大原则。
面向对象的七大原则是一组指导软件设计的原则,旨在帮助开发人员实现松耦合、可维护和可扩展的软件系统。这些原则的设计过程和发展历史可以追溯到20世纪80年代。
-
单一职责原则(Single Responsibility Principle):这个原则最早由罗伯特·C·马丁(Robert C. Martin)提出,并在他的《敏捷软件开发:原则、模式和实践》一书中详细阐述。该原则指出,一个类应该只有一个引起变化的原因,即一个类应该只负责一项职责。这样可以实现类的高内聚性和低耦合性。
-
开放关闭闭原则(Open-Closed Principle):开放封闭原则由伯特兰·梅耶(Bertrand Meyer)提出,他在他的《面向对象软件构造》一书中详细阐述了该原则。该原则指出,一个软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。这意味着当需求改变时,应该通过扩展现有实体而不是修改已有代码。
-
里氏替换原则(Liskov Substitution Principle):里氏替换原则由芭芭拉·利斯科夫(Barbara Liskov)提出,并在她的论文《数据抽象和层次类型》中详细阐述。该原则指出,子类对象应该能够替换所有使用基类对象的地方,而不会产生错误或违反系统的行为。这可以保证继承关系的正确性。
-
依赖倒置原则(Dependency Inversion Principle):依赖倒置原则由罗伯特·C·马丁提出,并在他的《敏捷软件开发:原则、模式和实践》一书中详细阐述。该原则指出,高层模块不应该依赖于低层模块,它们应该依赖于抽象。这样可以实现模块之间的松耦合。
-
接口隔离原则(Interface Segregation Principle):接口隔离原则由罗伯特·C·马丁提出,并在他的《敏捷软件开发:原则、模式和实践》一书中详细阐述。该原则指出,客户端不应该依赖于它不需要的接口。一个类只应该依赖于它所使用的接口,避免了不必要的依赖。
-
迪米特法则(Law of Demeter)(也叫最少知识原则):迪米特法则由伊恩·霍洛维茨(Ian Holland)和巴斯卡尔·勒格兰(Pascal Leroux)提出,并在他们的论文《迪米特法则对面向对象设计的影响》中详细阐述。该原则指出,一个对象应该对其他对象保持最少的了解,只与直接的朋友交流。这样可以减少对象之间的耦合。
-
合成复用原则(Composite Reuse Principle):合成复用原则由伊恩·霍洛维茨和巴斯卡尔·勒格兰提出,并在他们的论文《迪米特法则对面向对象设计的影响》中详细阐述。该原则指出,尽量使用对象组合,而不是继承来实现代码的复用。这样可以使系统更加灵活和可扩展。
随着面向对象编程的兴起和软件开发的需求不断演变,它们得到了广泛的应用和发展。这些原则的目标是提高软件系统的可维护性、可扩展性和可重用性,使软件的开发过程更加灵活和高效,而今天我们也将详细讲讲七大原则,希望能在日后的编程对你有所帮助。
简述
-
单一职责原则(Single Responsibility Principle,SRP):一个类应该只有一个变化的原因,即每个类应该只负责一项功能。
-
开放-关闭原则(Open/Closed Principle,OCP):软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。也就是说,可以通过扩展现有代码而不是修改它来实现新功能。
-
里氏替换原则(Liskov Substitution Principle,LSP):子类对象应该能够替换父类对象而不影响程序的正确性,确保子类的行为符合父类的预期。
-
接口隔离原则(Interface Segregation Principle,ISP):不应强迫客户端依赖于它们不使用的接口。应该将大的接口拆分成多个小接口,以便于实现和使用。
-
依赖反转原则(Dependency Inversion Principle,DIP):高层模块不应依赖于低层模块,二者都应依赖于抽象(接口或抽象类),而不应依赖于具体实现。
-
合成复用原则(Composite Reuse Principle,CRP):尽量使用对象的组合而不是继承来实现代码复用。组合关系比继承关系更灵活。
-
最少知识原则(Least Knowledge Principle,LKP):一个对象应该对其他对象有最少的了解。减少对象之间的耦合,通过公共接口进行交互。
可能你单看文字很多都还看不懂,有些东西甚至需要你学习了之后的东西再回来看,如果你是顺序查看博主的博文的话,建议只看里氏替换原则。
单一职责原则
基本概念
强调一个类应该只有一个单一的责任,即一个类应该仅仅负责一个功能或任务。
重点
- 单一性:每个类保持单一功能,简化类的接口。
- 职责划分:明确界定类的职责,避免交叉影响。
- 易维护性:变更一个责任时只需修改相关类,降低了风险。
作用
- 提高可读性和可理解性:清晰的职责使得代码更易于阅读和理解。
- 提升可维护性:减少了因改动引入的bug,因为每个类变更都与其单一的功能相关。
- 增强可重用性:聚焦于单一功能的类可以更容易地被重用于其他项目中。
示例
这个示例是其实也是大家在日后unity的设计中也经常使用的模式,当然,gamemanager用来具体干什么,就要视情况而定了。
using System;
using System.Collections.Generic;// 游戏管理类,负责管理游戏逻辑
class GameManager
{private Player player;private List<Enemy> enemies;public GameManager(){player = new Player();enemies = new List<Enemy>();InitializeEnemies();}// 初始化敌人private void InitializeEnemies(){enemies.Add(new Enemy("Enemy 1"));enemies.Add(new Enemy("Enemy 2"));enemies.Add(new Enemy("Enemy 3"));}// 游戏主循环public void Run(){while (true){player.Update();foreach (Enemy enemy in enemies){enemy.Update();}if (player.IsCollidingWithEnemy(enemies)){Console.WriteLine("Player collided with an enemy");break;}}}
}// 玩家类,负责玩家相关逻辑
class Player
{public void Update(){Console.WriteLine("Player is updating");}public bool IsCollidingWithEnemy(List<Enemy> enemies){// 检测玩家是否与敌人发生碰撞foreach (Enemy enemy in enemies){if (enemy.Position == this.Position){return true;}}return false;}// 玩家的其他属性和方法...
}// 敌人类,负责敌人相关逻辑
class Enemy
{public string Name { get; private set; }public int Position { get; private set; }public Enemy(string name){Name = name;Position = 0;}public void Update(){Console.WriteLine($"{Name} is updating");Position++;}// 敌人的其他属性和方法...
}class Program
{static void Main(string[] args){GameManager game = new GameManager();game.Run();}
}
开放-关闭原则
基本概念
开放-关闭原则是对象设计中的一种原则,其核心思想是“软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。
重点
- 开放性:允许在不改变现有代码的情况下添加新功能。
- 封闭性:现有的代码在功能上不会被修改,应该能安全地被使用。
- 通过继承和接口等机制支持灵活的扩展。
作用
- 增强软件的可维护性和可扩展性。
- 减少代码修改带来的风险,降低意外引入bug的可能性。
- 促进模块化设计,使得系统可以方便地进行部件替换或升级。
示例
在Main
方法中,我们创建了一个包含一个战士和一个法师角色的游戏场景对象,并调用了RunGame()
方法。由于Character
类是开放的,我们可以随时添加新的角色类而不需要修改GameScene
类的代码,同时GameScene
类的代码是关闭的,不需要对新的角色类进行修改,这就是所谓的开放关闭原则。
using System;// 游戏角色基类
abstract class Character
{public abstract void Attack();//可以在这里添加方法
}// 战士角色
class Warrior : Character
{public override void Attack(){Console.WriteLine("战士发起了一次普通攻击!");}
}// 法师角色,你还可以写一个牧师角色(相当于开放的)
class Mage : Character
{public override void Attack(){Console.WriteLine("法师施放了一次火球术!");}
}// 游戏场景类(相当于关闭了,不用管里面的)
class GameScene
{private Character[] characters;public GameScene(Character[] characters){this.characters = characters;}public void RunGame(){foreach (Character character in characters){character.Attack();}}
}class Program
{static void Main(string[] args){Character[] characters = { new Warrior(), new Mage() };GameScene gameScene = new GameScene(characters);gameScene.RunGame();}
}
里氏替换原则
基本概念
任何父类出现的地方,子类都可以替代
重点
语法表现——父类容器装子类对象,因为子类对象包含了父类的所有内容
作用
- 方便对象存储和管理
示例
简单写一个,我就不多解释了,就是简单的父类装子类。
using System;public class Shape
{public virtual double CalculateArea(){return 0;}
}public class Rectangle : Shape
{public double Width { get; set; }public double Height { get; set; }public override double CalculateArea(){return Width * Height;}
}public class Square : Shape
{public double SideLength { get; set; }public override double CalculateArea(){return SideLength * SideLength;}
}public class Program
{public static void Main(string[] args){Shape shape1 = new Rectangle { Width = 5, Height = 10 };Shape shape2 = new Square { SideLength = 5 };Console.WriteLine("Rectangle Area: " + shape1.CalculateArea());Console.WriteLine("Square Area: " + shape2.CalculateArea());}
}
接口隔离原则
基本概念
核心思想是“客户端不应该被迫依赖于它不使用的接口。” 简而言之,就是每个接口应该只包含客户端所需的方法,避免将多个不相关的方法聚合在一个接口中。
重点
- 细化接口:将大接口分拆为多个小接口,使得实现这些接口的类更为专注。
- 降低耦合度:使得类与接口的依赖关系更为精确,减小了系统之间的耦合,增强了灵活性。
- 提高可维护性:降低了不必要的方法对实现类的影响,修改接口时影响范围更小。
作用
- 增强系统的模块化,易于理解和维护。
- 提高代码的复用性,使不同的类能够更灵活地选择需要实现的接口。
- 降低修改某个接口时,导致其他代码破坏的风险。
示例
直接看例子,这个规范光靠说的话也很简单,就是不能把太多功能耦合到一个东西身上,打个比方,有些gamejam的顶级程序猿能把武器,道具这些全写到人物里面去,你可以从自己角度简单评价一下这个代码维护起来有多么逆天。
using System;// 定义不同接口:播放音频和播放视频分开,当然实际开发不一定这样分,但是你要知道为什么要这样规定
interface IPlayer
{void Play();
}interface IRecord
{void Record();
}// 实现接口
class VideoPlayer : IPlayer
{public void Play(){Console.WriteLine("开始播放视频");}
}class AudioPlayer : IPlayer, IRecord
{public void Play(){Console.WriteLine("开始播放音频");}public void Record(){Console.WriteLine("开始录音");}
}class Game
{private IPlayer player;public Game(IPlayer player){this.player = player;}public void Start(){player.Play();}
}class Program
{static void Main(string[] args){IPlayer videoPlayer = new VideoPlayer();IPlayer audioPlayer = new AudioPlayer();Game videoGame = new Game(videoPlayer);videoGame.Start(); // 输出:开始播放视频Game audioGame = new Game(audioPlayer);audioGame.Start(); // 输出:开始播放音频}
}
依赖反转原则
基本概念
这个的主要思想是“高层模块不应该依赖低层模块,二者都应该依赖抽象;抽象不应该依赖于细节,细节应该依赖于抽象。”说人话,依赖于抽象(接口或抽象类)而不是具体实现,这样可以减少模块之间的耦合。
重点
- 高层模块:指的是完成业务逻辑等高级功能的部分。
- 低层模块:指的是具体的实现细节,例如数据访问或硬件控制。
- 抽象:通常是一个接口或抽象类,用于定义高层模块和低层模块之间的交互。
作用
- 提高系统的灵活性和可扩展性,方便替换实现。
- 减少模块之间的耦合,使得更改低层实现时不影响高层逻辑。
- 提高代码的可测试性,通过依赖注入等方式简化单元测试。
示例
示例中,我们定义了一个接口 IWeapon
,以及两个实现类 Sword
和 Bow
。然后,在 Player
类中通过构造函数注入 IWeapon
接口的实例,以实现依赖反转原则。这样,我们可以根据需要选择不同的武器,而不需要修改 Player
类的代码。
在 Game
类的 Main
方法中,我们创建了一个 Player
实例,分别使用剑和弓箭进行攻击。这样,我们可以灵活地为角色选择不同的武器,而不需要修改 Game
类的代码。
using System;// 定义接口
public interface IWeapon
{void Attack();
}// 定义实现类
public class Sword : IWeapon
{public void Attack(){Console.WriteLine("使用剑攻击");}
}public class Bow : IWeapon
{public void Attack(){Console.WriteLine("使用弓箭攻击");}
}// 定义高层模块
public class Player
{private IWeapon weapon;// 通过构造函数注入依赖public Player(IWeapon weapon){this.weapon = weapon;}//避免了你在这里面写一堆道具和武器的方法public void Attack(){weapon.Attack();}
}// 示例程序
public class Game
{public static void Main(string[] args){IWeapon sword = new Sword();Player player1 = new Player(sword);player1.Attack();IWeapon bow = new Bow();Player player2 = new Player(bow);player2.Attack();}
}
合用复用原则
基本概念
大概意思是“你不会需要它”。这个原则强调在软件开发中,开发者不应该添加过多的功能或代码,只应当实现当前需求所需的功能,避免为了未来可能需要的功能而过度设计。
重点
- 避免过度设计:只开发当前需求所需的功能,避免考虑和实现未来可能不必要的功能。
- 简化代码:减少无谓的复杂性,让代码保持简洁和清晰。
- 提高维护性:随着代码变得复杂,维护的成本会增加,原则帮助保持代码的可维护性。
作用
- 降低项目的复杂度:代码更加简单,易于理解和维护。
- 提高开发效率:避免不必要的功能开发,从而节省时间和资源。
- 降低出错概率:减少不必要的逻辑和功能可以降低 bug 的数量,提高系统稳定性。
示例
没有示例,想要告诉你的更多是你要记住,不要画蛇添足
最少知识原则
基本概念
最少知识原则是面向对象设计中的一项原则,强调一个对象应当对其他对象有尽可能少的了解。说人话,一个对象应该只与直接的朋友(合作对象)进行交互,而不应该去了解其他对象之间的复杂关系。
重点
- 直接交互:对象只应与直接相关的对象进行通信,避免“连锁调用”。
- 封装性:通过减少对象间的知识,增强封装性,使对象能独立变化。
- 降低耦合:减少模块之间的依赖,有助于系统的维护和扩展。
作用
- 提高可维护性:系统的修改和维护更容易,因为对象之间的依赖关系被减少。
- 增强可读性:代码更容易理解,减少了对象之间复杂的交互模式。
- 促进独立性:使得各个模块之间能独立发展,减少了相互影响的风险。
示例
错误示范:假设我们有一个系统,其中 Order
类依赖于 Customer
和 Address
类
public class Address
{ public string Street { get; set; } public string City { get; set; }
} public class Customer
{ public Address Address { get; set; }
} public class Order
{ public Customer Customer { get; set; } public void PrintShippingAddress() { // 连锁调用,不符合最少知识原则 Console.WriteLine($"Shipping to: {Customer.Address.Street}, {Customer.Address.City}"); }
}
改进后:
public class Address
{ public string Street { get; set; } public string City { get; set; } public string GetFullAddress() { return $"{Street}, {City}"; }
} public class Customer
{ public Address Address { get; set; } public string GetShippingAddress() { return Address.GetFullAddress(); }
} public class Order
{ public Customer Customer { get; set; } public void PrintShippingAddress() { // 只与 Customer 交互,符合最少知识原则 Console.WriteLine($"Shipping to: {Customer.GetShippingAddress()}"); }
}
我想这个示例能让你明白这是什么个情况
总结
七大原则本身其实是大家不断探索后发现的约定,其实你可以不这样写程序,当然你在遇到长期项目的时候必然会遇到很多问题,规范的代码有主意你更好地进行长线开发。
可能博主对着七大原则的理解也有一些误区,欢迎批评指正。
还是那句话,学习路上,脚踏实地。
请期待我的下一篇博客!
我来自佑梦游戏开发,感谢你的关注和收藏!
相关文章:
C#(14)七大原则
前言 其实在面向对象设计里,程序猿们互相约定好一些原则,即七大原则。 面向对象的七大原则是一组指导软件设计的原则,旨在帮助开发人员实现松耦合、可维护和可扩展的软件系统。这些原则的设计过程和发展历史可以追溯到20世纪80年代。 单一职…...
JDBC使用连接池druid操作数据库mysql
// 创建DruidDataSource实例DruidDataSource dataSource = new DruidDataSource();String url = "jdbc:mysql://localhost:3306/demo_base?useUnicode=true&characterEncoding=utf8&useSSL=true";String username...
零碎04 MybatisPlus自定义模版生成代码
目录 背景 动手开干 需要的依赖包,需要注意mybatis-plus-generator的3.5版本是没有兼容历史版本的。 定义一个CodeGenerator类,负责生成代码和配置属性 Entity模版 背景 MybatisPlus代码生成使用默认的velocity模版解决不了定制化的需求࿰…...
rk3568-linux-5.10.160移植rtl8822cs wifi 模块纪要
rk3568-linux-5.10.160移植rtl8822cs wifi 模块纪要 1、将驱动添加到 kernel/drivers/net/wireless/rockchip_wlan/ 或者 kernel/drivers/net/wireless/realtek/rtlwifi/ 2、修改该目录下的makefile、kconfig 3、修改rtl8822cs/os_dep/linux/os_intfs.c,添加 MO…...
uniapp接入高德地图
下面代码兼容安卓APP和H5 高德地图官网:我的应用 | 高德控制台 ,绑定服务选择《Web端(JS API)》 /utils/map.js 需要设置你自己的key和安全密钥 export function myAMap() {return new Promise(function(resolve, reject) {if (typeof window.onLoadM…...
如何通过高效的缓存策略无缝加速湖仓查询
引言 本文将探讨如何利用开源项目 StarRocks 的缓存策略来加速湖仓查询,为企业提供更快速、更灵活的数据分析能力。作为 StarRocks 社区的主要贡献者和商业化公司,镜舟科技深度参与 StarRocks 项目开发,也为企业着手构建湖仓架构提供更多参考…...
微信小程序数据请求教程:GET与POST请求详解
微信小程序数据请求教程:GET与POST请求详解 引言 在微信小程序的开发过程中,数据请求是至关重要的一部分。通过与后端服务器进行通信,小程序能够获取动态数据,实现丰富的功能。在这篇文章中,我们将深入探讨微信小程序中的数据请求,重点介绍GET和POST请求的使用方法、示…...
【Redis 】Bitmap 使用
Redis Bitmap介绍 Redis Bitmap 是一种特殊的数据类型,它通过字符串类型键来存储一系列连续的二进制位(bits),每个位可以独立地表示一个布尔值(0 或 1)。这种数据结构非常适合用于存储和操作大量二值状态的…...
【C语言】指针与数组的例题详解:深入分析与高级用法
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 💯前言💯题目一详细分析与解答代码逐步解析 💯进一步优化和拓展1. 指针与数组的关系2. 指针运算的注意事项3. 常见的错误和陷阱4. 拓展:指针操作的应用场…...
CTF之密码学(密码特征分析)
一.MD5,sha1,HMAC,NTLM 1.MD5:MD5一般由32/16位的数字(0-9)和字母(a-f)组成的字符串 2.sha1:这种加密的密文特征跟MD5差不多,只不过位数是40(sha256:64位;sha512:128位) 3.HMAC:这种算法就是在前两种加密的基础上引入了秘钥,而秘钥又只有传输双方才知道,所以基本上…...
docker compose 使用记录
作用 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过一个 YAML 文件来配置应用程序的服务,然后使用一个命令即可创建并启动所有服务。 文档位置 Part 7: Use Docker Compose | Docker Docs 使用方法 1. 安装 Docker Compose sudo curl -…...
Python的3D可视化库 - vedo (3)visual子模块 点对象的可视化控制
文章目录 3 PointsVisual的方法3.1 对象属性3.1.1 顶点大小3.1.2 复制属性3.1.3 颜色设置3.1.4透明度设置 3.2 对象光效3.2.1 点的形状3.2.2 点的表面光效 3.3 尾随线和投影3.3.1 尾随线3.3.2 投影 3.4 给对象附加文字说明3.4.1 标注3.4.2 2D标注3.4.3 气泡说明3.4.4 旗标说明3…...
计算机网络易混淆知识点串记
文章目录 计算机网络易混淆知识点串记各层PDU首部:地址长度 计算机网络易混淆知识点串记 各层PDU首部: PUD首部长度 (B:字节)首部单位数据链路–帧帧首:14B帧尾部:4B——IPV420~60字节4B [通过4位二进制表示]IPV6固定首部40字节[可拓展]4BTCP20~60字节4BUDP8B字节 地址长度 …...
信息安全实验--密码学实验工具:CrypTool
1. CrypTool介绍💭 CrypTool 1的开源教育工具,用于密码学研究。通过CrypTool 1,可以实现加密和解密操作,数字签名。CrypTool1和2有很多区别的。 2. CrpyTool下载🔧 在做信息安全实验--密码学相关实验时,发…...
Leetcode 将有序数组转换为二叉搜索树
算法思想及代码解析: 这段代码的目的是将一个有序数组转换为 高度平衡的二叉搜索树(Balanced Binary Search Tree, BST)。以下是算法的详细解释: 1. 什么是高度平衡的二叉搜索树? 二叉搜索树:对于树中的每…...
VMware虚拟机安装Win7专业版详细教程(附镜像包)
目录 一、Win7镜像下载 二、配置虚拟机 三、安装Win7 四、常见问题 一、Win7镜像下载 镜像下载链接:https://pan.quark.cn/s/a8d3a2880101 此镜像为Win7专业版(收藏级镜像 已自用几年) 官方纯净系统没有附带任何其他第三方软件…...
IDEA算法的详细介绍及Python实现
目录 IDEA算法的详细介绍及Python实现引言第一部分:IDEA算法的原理与背景1.1 IDEA算法的来源与特点1.2 IDEA算法的核心步骤第二部分:IDEA算法的Python实现(面向对象设计)2.1 核心类设计2.2 代码实现2.3 使用示例第三部分:案例1 - 函数优化问题(策略模式)3.1 问题描述3.2…...
Spring Boot 开发环境搭建详解
下面安装spring boot的详细步骤,涵盖了从安装 JDK 和 Maven 到创建和运行一个 Spring Boot 项目的全过程。 文章目录 1. 安装 JDK步骤 1.1:下载 JDK步骤 1.2:安装 JDK步骤 1.3:配置环境变量 2. 安装 Maven步骤 2.1:下载…...
Element-Ui组件(icon组件)
一、前言 本篇文章主要是对官网的Icon组件进行总结归纳Icon 图标 | Element Plus 在现代Web应用开发中,图标是用户界面设计中不可或缺的一部分。它们不仅提升了用户体验,还使得信息的传达更加直观和高效。本文主要对Element Plus 官方提供的Icon组件进行…...
使用docker搭建hysteria2服务端
源链接:https://github.com/apernet/hysteria/discussions/1248 官网地址:https://v2.hysteria.network/zh/docs/getting-started/Installation/ 首选需要安装docker和docker compose 切换到合适的目录 cd /home创建文件夹 mkdir hysteria创建docke…...
Docker login 报证书存储错误的解决办法
文章目录 docker login 出现错误,提示:Error saving credentials: error storing credentials - err: exit status 1, out: Cannot autolaunch D-Bus without X11 $DISPLAY 环境 使用的是 Mint Linux ,容器为 docker-ce 最新版 1 2 3 4 $…...
vxe-modal VxeUI 窗口组件弹窗多窗口模式
VxeUI 实现在 vue 中使用弹窗组件,弹窗多个窗口可叠加,实现多实例的窗口组件。 npm install vxe-pc-ui4.3.6// ...import VxeUI from vxe-pc-uiimport vxe-pc-ui/lib/style.css// ...createApp(App).use(VxeUI).mount(#app)// ...官网:https…...
华为昇腾 acl_pytorch
目录 sam部署教程: segment-anyghing地址: sam onnx地址: 报错: encode继续报错: sam部署教程: Ascend/ModelZoo-PyTorch - Gitee.com segment-anyghing地址: https://github.com/visher…...
Mybatis控制台打印SQL执行信息(执行方法、执行SQL、执行时间)
文章目录 前言一、基本功能介绍1.1本章功能效果预览图: 二、可执行源码2.1 yaml基础配置2.2 MybatisAnalyzeSQLInterceptor实现SQL拦截 前言 SQL性能监控是一个程序必要的功能,通常我们可以使用数据库自带的客户端工具进行SQL性能分析。然而对于一些专业度不高的人…...
Easyui 实现订单拆分开票功能
Easyui 实现订单拆分开票功能 需求 1、实现一个订单开具多分发票功能; 2、支持拆行; 3、支持拆数量; 流程设计 1、操作页面展示订订单头信息,订单明细信息 2、点击新增发票按钮弹出一个弹出框用于创建一张拆分发票,弹…...
docker-elasticsearch-kibana-logstash
一、安装 Elasticsearch 尝试直接拉取 Elasticsearch 镜像: 执行 docker pull docker.elastic.co/elasticsearch/elasticsearch,拉取失败,错误提示为 “Error response from daemon: manifest for docker.elastic.co/elasticsearch/elasticse…...
深入理解注意力机制(Attention Mechanism)
在深度学习中,“注意力机制(Attention Mechanism)”是近年来的一个重要突破。它最初被提出用于处理自然语言处理(NLP)任务,但如今已经广泛应用于计算机视觉、强化学习和其他领域。注意力机制赋予模型一种“…...
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
点一下关注吧!!!非常感谢!!持续更新!!! Java篇开始了! 目前开始更新 MyBatis,一起深入浅出! 目前已经更新到了: Hadoop࿰…...
vitess使用:基于源码运行vtctldclient工具
继续未完成的探索事业。 这篇文章《vitess使用:从部署到go客户端连接查询》记录了基于官方文档起的一个vitess的server。由于设置分库分表的规则,需要使用vtctldclient这个工具,这个工具的摸索费了诸多周折,《vitess使用记录&…...
计算机毕业设计 | SpringBoot+vue健身房管理系统(附源码+论文)
1,研究背景 互联网概念的产生到如今的蓬勃发展,用了短短的几十年时间就风靡全球,使得全球各个行业都进行了互联网的改造升级,标志着互联网浪潮的来临。在这个新的时代,各行各业都充分考虑互联网是否能与本行业进行结合…...
计算机网络-GRE(通用路由封装协议)简介
昨天我们学习了VPN的基本概念,虚拟专用网络在当前企业总部与分支间广泛使用。常用的划分方法为基于协议层次有GRE VPN、IPSec VPN、L2TP VPN、PPTP VPN、SSL VPN等。其实我有考虑该怎么讲,因为在IP阶段好像虚拟专用网络讲得不深,在IE的阶段会…...
汽车渲染领域:Blender 和 UE5 哪款更适用?两者区别?
在汽车渲染领域,选择合适的工具对于实现高质量的视觉效果至关重要。Blender和UE5(Unreal Engine 5)作为两大主流3D软件,各自在渲染动画方面有着显著的差异。本文将从核心定位与用途、工作流程、渲染技术和灵活性、后期处理与合成四…...
服务器数据恢复—光纤存储FC硬盘数据恢复案例
服务器存储数据恢复环境: 某品牌光纤存储上共有16块FC硬盘。存储上的卷映射到Linux操作系统上。Linux操作系统上运行Oracle数据库。 服务器存储故障&检测: 存储上2块硬盘故障灯亮起,存储映射到linux操作系统上的卷挂载不上,业…...
MySQL系列之远程管理(安全)
导览 前言Q:如何保障远程登录安全一、远程登录的主要方式1. 用户名/口令2. SSH3. SSL/TLS 二、使用TLS协议加密连接1. 服务端2. 客户端 结语精彩回放 前言 在我们的学习或工作过程中,作为开发、测试或运维人员,经常会通过各类客户端软件&…...
硬菜!高精度!BO-Transformer贝叶斯优化编码器多特征分类预测/故障诊断
硬菜!高精度!BO-Transformer贝叶斯优化编码器多特征分类预测/故障诊断 目录 硬菜!高精度!BO-Transformer贝叶斯优化编码器多特征分类预测/故障诊断效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现BO-Transform…...
idea_常用设置
相关设置 项目的JDK设置out目录取消自动更新设置主题设置菜单和窗口字体大小滚轮调节字体大小显示行号与方法分隔符代码智能提示忽略大小写自动导包配置设置项目文件编码设置控制台的字符编码修改类头的文档注释信息设置自动编译 项目的JDK设置 File -> Project Structure -…...
C# 中的异步流:高效处理序列数据
C#中的异步流(Async Streams)。异步流是C# 8.0引入的一个新特性,它允许你异步地处理序列数据,非常适合处理大量数据或长时间运行的任务。以下是一篇关于C#中异步流的文章。 引言 在现代应用程序开发中,处理大量数据或…...
Spring WebFlux SSE(服务器发送事件)的正确用法
在SpringBoot2下SSE实现是返回一个SseEmitter,然后通过SseEmitter的send方法来发送事件. 在SpringBoot3的WebFlux 下SSE实现是返回一个Flux<ServerSentEvent<?>>,但是怎么手动向客户端发送SSE事件搜遍全网也没有看到一个讲清楚的.网上的例子一般都是这样的: GetM…...
pyhton+yaml+pytest+allure框架封装-全局变量渲染
我们在日常测试中 会有一个接口中多个值的情况 比如这种 { "name": "thread", "value": "4986-MainThread", "status": "framework", "start": "pytest", …...
Redis五大基本类型——Set集合命令详解(命令用法详解+思维导图详解)
目录 一、Set集合类型介绍 二、常见命令 1、SADD 2、SMEMBERS 3、SISMEMBER 4、SCARD 5、SRANDMEMBER 6、SPOP 7、SMOVE 8、SREM 编辑 9、集合间操作 (1)SINTER (2)SINTERSTORE (3)SUNION…...
网络协议之邮件协议(SMTP、POP3与IMAP)
一、引言 在数字化时代,电子邮件已成为人们日常沟通和信息交流的重要工具。电子邮件系统的稳定运行离不开一系列网络协议的支撑,其中SMTP、POP3和IMAP是最为关键的三个协议。它们分别负责邮件的发送、接收和管理,共同构建了一个高效、稳定的…...
【GAMES101笔记速查——Lecture 20 Color and Perception】
颜色与感知 目录 1 光场(Light Field / Lumigraph) 1.1 全光函数 1.1.1 改进:引入波长 1.1.2 改进:添加时间t 1.1.3 改进:人可以移动,添加空间坐标 1.1.4 改进:不把函数当电影来看。 1.…...
全新配置ubuntu18.04深度学习环境
1、下载显卡驱动 1.1、驱动下载 连接:显卡驱动 手动驱动搜索-》查找-》查看-》下载 下载可使用指令 wget https://us.download.nvidia.com/XFree86/Linux-x86_64/535.216.01/NVIDIA-Linux-x86_64-535.216.01.run 2、下载安装cuda12.0 wget https://developer.do…...
C++初阶——类和对象(下)
目录 1、再探构造函数——初始化列表 2、类型转换 3、static成员 4、友元 5、内部类 6、匿名对象 7、对象拷贝时编译器的优化(了解) 1、再探构造函数——初始化列表 1. 构造函数初始化除了使用函数体内赋值,还有一种方式——初始化列表, 初始化列…...
Android Framework SurfaceFlinger面试题及参考答案
目录 请简述 SurfaceFlinger 在 Android 系统中的作用。 SurfaceFlinger 是如何与 CPU、GPU 以及显示器协同工作的? 解释一下 Android 系统中的三块 Graphic Buffer 及其用途。 VSYNC 信号在 Android 渲染机制中扮演什么角色? 请描述 SurfaceFlinger 如何分发 VSYNC 信号…...
STM32 外设简介
STM32 外设简介 STM32 是由意法半导体 (STMicroelectronics) 开发的一系列基于 ARM Cortex 内核的微控制器,广泛应用于嵌入式系统中。STM32 系列的一个重要特点是其丰富而强大的外设模块,支持多种接口和功能,能满足工业控制、物联网、消费电…...
java操作doc——java利用Aspose.Words操作Word文档并动态设置单元格合并
在实际工作中,如果业务线是管理类项目或者存在大量报表需要导出的业务时,可以借助第三方插件实现其对应功能。 尤其是需要对word文档的动态操作或者模板数据的定向合并,使用Aspose会相对来说容易一些,而且相关文档比较完整&#…...
人工智能—机器学习-图像处理
1. 人工智能(AI) 定义:人工智能是计算机科学的一个分支,旨在开发能够模拟人类智能的系统,包括学习、推理、问题解决、感知和语言理解等能力。子领域: 机器学习(ML):使计…...
数据结构——树
参考:数据结构(C版)第2版 [王红梅] 文章目录 树和二叉树基本术语二叉树概念二叉树的性质二叉树的存储顺序存储二叉链表 二叉树的遍历广度遍历深度遍历 树和二叉树 基本术语 结点的度、树的度:某结点拥有子树的个数为该结点的度&…...
快速理解微服务中Fegin的概念
一.由来 1.在传统的架构里面,我们是通过使用RestTemplate来访问其他的服务,但是这种方式就存在了一个很大的缺陷,也就是被调用方如果发生了服务的迁移(IP和端口发生了变化),那么调用方也需要同步的在代码里面进行修改,…...