设计模式——七大原则

​更多内容,前往 IT-BLOG

​设计模式的目的是为了让程序,具有更好的代码重用性、可读性(编程规范性,便于后期维护和理解)、可扩展性(当需要增加新需求时,非常方便)、可靠性(增加新功能后,对原功能么有影响)、使程序呈现高内聚,低耦合的特性。设计模式包含了面向对象的精髓,“懂了设计模式,就懂得了面向对象分析和设计(OOA/D)的核心”

一、单一职责原则

单一职责原则(SRP:Single responsibility principle)又称为单一功能原则: 它规定一个类应该只负责一项职责。

单一职责原则注意事项和细节:
1)、降低类的复杂度,一个类只负责一项职责。
2)、提高类的可读性,可维护性。
3)、降低变更引起的风险。
4)、通常情况下,我们应当遵守单一职责原则,只有当逻辑足够简单时,才可以在代码级别违反单一职责原则;只有类中方法足够少,可以在方法级别保持单一职责原则。

二、接口隔离原则

接口隔离原则(Interface Segregation Principle,ISP)的定义: 客户端不应该依赖它不需要的接口类,类之间的依赖关系应该建立在最小的接口上。一句话,就是实现接口的类中,有多余的方法时,需要将接口进行拆分。

接口隔离原则的规范:
1)、使用接口隔离原则前首先需要满足单一职责原则。
2)、接口需要高内聚,也就是提高接口、类、模块的处理能力,少对外发布public的方法。
3)、定制服务,就是单独为一个个体提供优良的服务,简单来说就是拆分接口,对特定接口进行定制。
4)、接口设计是有限度的,接口的设计粒度越小,系统越灵活,但是值得注意不能过小,否则变成"字节码编程"。

接口隔离解决的问题如下(实现类实现了接口中不需要的抽象方法):

//接口
interface Interface1 {void operation1();void operation2();void operation3();
}class B implements Interface1 {public void operation1() {System.out.println("B 实现了 operation1");}public void operation2() {System.out.println("B 实现了 operation2");}public void operation3() {System.out.println("B 实现了 operation3");}
}
//问题所在:A类只用到了B类的 1,2 方法,但B类却要实现方法3,造成代码的冗余。
class A { //A 类通过接口Interface1 依赖(使用) B类,但是只会用到1,2方法public void depend1(Interface1 i) {i.operation1();}public void depend2(Interface1 i) {i.operation2();}
}

遵循接口隔离原则后(将抽象方法进行隔离,当需要时实现多个接口即可) :

// 接口1
interface Interface1 {void operation1();void operation2();
}// 接口2
interface Interface2 {void operation3();
}class B implements Interface1 {public void operation1() {System.out.println("B 实现了 operation1");}public void operation2() {System.out.println("B 实现了 operation2");}}class A { // A 类通过接口Interface1,Interface2 依赖(使用) B类,但是只会用到1,2,3方法public void depend1(Interface1 i) {i.operation1();}public void depend2(Interface2 i) {i.operation2();}
}

三、依赖倒置原则

依赖倒转原则(Dependency Inversion Principle,DIP)的定义: 程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

依赖倒置的原则:
1)、高层模块不应该依赖底层模块,二者都应该依赖其抽象。
2)、抽象不应该依赖细节(实现类),细节应该依赖抽象。
3)、依赖倒置的中心思想是面向接口编程。
4)、依赖倒置的的设计理念是:相对于细节的多样性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳的多。在 Java 中,抽象指的是接口和抽象类,细节就是具体的实现类。
5)、使用接口或抽象类的目的是定制好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。

依赖倒置解决的问题如下(方法中传入的参数为类,而不是接口):

//完成 Person 接收消息的功能:这里receive方法中直接传入的对象是 类 也是依赖倒置重要强调的问题所在。
/**1. 如果我们获取的对象是 微信,短信等等,则新增类,同时Perons也要增加相应的接收方法getInfo()* 2. 解决思路:引入一个抽象的接口IReceiver, 表示接收者, 这样Person类与接口IReceiver发生依赖* 因为Email, WeiXin 等等属于接收的范围,他们各自实现IReceiver 接口就ok, 这样我们就符号依赖倒转原则*/
class Person {public void receive(Email email ) {System.out.println(email.getInfo());}
}class Email {public String getInfo() {return "电子邮件信息: hello,world";}
}

