【设计模式】1、设计模式七大原则
目录
- 一、单一职责
- 二、接口隔离
- 三、依赖倒置(倒转)
- 四、里氏替换
- 五、迪米特法则(Law of Demeter)
- 六、开闭
- 七、合成复用
一、单一职责
- 类(或方法)功能的专一性。一个类(或方法)不应该承担太多功能,一个类(或方法)最好只承担 一种类型 的功能。
public class SingleResponsibility {public static void main(String[] args) {Vehicle vehicle = new Vehicle();vehicle.run("汽车");vehicle.run("火车");vehicle.run("自行车");vehicle.run("飞机"); // 有问题vehicle.run("轮船"); // 有问题}
}class Vehicle {public void run(String vehicleName) {System.out.println(vehicleName + "在公路上行驶");}
}
Vehicle
类既处理陆地上的交通工具,又处理天空中的交通工具;它的作用太广泛了,不单一。
public class SingleResponsibility {public static void main(String[] args) {RoadVehicle roadVehicle = new RoadVehicle();roadVehicle.run("汽车");roadVehicle.run("火车");roadVehicle.run("自行车");SkyVehicle skyVehicle = new SkyVehicle();skyVehicle.run("飞机");WaterVehicle waterVehicle = new WaterVehicle();waterVehicle.run("轮船");}
}class RoadVehicle {public void run(String vehicleName) {System.out.println(vehicleName + "在公路上行驶");}
}class WaterVehicle {public void run(String vehicleName) {System.out.println(vehicleName + "在水中行驶");}
}class SkyVehicle {public void run(String vehicleName) {System.out.println(vehicleName + "在天空中行驶");}
}
在类级别遵循了单一职责原则
当业务功能比较简单的时候也没有必要将其拆分为多个类(如下所示)
public class SingleResponsibility {public static void main(String[] args) {Vehicle vehicle = new Vehicle();vehicle.run("汽车", VehicleType.ROAD);vehicle.run("火车", VehicleType.ROAD);vehicle.run("自行车", VehicleType.ROAD);vehicle.run("飞机", VehicleType.SKY);vehicle.run("轮船", VehicleType.WATER);}
}enum VehicleType {ROAD, WATER, SKY;
}class Vehicle {public void run(String name, VehicleType type) {String sentence = "";if (type == VehicleType.ROAD) {sentence = "在公路上行驶";} else if (type == VehicleType.WATER) {sentence = "在水中行驶";} else if (type == VehicleType.SKY) {sentence = "在天空中行驶";}System.out.println(name + sentence);}// public void roadRun(String name) {}// public void skyRun(String name) {}// public void waterRun(String name) {}
}
Vehicle
类不符合单一职责原则,但其功能简单 。
当功能非常非常简单的时候,不一定必须遵循单一职责原则。(杀鸡别用宰牛刀)
- 降低了类的功能的复杂度
- 提高了代码的维护性
- 代码修改导致连带错误几率降低
二、接口隔离
① Clients should not be forced to depend on methods they do not use. 客户端不应该被迫依赖它不使用的方法。
② The dependency of one class to another one should depend on the smallest possible interface. 一个类对另一个类的依赖应该建立在最小的接口上。
public class InterfaceSegregation {public static void main(String[] args) {InOutAbleImpl1 impl1 = new InOutAbleImpl1();InOutAbleImpl2 impl2 = new InOutAbleImpl2();Cat cat = new Cat();cat.use1(impl1);cat.use2(impl1);cat.use3(impl1);Dog dog = new Dog();dog.use1(impl2);dog.use2(impl2);dog.use3(impl2);}
}class Cat {public void use1(InOutAble inOutAble) {inOutAble.openDoor();}public void use2(InOutAble inOutAble) {inOutAble.pushGoods();}public void use3(InOutAble inOutAble) {inOutAble.writeGoodsName();}
}class Dog {public void use1(InOutAble inOutAble) {inOutAble.openDoor();}public void use2(InOutAble inOutAble) {inOutAble.popGoods();}public void use3(InOutAble inOutAble) {inOutAble.writePeopleName();}
}/*** 存取东西的接口*/
interface InOutAble {// 类型1void openDoor(); // 打开门// 类型2void pushGoods(); // 放入货物void writeGoodsName(); // 登记货物名字// 类型3void popGoods(); // 取出货物void writePeopleName(); // 登记取货人的名字
}class InOutAbleImpl1 implements InOutAble {@Overridepublic void openDoor() {System.out.println("InOutAbleImpl1 - openDoor");}@Overridepublic void pushGoods() {System.out.println("InOutAbleImpl1 - pushGoods");}@Overridepublic void writeGoodsName() {System.out.println("InOutAbleImpl1 - writeGoodsName");}@Overridepublic void popGoods() {System.out.println("InOutAbleImpl1 - popGoods");}@Overridepublic void writePeopleName() {System.out.println("InOutAbleImpl1 - writePeopleName");}
}class InOutAbleImpl2 implements InOutAble {@Overridepublic void openDoor() {System.out.println("InOutAbleImpl2 - openDoor");}@Overridepublic void pushGoods() {System.out.println("InOutAbleImpl2 - pushGoods");}@Overridepublic void writeGoodsName() {System.out.println("InOutAbleImpl2 - writeGoodsName");}@Overridepublic void popGoods() {System.out.println("InOutAbleImpl2 - popGoods");}@Overridepublic void writePeopleName() {System.out.println("InOutAbleImpl2 - writePeopleName");}
}
public class InterfaceSegregation {public static void main(String[] args) {OpenPushImpl impl1 = new OpenPushImpl();OpenPopImpl impl2 = new OpenPopImpl();Cat cat = new Cat();cat.use1(impl1);cat.use2(impl1);cat.use3(impl1);Dog dog = new Dog();dog.use1(impl2);dog.use2(impl2);dog.use3(impl2);}
}class Cat {public void use1(OpenPushImpl openPushImpl) {openPushImpl.openDoor();}public void use2(OpenPushImpl openPushImpl) {openPushImpl.pushGoods();}public void use3(OpenPushImpl openPushImpl) {openPushImpl.writeGoodsName();}
}class Dog {public void use1(OpenPopImpl openPopImpl) {openPopImpl.openDoor();}public void use2(OpenPopImpl openPopImpl) {openPopImpl.popGoods();}public void use3(OpenPopImpl openPopImpl) {openPopImpl.writePeopleName();}
}interface OpenDoorAble {void openDoor(); // 打开门
}interface PushAble {void pushGoods(); // 放入货物void writeGoodsName(); // 登记货物名字
}interface PopAble {void popGoods(); // 取出货物void writePeopleName(); // 登记取货人的名字
}class OpenPushImpl implements OpenDoorAble, PushAble {@Overridepublic void openDoor() {System.out.println("OpenPushImpl - openDoor");}@Overridepublic void pushGoods() {System.out.println("OpenPushImpl - pushGoods");}@Overridepublic void writeGoodsName() {System.out.println("OpenPushImpl - writeGoodsName");}
}class OpenPopImpl implements OpenDoorAble, PopAble {@Overridepublic void openDoor() {System.out.println("OpenPopImpl - openDoor");}@Overridepublic void popGoods() {System.out.println("OpenPopImpl - popGoods");}@Overridepublic void writePeopleName() {System.out.println("OpenPopImpl - writePeopleName");}
}
三、依赖倒置(倒转)
🍬 ① 高层模块不应该依赖低层模块(类),二者都应该依赖于抽象(接口)
🍬 ② 抽象(接口)不应该依赖细节(实现类),而是细节依赖于抽象
🍬 ③ 依赖倒置的中心思想是:面向接口(抽象)编程
🍬 ④ 依赖倒置设计理念:相对于细节的多变性,抽象的东西要稳定得多。以抽象为基础搭建的架构比以细节为基础搭建的架构要稳定
🍬 ⑤ 使用接口或抽象类的作用是:制定规范(协议);把展现细节的任务交给接口的实现类
接口 ➡️ 抽象
实现类 ➡️ 细节
public class DependencyInversion {public static void main(String[] args) {Person person = new Person();person.sendMessage(new QQMessage("用QQ问候一下小明"));person.sendMessage(new WechatMessage("用微信问候一下小明"));}
}class Person {public void sendMessage(QQMessage qqMessage) {System.out.println(qqMessage.buildMessage());}public void sendMessage(WechatMessage wechatMessage) {System.out.println(wechatMessage.buildMessage());}
}class QQMessage {private String message;public QQMessage(String message) {this.message = message;}public String buildMessage() {return "QQ Message: " + message;}
}class WechatMessage {private String message;public WechatMessage(String message) {this.message = message;}public String buildMessage() {return "Wechat Message: " + message;}
}
😰 假如版本升级,还想发送
抖音消息
的话:① 需要创建一个 TiktokMessage 类;② 需要在 Person 类中再重载一个sendMessage(TiktokMessage tiktokMessage)
方法
😰 每次版本升级,增加新的发送消息的方式的时候对代码的改动非常大。假如不止一个用户(不仅仅只有 Person 类),哪改动就更加巨大了
面向接口编程:
public class DependencyInversion {public static void main(String[] args) {Person person = new Person();person.sendMessage(new QQMessage("用QQ问候一下小明"));person.sendMessage(new WechatMessage("用微信问候一下小明"));}
}class Person {public void sendMessage(IMessage iMessage) {System.out.println(iMessage.buildMessage());}
}interface IMessage {String buildMessage();
}/*** 发送 QQ 消息*/
class QQMessage implements IMessage {private String message;public QQMessage(String message) {this.message = message;}@Overridepublic String buildMessage() {return "QQ Message: " + message;}
}/*** 发送微信消息*/
class WechatMessage implements IMessage {private String message;public WechatMessage(String message) {this.message = message;}public String buildMessage() {return "Wechat Message: " + message;}
}
四、里氏替换
继承优点:
🍬 提高代码的复用性(子类继承父类后可使用父类的非 private
关键字修饰的的成员)
public class Animal {public void eat() {System.out.println("Animal - public void eat()");}protected void drink() {System.out.println("Animal - protected void drink()");}void play() {System.out.println("Animal - void play()");}
}class Dragon extends Animal {public void use() {eat(); // Animal - public void eat()drink(); // Animal - protected void drink()play(); // Animal - void play()}public static void main(String[] args) {Dragon dragon = new Dragon();dragon.use();}
}
继承缺点:
🍬 ① 继承关系过去庞大的话,整个代码结构会很乱
🍬 ② 代码耦合性变高
🍬 ③ 代码稳定性变差(子类可以重写父类的方法。重写之后,运行时究竟调用的是父类的方法还是子类重写的方法很难判断)
🍬 ④ 如果有多处直接使用父类方法的实现,但凡父类方法修改了,所有依赖该父类方法的地方都得考虑兼容性(考虑代码是否会产生 bug)
(1) 子类可以实现父类的抽象方法,【不要覆盖父类的非抽象方法】 (2) 子类可以可以增加自己特有的实现,不要影响父类的非抽象方法【你用父类的可以,但不要改】 (3) 子类方法重载父类方法的时候,方法的形参要比父类方法的形参更宽松(父类方法的形参得是子类方法的形参的父类型)
public class Main {public static void main(String[] args) {Parent parent = new Parent();parent.m2(new ArrayList<>());Son son = new Son();son.m2(new ArrayList<>());/*Parent - m2(ArrayList<String>)Parent - m2(ArrayList<String>)*/}
}class Parent {public void m1() {System.out.println("Parent - m1()");}public void m2(ArrayList<String> list) {System.out.println("Parent - m2(ArrayList<String>)");}
}class Son extends Parent {// 不符合里氏替换原则(子类不应该重写父类的非抽象方法)@Overridepublic void m1() {System.out.println("Son - m1()");}// 子类重载父类的方法(子类重载的方法的参数类型要比父类被重载的方法的参数类型大)// 这样才符合里氏替换原则, 子类增加代码(如新增一个方法)不会影响父类方法的使用public void m2(List<String> list) {System.out.println("Son - m2(List<String>)");}
}
(4) 子类实现父类的抽象方法的时候,方法的返回值应比父类的更加严格
五、迪米特法则(Law of Demeter)
🍬 只与你的直接朋友交谈,不与陌生人交谈【降低类与类之间的耦合】
A ➡️ B ➡️ C
① A 和 B 是直接朋友
② B 和 C 是直接朋友
③ A 和 C 是陌生人
④ 若 A 想使用 C 中的方法,需要通过 B
🍬 直接朋友:
① 当前对象本身
② 当前对象的成员变量
③ 当前对象的成员方法的返回类型
④ 当前对象的成员方法的参数
class Parent {public void m() {// 在方法内部 new 出来的是非直接朋友User user = new User();}
} class User {}
六、开闭
🎄 Open Close Principe:软件对象(类、模块、方法等)应该对扩展开放,对修改关闭
🎄 用抽象构建框架,用实现扩展细节
🎄 开放 服务方 的拓展,关闭 消费方 的修改
public class OpenClosePrincipe {public static void main(String[] args) {// 对消费方的修改关闭// 尽量少修改原先的代码MilkTeaFactory factory = new MilkTeaFactory();factory.makeMilkTea(MilkTeaType.APPLE);factory.makeMilkTea(MilkTeaType.BANANA);}
}interface MilkTeaAble {}class AppleMilkTea implements MilkTeaAble {public AppleMilkTea() {System.out.println("苹果奶茶");}
}class BananaMilkTea implements MilkTeaAble {public BananaMilkTea() {System.out.println("香蕉奶茶");}
}enum MilkTeaType {APPLE, BANANA
}class MilkTeaFactory {public MilkTeaAble makeMilkTea(MilkTeaType type) {switch (type) {case APPLE:return new AppleMilkTea();case BANANA:return new BananaMilkTea();}return null;}
}
public class OpenClosePrincipe {// 修改依赖的类型(消费方代码没有修改)private static MilkTeaAble factory = new WatermelonMilkTeaFactory();public static void main(String[] args) {factory.milkTea();}
}interface MilkTeaAble {void milkTea();
}class AppleMilkTeaFactory implements MilkTeaAble {@Overridepublic void milkTea() {System.out.println("苹果奶茶");}
}class BananaMilkTeaFactory implements MilkTeaAble {@Overridepublic void milkTea() {System.out.println("香蕉奶茶");}
}class WatermelonMilkTeaFactory implements MilkTeaAble {@Overridepublic void milkTea() {System.out.println("西瓜奶茶");}
}
七、合成复用
📖 通过对象 组合、聚合、依赖 达成代码复用,而不是继承
class Animal {public void eat() {System.out.println("Animal - eat()");}public void drink() {System.out.println("Animal - drink()");}public void play() {System.out.println("Animal - play()");}
}/*** 继承(不推荐, 不符合合成复用原则)*/
class People1 extends Animal {public void use() {eat();drink();play();}
}/*** 依赖(推荐)*/
class People2 {public void use(Animal animal) {animal.eat();animal.drink();animal.play();}
}/*** 聚合(推荐)*/
class People3 {private Animal animal;public void setAnimal(Animal animal) {this.animal = animal;}public void use() {animal.eat();animal.drink();animal.play();}
}/*** 组合(推荐)*/
class People4 {private Animal animal = new Animal();public void use() {animal.eat();animal.drink();animal.play();}
}
相关文章:
【设计模式】1、设计模式七大原则
目录一、单一职责二、接口隔离三、依赖倒置(倒转)四、里氏替换五、迪米特法则(Law of Demeter)六、开闭七、合成复用一、单一职责 类(或方法)功能的专一性。一个类(或方法)不应该承担…...
【前端老赵的CSS简明教程】10-1 CSS预处理器和使用方法
大家好,欢迎来到本期前端课程。我是前端老赵,今天的课程将讲解CSS预处理器的概念和使用方法,希望能够帮助大家更好地进行前端开发。 CSS预处理器是什么? CSS预处理器是一种将类似CSS的语言转换为CSS的工具。它们提供了许多额外的功能,如变量、嵌套、混入、函数等等。这些…...
BFC详解
1. 引言 在前端的布局手段中,一直有这么一个知识点,很多前端开发者都知道有它的存在,但是很多人也仅仅是知道它的存在而已,对它的作用也只是将将说得出来,可是却没办法说得非常的清晰。这个知识点,就是BFC…...
C++:哈希结构(内含unordered_set和unordered_map实现)
unordered系列关联式容器 在C98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到$log_2 N$,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好 的查询是ÿ…...
Java实现调用第三方相关接口(附详细思路)
目录1.0.简单版2.0.升级版2-1.call.timeout()怎么传入新的超时值2-2.timeout(10, TimeUnit.SECONDS)两个参数的意思,具体含义3.0.进阶版3-1.java.net.SocketTimeoutException: 超时如何解决4.0.终极版1.0.简单版 以下是一个使用 Java 实际请求“第三方”的简单示例代…...
基础数据结构:单链表
今天懒洋洋学习了关于基础数据结构有关单链表的相关操作,懒洋洋来这温习一下。一:单链表的定义链表定义:用链式存储的线性表统称为链表,即逻辑结构上连续,物理结构上不连续。链表分类:单链表、双链表、循环链表、静态链…...
基于51单片机的智能计算器Protues仿真设计
目录 一、设计背景 二、实现功能 三、硬件设计 3.1 总体硬件设计 3.2 键盘电路的设计 3.3 显示电路的设计 四、仿真演示 五、源程序 一、设计背景 随着社会的发展,科学的进步,人们的生活水平在逐步的提高,尤其是微电子技术的发展&am…...
Pandas数据分析实战练习
Pandas数据分析实战练习 文章目录 Pandas数据分析实战练习一、读取Excel文件中的数据1、读取工号、姓名、时段、交易额这四列数据,使用默认索引,输出前10行数据2、读取第一个worksheet中所有列,跳过第1、3、5行,指定下标为1的列中数据为DataFrame的行索引标签二、筛选符合特…...
C++ 继承下(二篇文章学习继承所有知识点)
5.继承与友元友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员 //验证友元不能继承 class B {friend void Print(); public:B(int b): _b(b){cout << "B()" << endl;}protected:int _b; };class D : public B { public:D(int b,…...
【C++】C++11新特性——类的改进|lambda表达式
文章目录一、类的改进1.1 默认生成1.2 移动构造函数1.3 移动赋值重载函数1.4 成员变量缺省值1.5 强制生成默认函数的关键字default1.6 禁止生成默认函数的关键字delete1.6.1 C98防拷贝1.6.1 C11防拷贝二、lambda表达式2.1 对比2.2 lambda表达式语法2.3 捕捉列表2.4 函数对象与l…...
C语言进阶(37) | 程序环境和预处理
目录 1.程序的翻译环境和执行环境 2.详解编译链接 2.1 翻译环境 2.2 编译本身也分为几个阶段: 2.3 运行环境 3.预处理详解 3.1预定符号 3.2 #define 3.3 #undef 3.4 命令行定义 3.5 条件编译 3.6 文件包含 了解重点: 程序的翻译环境程序的执行环境详解: C语言程…...
Golang每日一练(leetDay0005)
目录 13. 罗马数字转整数 Roman to Integer ★ 14. 最长公共前缀 Longest Common Prefix ★ 15. 三数之和 3Sum ★★★ 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 13. 罗马数字转…...
occt_modeling_data(一)——拓扑
下面是我基于opencascade英文文档中关于occt_modeling_data中Topology部分进行的翻译,英文好的还是建议直接看文档,部分我不肯定的地方我会附上英文原句。如发现有错误欢迎评论区留言。 OCCT Topolog允许用户访问和操纵物体的数据,且不需要处…...
【AcWing】蓝桥杯备赛-深度优先搜索-dfs(3)
目录 写在前面: 题目:93. 递归实现组合型枚举 - AcWing题库 读题: 输入格式: 输出格式: 数据范围: 输入样例: 输出样例: 解题思路: 代码: AC &…...
宇宙最强-GPT-4 横空出世:最先进、更安全、更有用
文章目录前言一、准确性提升1.创造力2.视觉输入3.更长的上下文二、相比于ChatGPT有哪些提升1.GPT-4 的高级推理能力超越了 ChatGPT2.GPT-4 在多种测试考试中均优于 ChatGPT。三、研究团队在GPT-4模型都做了哪些改善1.遵循 GPT、GPT-2 和 GPT-3 的研究路径2.我们花了 6 个月的时…...
HashMap的实际开发使用
目 录 前言 一、HashMap是什么? 二、使用步骤 1.解析一下它实现的原理 编辑 2.实际开发使用 总结 前言 本章,只是大概记录一下hashMap的简单使用方法,以及理清一下hashMap的put方法的原理,以及get方法的原理。 一、Has…...
OpenCV入门(十三)快速学会OpenCV 12 图像梯度
OpenCV入门(十三)快速学会OpenCV 12 图像梯度1.Sobel算子1.1 计算x1.2 计算y1.3 计算xy2.Scharr算子2.1 计算x2.2 计算y2.3 计算xy3.Laplacian算子4.总结图像梯度计算的是图像变化的速度。对于图像的边缘部分,其灰度值变化较大,梯…...
软考:常见小题目计算题
01采购合同的类型采购合同主要包括总价类合同、成本补偿类合同、工料合同三大类合同。1、总价类合同此类合同为既定产品、服务或成果的采购设定一个总价。这种合同应在已明确定义需求,且不会出现重大范围变更的情况下使用。包括:(1࿰…...
【Linux】进程的程序替换
文章目录1. 程序替换1.创建子进程的目的是什么?2.了解程序是如何进行替换的3. 程序替换的基本原理当创建进程的时候,先有进程数据结构,还是先加载代码和数据?程序替换是整体替换,不是局部替换execl 返回值4. 替换函数1…...
【C++】模板(上)
文章目录1、泛型编程2、函数模板函数模板的实例化模板参数的匹配原则3、 类模板类模板的实例化1、泛型编程 void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(double& left, double& right) {double temp left;left …...
express框架利用formidable上传图片
express框架,在上传图片功能方面,用formidable里面的incomingform功能,很方便。很多功能都已经封装好了,非常好用,简单,不需要写更深层次的代码了。确实不错。 下面是我自己跟着黑马教程的博客系统的部分&…...
测试背锅侠?入职软件测试后大d佬给我丢了这个bug分类分析,至今受益匪浅......
目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 刚成为入职…...
STM32 OTA应用开发——通过内置DFU实现USB升级(方式1)
STM32 OTA应用开发——通过内置DFU实现USB升级(方式1) 目录STM32 OTA应用开发——通过内置DFU实现USB升级(方式1)前言1 硬件介绍2 环境搭建2.1 Keil uVsion2.2 zadig2.3 STM32CubeProgrammer2.4 安装USB驱动3 OTA升级结束语前言 …...
基于MFC的JavaScript进行网页数据交互
目录 前言 一、创建html对话框工程 二、使用步骤 1.引入JavaScript接口代码 2.重写相关接口 3.在html网页中添加C/C调用的接口 4.在MFC工程中添加调用接口 5.设置确认按键触发调用 6.运行结果 总结 前言 如何快速的进行MFC开发,这里我介绍一种JavaScript与C/C交互的…...
AUTOSAR-Fee
Fee模块 全称Flash EEPROM Emulation Module,属于ECU抽象层 Fee模块本身是脱离硬件的,但是Fee模块可能会引用的Fls模块定制API,所以只能算半抽象. FEE模块应从设备特定的寻址方案和分段中抽象出来,并为上层提供虚拟寻址方案和分段(virtual addressing scheme and segment…...
Linux基本命令——操作演示
Linux基本命令——操作演示Linux的目录结构Linux命令入门目录切换相关命令(cd/pwd)相对路径、绝对路径和特殊路径符创建目录命令(mkdir)文件操作命令part1 (touch、cat、more)文件操作命令part2 (cp、mv、rm)查找命令 …...
【Linux】目录和文件的权限
Linux中的权限有什么作用Linux权限管理文件访问者的分类文件类型和访问权限(事物属性)**文件权限值的表示方法**文件访问权限的相关设置方法chmodchownchgrpumaskumask使用 sudo分配权限目录的权限Linux中的权限有什么作用 Linux下有两种用户࿱…...
Unity 优化之Player Setting
Quality SettingPixel Light Count 使用前向渲染时最大像素光源数。也是性能关键。数量越大消耗越多。Texture Quality:贴图质量,可以选择Half Res,这样速度会更快,但是贴图质量会轻微下降。Anisotropic Textures 纹理各向异形Ant…...
Qt——通过一个简单的程序例程熟悉使用Qt Creator软件进行项目搭建的基本流程(新建项目、项目的文件组成、修改ui文件、编译运行与调试)
【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! 《项目案例分享》 《极客DIY开源分享》 《嵌入式通用开发实战》 《C++语言开发基础总结》 《从0到1学习嵌入式Linux开发》 《QT开发实战》 《Android开发实战》...
Linux 如何使用 git | 新建仓库 | git 三板斧
文章目录 专栏导读 一、如何安装 git 二、注册码云账号 三、新建仓库 配置仓库信息 四、克隆远端仓库到本地 五、git 三板斧 1. 三板斧第一招:git add 2. 三板斧第二招:git commit 解决首次 git commit 失败的问题 配置机器信息 3. 三…...
网站设计与建设ppt/官网seo是什么
前段时间在折腾如何通过 SD-WAN 组网方式打通办公室和家里的异地局域网。需要用到路由器的静态路由表功能,但是遍历整个家用路由器市场几乎没有支持这个功能的路由器(只有华硕 RT-AX57 有这个功能,但是成本超出了我的预算)。所有就…...
网站搭建是哪个岗位做的事儿/福州百度关键词排名
关于先序遍历、中序遍历、后序遍历的定义可以参考这篇博客二叉树的遍历规则。 目前能够百度到的问题大多都是根据(先序&中序)或(中序&后序)序列构建唯一二叉树,其中贴出一些提供思路的博客:二叉树…...
门户网站综合型门户/9个广州seo推广神技
| 标题 | 名称 | 钩子描述 || --- | --- | --- || 会员添加 | member_add | 当添加会员时 || 会员编辑 | member_edit | 当编辑会员时 || 会员删除 | member_del | 当删除会员时 || 会员登录 | member_login | 当会员登录 |>添加会员,编辑,删除&#…...
做网站好多钱/百度一下官网首页登录
通过这个网站上传excel:http://www.docpe.com/excel/excel-to-html.aspx 然后转换,将压缩包打开,实际就是一个html. 找到table标签的开始和结束,直接将这一大段考到md文件里面即可… 有一点很坑爹,就是如果你一行都是英文,好比包名,markdown不会将其压缩,导致包名就很长一行,其…...
goz建站/软文网
下面我们讲解登录功能。首先为了方便我们开发,我们在根目录(www目录)下建立一个项目文件夹,叫joke。接着在joke下建立两个文件夹,一个叫admin后台文件夹,另一个叫home前台文件夹(当然,你也可以使用别的名称,…...
常德哪里有做网站/网站优化怎么做
规范化齐次坐标的作用:可将图形变换表示为图形点集规范化次坐标矩阵与某一变换矩阵相乘的形式。 平移变换比例变换旋转变换 对称变换 错位变换相对任一参考点的二维几何变换 相对任意方向的二维几何变换...