遵循依赖倒置原则后(方法中传入的参数修改为接口) :

public class DependecyInversion {public static void main(String[] args) {Person person = new Person();//当为电子邮件时,传入邮件对象person.receive(new Email());//当为微信时,传入微信对象person.receive(new WeiXin());}}//定义接口
interface IReceiver {public String getInfo();
}
//原电子邮件类,实现接口
class Email implements IReceiver {public String getInfo() {return "电子邮件信息: hello,world";}
}//增加微信
class WeiXin implements IReceiver {public String getInfo() {return "微信信息: hello,ok";}
}//方法中传入接口
class Person {//这里我们是对接口的依赖public void receive(IReceiver receiver ) {System.out.println(receiver.getInfo());}
}

依赖传递的三种方式和案例:
【1】接口传递: 就是上面举例的方式。
【2】构造方法传递:

//方式2: 通过构造方法依赖传递//接口1interface IOpenAndClose {public void open(); //抽象方法}//接口2interface ITV {public void play();}//接口1的方法实现调用接口2,接口2的实现通过构造器传入class OpenAndClose implements IOpenAndClose{//成员public ITV tv;//构造器public OpenAndClose(ITV tv){//将传入的对象值复制给自己的成员变量this.tv = tv;}//调用的方法public void open(){this.tv.play();}}//--------------测试类-------------------public class DependencyPass {public static void main(String[] args) {openAndClose.open(changHong);//通过构造器进行依赖传递OpenAndClose openAndClose = new OpenAndClose(changHong);openAndClose.open();}}

【3】setter 方法传递: (将实现类通过 set 方法传入到目标对象中):

// 方式3 , 通过setter方法传递
interface IOpenAndClose {public void open(); // 抽象方法//相当于多添加了一个方法,只用来获取实现 ITV 接口的实现类,并赋值给自己的属性对象。public void setTv(ITV tv);
}
// ITV接口
interface ITV {public void play();
}
//目标类(逻辑处理类)当tv属性多次使用到时,可以用此方法实现
class OpenAndClose implements IOpenAndClose {private ITV tv;public void setTv(ITV tv) {this.tv = tv;}public void open() {this.tv.play();}
}
//接口 ITV 的实现类
class ChangHong implements ITV {@Overridepublic void play() {System.out.println("长虹电视机,打开");}}
//--------------------测试-----------------
public class DependencyPass {public static void main(String[] args) {OpenAndClose openAndClose = new OpenAndClose();//通过setter方法进行依赖传递openAndClose.setTv(changHong);openAndClose.open();}
}

依赖倒置原则的注意事项和细节:
1)、低层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好。
2)、变量的声明类型尽量是抽象类或接口,这样我们的变量引用和实际对象间,就存在一个缓冲区层,对于程序扩展和优化。
3)、继承时遵循理氏替换原则

四、里氏替换原则

里氏代换原则(Liskov Substitution Principle,LSP)的定义: 所有引用基类的地方必须能透明地使用其子类的对象,子类可以扩展父类的功能,但不能改变父类原有的功能。面向对象(Object Oriented,OO)继承性的思考和说明:
1)、继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契约,虽然它不强制要求所有子类都必须遵循这种契约,但是如果子类对这些已经实现的方法任意修改,就会对这个继承体系造成破坏。
2)、继承在给程序设计带来方便的同时,也带来了弊端。比如使用继承给程序带来侵入性,程序可移植性降低,增加对对象间的耦合性。如果一个类被其他的类所继承,则当此类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能产生故障。
3)、问题提出:在编程中如何正确的使用继承,答案是:遵循里氏替换原则

里氏替换原则基本介绍:
1)、里氏替换原则是在1988年,有麻省理工学院的一名姓里的女士提出的。
2)、如果对类型为T1的对象o1,对有类型为T2的对象o2,使得以T1定义的所有程序P中对象o1可以代替成o2,程序 P 的行为没有发生变化,那么类型T2是类型T1的子类型。换句话说,所有引用基类的地方能透明地使用其子类的对象。
3)、在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法。
4)、里氏替换原则告诉我们,继承实际上让两个类耦合性增强了,在适当的情况下,可以通过聚合、组合、依赖来解决问题。

里氏替换解决的问题如下:(子类重写了父类的方法)

// A类
class A {// 返回两个数的差public int func1(int num1, int num2) {return num1 - num2;}
}// B类继承了A
// 增加了一个新功能:完成两个数相加,然后和9求和
class B extends A {//这里,重写了A类的方法, 可能是无意识public int func1(int a, int b) {return a + b;}public int func2(int a, int b) {return func1(a, b) + 9;}
}

遵循里氏替换原则后(提取一个公共的类,将A类与B类进行组合) :

//创建一个更加基础的基类
class Base {//把更加基础的方法和成员写到Base类
}// A类
class A extends Base {// 返回两个数的差public int func1(int num1, int num2) {return num1 - num2;}
}// B类继承了A
// 增加了一个新功能:完成两个数相加,然后和9求和
class B extends Base {//如果B需要使用A类的方法,使用组合关系private A a = new A();//这里,重写了A类的方法, 可能是无意识public int func1(int a, int b) {return a + b;}public int func2(int a, int b) {return func1(a, b) + 9;}//我们仍然想使用A的方法public int func3(int a, int b) {return this.a.func1(a, b);}
}

五、开闭原则

开闭原则(Open Closed Principle,OCP)的定义是: 一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。模块应尽量在不修改原代码的情况下进行扩展。

开闭原则的基本介绍:
1)、开闭原则是编程中最基础、最重要的设计原则。
2)、一个软件实体,如类,模块和函数应该对扩展开发(提供方),对修改关闭(使用方)。用抽象构建框架,用实现扩展细节。
3)、当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是修改已有的代码来实现变化。
4)、编程中遵循其他原则,以及使用设计模式的目的就是遵循开闭原则

开闭原则解决的问题如下:(在使用方进行了代码修改)

//这是一个用于绘图的类 [使用方]
class GraphicEditor {//接收Shape对象,然后根据type,来绘制不同的图形public void drawShape(Shape s) {//**问题所在:此类属于使用方,但当我们需要扩展新的图形时,却要修改使用方,就不符合OCP原则if (s.m_type == 1) {drawRectangle(s);}else if (s.m_type == 2) {drawCircle(s);}}//绘制矩形public void drawRectangle(Shape r) {System.out.println(" 绘制矩形 ");}//绘制圆形public void drawCircle(Shape r) {System.out.println(" 绘制圆形 ");}
}//Shape类,基类
class Shape {int m_type;
}class Rectangle extends Shape {Rectangle() {super.m_type = 1;}
}
class Circle extends Shape {Circle() {super.m_type = 2;}
}

遵循开闭替换原则(将公共方法提取到抽象类,在实现类中实现需要调用的方法,使用类中直接调用公共方法即可) :

//这是一个用于绘图的类 [使用方]
class GraphicEditor {//接收Shape对象,调用draw方法public void drawShape(Shape s) {//直接调用公共方法即可,就算增加新的图形也无需修改此处,//当多个地方调用时,更能体现OCP的重要性,这里只是简单举例s.draw();}
}//Shape类,基类
abstract class Shape {//抽象方法public abstract void draw();
}
//[提供方]
class Rectangle extends Shape {@Overridepublic void draw() {// TODO Auto-generated method stubSystem.out.println(" 绘制矩形 ");}
}class Circle extends Shape {@Overridepublic void draw() {// TODO Auto-generated method stubSystem.out.println(" 绘制圆形 ");}
}

六、迪米特法则

迪米特法则(Law of Demeter,LOD),有时候也叫做最少知识原则(Least Knowledge Principle,LKP)定义是: 一个软件实体应尽可能少地与其他实体发生相互作用。迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块独立,相互之间不存在(或很少有)依赖关系。迪米特法则则不希望类之间建立直接的关系。如果真的有需要建立联系,也希望能通过它的友元类(中间类或者跳转类)来转达。

迪米特法则的规则:
1)、Only talk to your immediate friends(只与直接的朋友通讯):每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系, 我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖,关联,组合,聚合等。其中,我们称出现成员变量,方法参数,方法返回值中的类为直接的朋友,而出现在局部变量中的类不是直接的朋友(例如,在一个方法中new了一个类,那么此类就不属于直接朋友)。也就是说,陌生的类最好不要以局部变量的形式出现在类的内部。
2)、一个对象应该对其他对象保持最少的了解。
3)、类与类关系越密切,耦合度越大。
4)、迪米特法则指一个类对自己依赖的类知道的 越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的public 方法,不对外泄露任何信息。
5)、 迪米特法则还有个更简单的定义:只与直接的朋友通信。

迪米特法则解决的问题如下: (方法中出现了局部变量)

//通过查看如下代码会发现,CollegeEmployee 以局部变量的形式出现在方法 printAllEmployee 中,违反了迪米特法则
public class Demeter1 {//该方法完成输出学校总部和学院员工信息(id)void printAllEmployee(CollegeManager sub) {//分析问题//1. 这里的 CollegeEmployee 不是  SchoolManager的直接朋友//2. CollegeEmployee 是以局部变量方式出现在 SchoolManager//3. 违反了 迪米特法则//获取到学院员工List<CollegeEmployee> list1 = sub.getAllEmployee();System.out.println("------------学院员工------------");for (CollegeEmployee e : list1) {System.out.println(e.getId());}}

遵循迪米特法则后(将局部变量部分,提取到自己的类中):

public class DemeterUpdate {void printAllEmployee(CollegeManager sub) {//分析问题//1. 将输出学院的员工方法,封装到CollegeManagersub.printEmployee();}
}//管理学院员工的管理类
class CollegeManager {//输出学院员工的信息public void printEmployee() {//获取到学院员工List<CollegeEmployee> list1 = getAllEmployee();System.out.println("------------学院员工------------");for (CollegeEmployee e : list1) {System.out.println(e.getId());}}//返回学院的所有员工public List<CollegeEmployee> getAllEmployee() {List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();for (int i = 0; i < 10; i++) { //这里我们增加了10个员工到 listCollegeEmployee emp = new CollegeEmployee();emp.setId("学院员工id= " + i);list.add(emp);}return list;}
}

迪米特法则注意事项和细节:
1)、迪米特法则的核心是降低类之间的耦合。
2)、但是注意:由于每个类之间都减少了不必要的依赖,因此迪米特法则只是要求降低类之间(对象间)耦合关系,并不是要求完全没有依赖关系。

七、合成复用原则

合成复用原则的定义是: 原则是尽量使用合成/聚合的方法,而不是使用继承。
聚合用来表示“拥有”关系或者整体与部分的关系: 代表部分的对象有可能会被多个代表整体的对象所共享,而且不一定会随着某个代表整体的对象被销毁或破坏而被销毁或破坏,部分的生命周期可以超越整体。例如,班级和学生,当班级删除后,学生还能存在,学生可以被培训机构引用。

class OpenAndClose implements IOpenAndClose {private ITV tv;//通过set方法将ITV对象聚合到OpenAndClose对象中public void setTv(ITV tv) {this.tv = tv;}public void open() {this.tv.play();}
}

合成用来表示一种强得多的“拥有”关系: 在一个合成关系里,部分和整体的生命周期是一样的。一个合成的新对象完全拥有对其组成部分的支配权,包括它们的创建和湮灭等。使用程序语言的术语来说,合成的新对象对组成部分的内存分配、内存释放有绝对的责任。例如,一个人由头、四肢和各种器官组成,人与这些具有相同的生命周期,人死了,这些器官也就挂了。房子和房间的关系,当房子没了,房间也不可能独立存在。

class OpenAndClose implements IOpenAndClose {//将 ITV 对象组合到 OpenAndClose 对象中ITV tv = new ITV();
}

【总结】设计原则的核心思想:
【1】找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
【2】 针对接口编程,而不是针对实现编程。
【3】为了交互对象之间的松耦合设计而努力。

简单理解就是: 开闭原则是总纲,它指导我们要对扩展开放,对修改关闭;单一职责原则指导我们实现类要职责单一;里氏替换原则指导我们不要破坏继承体系;依赖倒置原则指导我们要面向接口编程;接口隔离原则指导我们在设计接口的时候要精简单一;迪米特法则指导我们要降低耦合。

设计模式就是通过这七个原则,来指导我们如何做一个好的设计。但是设计模式不是一套“奇技淫巧”,它是一套方法论,一种高内聚、低耦合的设计思想。我们可以在此基础上自由的发挥,甚至设计出自己的一套设计模式。

当然,学习设计模式或者是在工程中实践设计模式,必须深入到某一个特定的业务场景中去,再结合对业务场景的理解和领域模型的建立,才能体会到设计模式思想的精髓。如果脱离具体的业务逻辑去学习或者使用设计模式,那是极其空洞的。

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

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

相关文章

树莓派5一键安装C++版本OpenCV

安装环境 本人当前的安装环境&#xff1a; 树莓派5Raspberry Pi os (64-bit) Debian12 Bookworm 镜像下载地址 我这里是将镜像安装好后直接安装opencv&#xff0c;如果不是刚安装好的镜像需要注意是否有openCV的python之类的安装过&#xff0c;不然可能出现编译错误 一、扩展内…

SpringBoot中数据库的连接及Mybatis的配置和使用

目录 1 在pom.xml中引入相关依赖 2 对数据库进行配置 2.1 配置application.yml 2.2 idea连接数据库 (3.2.1有用到) 3 Mybatis的使用 3.1 测试文件的引入 3.2 使用 3.2.1 使用注解(有小技巧(✪ω✪)) 3.2.2 使用动态sql 1 在pom.xml中引入相关依赖 <dependencies&g…

海外多语言盲盒开发:打破语言障碍,连接全球消费者

随着全球化的加速和互联网的普及&#xff0c;语言障碍成为了影响跨国交流和商业活动的重要因素。为了满足跨国市场的需求&#xff0c;海外多语言盲盒开发成为了一个新兴的领域。本文将探讨海外多语言盲盒开发的意义、现状和未来发展。 一、海外多语言盲盒开发的意义 在全球化…

RedHat8.4安装邮件服务器

一、配置发件服务器 1.1 根据现场IP&#xff0c;配置主机名 vim /etc/hosts 192.168.8.120 mail.test.com 将主机名更改为邮件服务器域名mail.test.com 1.2 关闭防火墙&#xff0c;禁止开机启动 systemctl stop firewalld systemctl disable firewalld 1.3 关闭selinux v…

基于springboot就业信息管理系统源码和论文

随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;就业信息管理系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&#xff0c;而…

InnoDB 锁系统(小白入门)

1995年 &#xff0c;MySQL 1.0发布&#xff0c;仅供内部使用&#xff01; 开发多用户、数据库驱动的应用时&#xff0c;最大的一个难点是&#xff1a;一方面要最大程度地利用数据库的并发访问&#xff0c;另一方面还要确保每个用户能以一致性的方式读取和修改数据。 MVCC 并发…

基于python+控制台的员工信息管理系统

基于python控制台的员工信息管理系统 一、系统介绍二、效果展示三、其他系统实现四、获取源码 一、系统介绍 1.添加职工数据 2.显示职工数据 3.查询职工数据 4.修改职工数据 5.删除职工数据 6.保存职工数据 7.排序职工数据 8.统计职工工资数据 9.退出 二、效果展示 三、其他系…

从搜索引擎到答案引擎:LLM驱动的变革

在过去的几周里&#xff0c;我一直在思考和起草这篇文章&#xff0c;认为谷歌搜索正处于被颠覆的边缘&#xff0c;它实际上可能会影响 SEO 作为业务牵引渠道的可行性。 考虑到谷歌二十多年来的完全统治地位&#xff0c;以及任何竞争对手都完全无力削弱它&#xff0c;坦率地说&…

CSS transition(过渡效果)详解并附带示例

CSS过渡效果&#xff08;CSS transitions&#xff09;是一种在元素属性值发生变化时&#xff0c;通过指定过渡效果来实现平滑的动画效果的方法。通过定义起始状态和结束状态之间的过渡属性&#xff0c;可以使元素的变化更加流畅和可视化。 过渡效果的基本语法如下&#xff1a;…

远程监控电脑软件会保存哪些记录?

远程监控电脑软件是一种功能强大的辅助工具&#xff0c;能够监控到各种各样的东西&#xff0c;常被企业用于管理员工。那么&#xff0c;远程监控电脑软件都会监控保存哪些记录呢&#xff1f; 一、网络活动 无论是浏览器访问记录、下载记录还是网络聊天记录&#xff0c;它都能…

疑惑问题总结

目录 问题总结 1. 布局为啥用不同盒子,我只想用div ? 2. 为啥用辣么多类名? 3. 到底用margin还是 padding ? 4. 自己做没有思路? 最后一定多运用辅助工具,比如屏幕画笔,ps等等 问题总结 1. 布局为啥用不同盒子,我只想用div ? 标签都是有语义的,合理的地方用合理的标…

乐意购项目前端开发 #6

一、商品详情页面 代码模版 创建Detail文件夹, 然后创建index.vue文件 <script setup> import { getDetail } from "/api/goods/index"; import { ref, onMounted } from "vue"; import { useRoute } from "vue-router"; import { useCar…

P8722 [蓝桥杯 2020 省 AB3] 日期识别--2024蓝桥杯冲刺省一

点击跳转例题 知识点&#xff1a;字符串总结 注意事项在代码中 #include <bits/stdc.h> #define int long long //(有超时风险) #define PII pair<int,int> #define endl \n #define LL __int128using namespace std;const int N2e610,M1e310,mod998244353,INF0x3f…

SpringBoot 登录检验JWT令牌 生成与校验

JWT官网 https://jwt.io/ 引入依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version> </dependency>设置过期时间 LocalDateTime localDateTime LocalDateTime.now().…

STM32--SPI通信协议(1)SPI基础知识总结

前言 I2C (Inter-Integrated Circuit)和SPI (Serial Peripheral Interface)是两种常见的串行通信协议&#xff0c;用于连接集成电路芯片之间的通信&#xff0c;选择I2C或SPI取决于具体的应用需求。如果需要较高的传输速度和简单的接口&#xff0c;可以选择SPI。如果需要连接多…

驾照考试-科目三

有车阻挡 先踩刹车或者自然降速,估计要停了就踩离合换1档,然后踩刹车,再半制动起步,起步后再踩油门换2挡,然后维持速度。如果估计不会停,就等距离合适后再踩油门启动。(一般是停好些) 准备 上车,系安全带,调座位和镜子,检测灯光,手刹,挡位,远近交替灯闪两下,…

css1字体属性

一.font-family(字体系列&#xff09; 不同字体系统用&#xff0c;隔开&#xff1b; 多个字母的字体系统用“”&#xff1b; 二.font-size&#xff08;字体大小&#xff09;&#xff08;有单位px&#xff09;&#xff08;默认字体16px&#xff09; 三.font-weight&#xff08…

Leetcode—535. TinyURL 的加密与解密【中等】

2024每日刷题&#xff08;110&#xff09; Leetcode—535. TinyURL 的加密与解密 实现代码 class Solution { public:// Encodes a URL to a shortened URL.string encode(string longUrl) {while(!urlToCode.count(longUrl)) {string code;for(int i 0; i < 6; i) {code…

如何快速上手VUE框架并写出VUE简单的增删改查的的开发代码

要快速上手Vue框架并编写简单的增删改查&#xff08;CRUD&#xff09;开发代码&#xff0c;可以遵循以下步骤&#xff1a; 步骤1&#xff1a;了解Vue基本概念和原理 在开始编写代码之前&#xff0c;需要了解Vue的基本概念和原理&#xff0c;包括组件、数据双向绑定、指令、生命…

Blender使用Rigify和Game Rig Tool基础

做动画需要的几个简要步骤&#xff1a; 1.建模 2.绑定骨骼 3.绘制权重 4.动画 1.Rigify是干嘛用的&#xff1f; 》 绑定骨骼 2.Game Rig Tool干嘛用的&#xff1f; 》 修复Rigify绑定骨骼做的动画导入游戏引擎的问题&#xff0c;如果Rigify自身修复了就不需要这个插件了&#…