C++设计模式_创建型模式_工厂方法模式
目录
C++设计模式_创建型模式_工厂方法模式
一、简单工厂模式
1.1 简单工厂模式引入
1.2 简单工厂模式
1.3 简单工厂模式利弊分析
1.4 简单工厂模式的UML图
二、工厂方法模式
2.1 工厂模式和简单工厂模式比较
2.2 工厂模式代码实现
2.3 工厂模式UML
三、抽象工厂模式
3.1 战斗场景分类范例1
3.1.1 抽象工程代码实现
3.1.2 抽象工厂模式优缺点
3.1.3 抽象工厂模式UML
3.2 抽象工厂范例2
3.2.1 代码实现
3.2.2 UML
四、三个工厂模式总结
一、简单工厂模式
1.1 简单工厂模式引入
需求:假如现在游戏策划提出了三个需求:增加三个怪物,亡灵类怪物,元素类怪物,机械类怪物,他们都有生命值,魔法值和攻击力三个属性。
Monster作为怪物主类,M_Undead作为亡灵类,M_Element元素类,M_Mechanic机械类;
代码如下:
namespace _namespace2
{class Monster{public:Monster(int life, int magic, int attack) :m_life(life), m_magic(magic), m_attack(attack) {}virtual ~Monster() // 基类 析构 虚方法{}protected:int m_life;int m_magic;int m_attack;};class M_Undead : public Monster{public:M_Undead(int life, int magic, int attack) : Monster(life,magic, attack) {cout << "亡灵类动物" << endl;}};class M_Element : public Monster{public:M_Element(int life, int magic, int attack) : Monster(life, magic, attack) {cout << "元素类动物" << endl;}};class M_Mechanic : public Monster{public:M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack) {cout << "机械类动物" << endl;}};}
void test1()
{_namespace2::Monster *m1 = new _namespace2::M_Undead(300, 100, 100);_namespace2::Monster *m2 = new _namespace2::M_Element(300, 100, 100);_namespace2::Monster *m3 = new _namespace2::M_Mechanic(300, 100, 100);/*亡灵类动物元素类动物机械类动物*/
}
上边使用new + 具体的类名来创建对象,这是一种具体类型的紧耦合关系。
1.2 简单工厂模式
简单工厂模式的实现思路:使用工厂类代替new来实现创建怪物的代码,用户在创建时候,与具体的类对象代码隔离,做到了松耦合。
namespace _namespace1
{class Monster{public:Monster(int life, int magic, int attack) :m_life(life), m_magic(magic), m_attack(attack) {}virtual ~Monster() // 基类 析构 虚方法{}protected:int m_life;int m_magic;int m_attack;};class M_Undead : public Monster{public:M_Undead(int life, int magic, int attack) : Monster(life,magic, attack) {cout << "亡灵类动物" << endl;}};class M_Element : public Monster{public:M_Element(int life, int magic, int attack) : Monster(life, magic, attack) {cout << "元素类动物" << endl;}};class M_Mechanic : public Monster{public:M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack) {cout << "机械类动物" << endl;}};// 简单工厂模式class MonsterFactor{public:Monster * createMonster(string strmontype){Monster *ptrobj = nullptr;if (strmontype == "a"){ptrobj = new M_Undead(300, 100, 100);}else if (strmontype == "b"){ptrobj = new M_Element(300, 100, 100);}else if (strmontype == "c"){ptrobj = new M_Mechanic(300, 100, 100);}return ptrobj;}};}
void test2()
{//2 简单工厂模式的实现思路:使用工厂类可以实现创建怪物的代码,用户在创建时候,与具体的类对象要实现的逻辑代码隔离。_namespace1::MonsterFactor fac;_namespace1::Monster *m1 = fac.createMonster("a");_namespace1::Monster *m2 = fac.createMonster("b");_namespace1::Monster *m3 = fac.createMonster("c");
实例化一个工厂对象,然后通过向工厂中传递对应的标识来创建对象。/*亡灵类动物元素类动物机械类动物*/
}
1.3 简单工厂模式利弊分析
如果想新增加一个怪物,需要修改两个位置,首先,新增加一个新的怪物类,然后在工厂类的createMonster() 方法中再增加一个if else。这种做法不符合开闭原则。
开闭原则:代码的扩展性问题:对扩展开发,对修改关闭。当增加新功能,不应该通过修改已经存在的代码,比如在createMonster()中增加if else(), 而是应该通过扩展代码比如增加新类,增加新成员函数来进行扩展。假如上边要增加100个怪物类型,就要增加100个 if else(),这样的做法不可取,如果只增加几个,这样方法也可以,所以应该在代码的可读性和可扩展性之间做出权衡。
上面引入简单工厂模式的意图:定义一个工厂类,改类的成员函数可以根据不同的参数创建并返回不同的类对象,被创建的对象所属的类一般都具有相同的父类,比如上边的三个怪物类都继承自Monster类,调用者无需关系创建对象的细节。
简单工厂模式:实现了创建怪物代码语具体怪物类解耦合的效果,即创建一个类时,用户不必知道类名字,只需调用工厂类接口,将要创建的类的类型传入,即可创建类。
1.4 简单工厂模式的UML图
工厂和类之间是has a 关系。

二、工厂方法模式
工厂方法模式简称工厂模式或多态工厂模式;与简单工厂模式比,灵活性更强,实现也更加复杂,一如更多的新类。每一个工厂类对应了怪物类,比如亡灵类对应的工厂为亡灵工厂类。工厂模式:修改代码不如增加代码好,符合开闭原则。
2.1 工厂模式和简单工厂模式比较
简单工厂模式把创建对象这件事放在一个统一的工厂中处理,每增加一个类,就要在工厂中增加对应的if else语句;而工厂模式相当于创建一个框架,从而让子类来决定给对象如何创建。工厂方法模式往往需要创建一个与产品等级结构(层次)相同的工厂等级结构,这也新增加了新类的层次结构和数目。
2.2 工厂模式代码实现
namespace _sp1
{// 怪物类父类class CMonster{public:CMonster(int life,int maigc,int attack):m_life(life),m_magic(maigc), m_attack(attack){}protected:int m_life;int m_magic;int m_attack;};// 亡灵类class CUnded : public CMonster{public:CUnded(int life, int maigc, int attack) :CMonster(life, maigc, attack){cout << "亡灵类来到世界" << endl;}private:};// 元素类class CEle : public CMonster{public:CEle(int life, int maigc, int attack) :CMonster(life, maigc, attack){cout << "元素类来到世界" << endl;}private:};// 机械类class CMecanical : public CMonster{public:CMecanical(int life, int maigc, int attack) :CMonster(life, maigc, attack){cout << "机械类来到世界" << endl;}};// 简单工厂模式:创建一个工厂类,在工厂类中返回对应的 怪物类;// 工厂方法// 1 创建一个工厂基类;class CFactorMonster{public:virtual CMonster * createMonster() = 0;virtual ~CFactorMonster(){}};// 2 创建每个怪物的工厂class CFactorUnded : public CFactorMonster{public:virtual CMonster * createMonster(){CMonster *ptmp = new CUnded(200,300,400);return ptmp;}};class CFactorCEle : public CFactorMonster{public:virtual CMonster * createMonster(){CMonster *ptmp = new CEle(200, 300, 400); // 多态return ptmp;}};// 创建一个全局方法CMonster *GlobalCreateMonster(CFactorMonster *factory){return factory->createMonster(); // 多态}
}
void test2()
{// 先 创建一个工厂父类;由于每个工厂具有固定的步骤,所以有工厂父类;_sp1::CFactorMonster *p = new _sp1::CFactorUnded();_sp1::CMonster *pp = p->createMonster();_sp1::CFactorMonster *p2 = new _sp1::CFactorCEle();_sp1::CMonster *pp2 = p2->createMonster();// 工厂模式创建了一个工厂父类,在此基础上,又增加了每个怪物对应的工厂;// 与简单工厂模式比,比之前的复杂,但是灵活性更强,实现了 开闭原则,付出的代价是新增加了每个怪物的工厂类;//
}
2.3 工厂模式UML

三、抽象工厂模式
使用两个示例来说明和演示什么是抽象工厂模式,场景1是战斗场景模式,场景2是产品类
3.1 战斗场景分类范例1
上边的三种怪物类别分别是:亡灵类,元素类和机械类。现在再将这三类怪物分为不同场景:沼泽地区,山脉地区,城镇地区。这样之前的三类怪物就成了9类怪物,类别如下图所示:

上图中有两个概念:产品等级结构 和 产品族。
抽象工厂模式按照产品族来生产商品。
一个工厂子类能够创建不止一种而是多种具有相同规则的怪物对象,也就是创建一个产品族的对象,那么就可以有效减少所创建的工厂子类数量,这就是抽象工厂模式的核心思想。
3.1.1 抽象工程代码实现
实现上面9种怪物:
namespace _nsp1
{// 怪物类父类class CMonster{public:CMonster(int life, int maigc, int attack) :m_life(life), m_magic(maigc), m_attack(attack){}protected:int m_life;int m_magic;int m_attack;};/// 下面分别实现这9个类别,每个怪物类都继承自怪物父类// 城镇亡灵类class CMonsterTownUndead : public CMonster{public:CMonsterTownUndead(int life, int magic, int attack) : CMonster(life, magic, attack){cout << "一个城镇亡灵类型怪物来到了这个世界" << endl;}};// 城镇元素类class CMonsterTownElement : public CMonster{public:CMonsterTownElement(int life, int magic, int attack) : CMonster(life, magic, attack){cout << "一个城镇元素类型怪物来到了这个世界" << endl;}};// 城镇机械类class CMonsterTownMechanic : public CMonster{public:CMonsterTownMechanic(int life, int magic, int attack) : CMonster(life, magic, attack){cout << "一个城镇机械类型怪物来到了这个世界" << endl;}};/// 山脉类// 山脉亡灵类class CMonsterMaintainUndead : public CMonster{public:CMonsterMaintainUndead(int life, int magic, int attack) : CMonster(life, magic, attack){cout << "一个山脉亡灵类型怪物来到了这个世界" << endl;}};// 山脉元素类class CMonsterMaintainElement : public CMonster{public:CMonsterMaintainElement(int life, int magic, int attack) : CMonster(life, magic, attack){cout << "一个山脉元素类型怪物来到了这个世界" << endl;}};// 山脉机械类class CMonsterMaintainMechanic : public CMonster{public:CMonsterMaintainMechanic(int life, int magic, int attack) : CMonster(life, magic, attack){cout << "一个山脉机械类型怪物来到了这个世界" << endl;}};/// 沼泽类// 沼泽亡灵类class CMonsterMarshUndead : public CMonster{public:CMonsterMarshUndead(int life, int magic, int attack) : CMonster(life, magic, attack){cout << "一个沼泽亡灵类型怪物来到了这个世界" << endl;}};// 沼泽元素类class CMonsterMarshElement : public CMonster{public:CMonsterMarshElement(int life, int magic, int attack) : CMonster(life, magic, attack){cout << "一个沼泽元素类型怪物来到了这个世界" << endl;}};// 沼泽机械类class CMonsterMarshMechanic : public CMonster{public:CMonsterMarshMechanic(int life, int magic, int attack) : CMonster(life, magic, attack){cout << "一个沼泽机械类型怪物来到了这个世界" << endl;}};/// 创建工厂class CMonsterFactory{public:virtual CMonster *createMonsterUndead() = 0;virtual CMonster *createMonsterElement() = 0;virtual CMonster *createMonsterMechanic() = 0;virtual ~CMonsterFactory(){}};// 城镇类工厂:一个工厂能生产一个产品族class CMonsterFactoryTown : public CMonsterFactory{virtual CMonster *createMonsterUndead(){return new CMonsterTownUndead(100, 100, 100);}virtual CMonster *createMonsterElement(){return new CMonsterTownElement(100, 100, 100);}virtual CMonster *createMonsterMechanic(){return new CMonsterTownMechanic(100, 100, 100);}};// 山脉类怪物工厂class CMonsterFactoryMaintain : public CMonsterFactory{virtual CMonster *createMonsterUndead(){return new CMonsterMaintainUndead(100, 100, 100);}virtual CMonster *createMonsterElement(){return new CMonsterMaintainElement(100, 100, 100);}virtual CMonster *createMonsterMechanic(){return new CMonsterMaintainMechanic(100, 100, 100);}};// 沼泽类怪物工厂class CMonsterFactoryMarsh : public CMonsterFactory{virtual CMonster *createMonsterUndead(){return new CMonsterMarshUndead(100, 100, 100);}virtual CMonster *createMonsterElement(){return new CMonsterMarshElement(100, 100, 100);}virtual CMonster *createMarshMechanic(){return new CMonsterMaintainMechanic(100, 100, 100);}};}int main()
{_nsp1::CMonsterFactory *pc = new _nsp1::CMonsterFactoryTown();_nsp1::CMonster *pM1 = pc->createMonsterUndead();_nsp1::CMonster *pM2 = pc->createMonsterMechanic();_nsp1::CMonster *pM3 = pc->createMonsterElement();/*一个城镇亡灵类型怪物来到了这个世界一个城镇机械类型怪物来到了这个世界一个城镇元素类型怪物来到了这个世界 */system("pause");return 0;
}
3.1.2 抽象工厂模式优缺点
1 如果增加一个新场景,比如增加一个森林场景,需要增加三个怪物,CMonsterForestUndead CMonsterForestElement CMonsterForestMechnical等类,然后再创建森林工厂来创建这三个怪物类,这样符合开闭原则。
2 如果增加新怪物,比如增加龙类,不仅要增加三个继承自CMonster的子类,还要修改Factory类,在该类中增加新的虚函数结构,比如createMonsterDragon(),同时各个子工厂中也要实现createMonsterDragon()类,这样的修改不符合开闭原则。
3 只增加一个产品族则符合开闭原则,只需要增加新工厂子类,这是该模式的优点。如果在某个场景中,比如在游戏中,怪物种类比较固定的情况下,更适合使用抽象工厂模式。
3.1.3 抽象工厂模式UML

3.2 抽象工厂范例2
以生产芭比娃娃为例,芭比娃娃由三部分组成,分别是:身体,衣服,鞋子;有三个工厂都能生产芭比娃娃的这三个部分,中国工厂,日本工厂和美国工厂,产品结构图如下:

现在需求,制作两个芭比娃娃,第一个身体,衣服,鞋子全部采用中国厂商制造的部件。第二个芭比娃娃:中国生产的身体部件,日本工厂生产的衣服部件,美国产的鞋子部件。

3.2.1 代码实现
类的设计思路:将身体,衣服,鞋子这三个部件实现为抽象类;实现一个抽象工厂,分别用来生产身体,衣服,鞋子这三个部件。实现这三个厂商的生产的部件。
namespace _namesp1
{// 1 三个组成部件// 身体部件 和 生产工厂class CBody{public:virtual void productName() = 0;virtual ~CBody() {}};class CBody_China : public CBody{public :virtual void productName(){cout << "中国牌身体" << endl;}};class CBody_America : public CBody{public:virtual void productName(){cout << "美国牌身体" << endl;}};class CBody_Japan : public CBody{public:virtual void productName(){cout << "日本牌身体" << endl;}};// 衣服部件 和 生产工厂class CCloth{public:virtual void productName() = 0;virtual ~CCloth() {}};class CCloth_China : public CCloth{public:virtual void productName(){cout << "中国牌衣服" << endl;}};class CCloth_America : public CCloth{public:virtual void productName(){cout << "美国牌衣服" << endl;}};class CCloth_Japan : public CCloth{public:virtual void productName(){cout << "日本牌衣服" << endl;}};// 鞋子部件 和 生产工厂class CShoes{public:virtual void productName() = 0;virtual ~CShoes() {}};class CShoes_China : public CShoes{public:virtual void productName(){cout << "中国牌鞋子" << endl;}};class CShoes_America : public CShoes{public:virtual void productName(){cout << "美国牌鞋子" << endl;}};class CShoes_Japan : public CShoes{public:virtual void productName(){cout << "日本牌鞋子" << endl;}};// 组装芭比娃娃类class CBarbieDoll{public:CBarbieDoll(CBody *body1, CCloth *cloth1, CShoes *shoes1):body(body1),cloth(cloth1),shoes(shoes1) {}// 组成芭比娃娃void composeBar(){cout << "组成一个芭比娃娃" << endl;body->productName();cloth->productName();shoes->productName();}private:CBody *body;CCloth *cloth;CShoes *shoes;};// 抽象工厂类class CAbstractFactory{public:virtual CBody* createBody() = 0;virtual CCloth* createCloth() = 0;virtual CShoes* createShoes() = 0;virtual ~CAbstractFactory(){}};// 中国工厂class ChinaFactory : public CAbstractFactory{public:virtual CBody * createBody(){return new CBody_China;}virtual CCloth * createCloth(){return new CCloth_China;}virtual CShoes * createShoes(){return new CShoes_China;}};// 日本工厂class JapanFactory : public CAbstractFactory{public:virtual CBody * createBody(){return new CBody_Japan;}virtual CCloth * createCloth(){return new CCloth_Japan;}virtual CShoes * createShoes(){return new CShoes_Japan;}};// 美国工厂class AmericaFactory : public CAbstractFactory{public:virtual CBody * createBody(){return new CBody_America;}virtual CCloth * createCloth(){return new CCloth_America;}virtual CShoes * createShoes(){return new CShoes_America;}};
}int main()
{_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口// 生产第一个娃娃_namesp1::CAbstractFactory *pChinaFactory = new _namesp1::ChinaFactory();_namesp1::CBody *pChinaBody = pChinaFactory->createBody();_namesp1::CCloth *pChinaCloth = pChinaFactory->createCloth();_namesp1::CShoes *pChinaShoes = pChinaFactory->createShoes();// 组装_namesp1::CBarbieDoll *pbar = new _namesp1::CBarbieDoll(pChinaBody, pChinaCloth, pChinaShoes);pbar->composeBar();// 生产第二个娃娃_namesp1::CAbstractFactory *pAmericaFactory = new _namesp1::AmericaFactory();_namesp1::CAbstractFactory *pJapanFactory = new _namesp1::JapanFactory();_namesp1::CBody *pChinaBody2 = pChinaFactory->createBody();_namesp1::CCloth *pChinaCloth2 = pJapanFactory->createCloth();_namesp1::CShoes *pChinaShoes2 = pAmericaFactory->createShoes();// 组装_namesp1::CBarbieDoll *pbar2 = new _namesp1::CBarbieDoll(pChinaBody2, pChinaCloth2, pChinaShoes2);pbar2->composeBar();/*组成一个芭比娃娃
中国牌身体
中国牌衣服
中国牌鞋子
组成一个芭比娃娃
中国牌身体
日本牌衣服
美国牌鞋子*/system("pause");return 0;
}
抽象工厂模式定义: 提供一个抽象工厂接口,此接口负责定义一个产品族;
3.2.2 UML

四、三个工厂模式总结
1 代码实现角度:修改工厂模式方法,使得一个工厂支持多个产品,就是抽象工厂模式;
2 从工厂数量来看:简单工厂模式需要的工厂类最少,工厂模式需要的工厂类较多,抽象工厂用来生产一个产品族的产品。
3 从实际项目角度:小项目用简单工厂模式,中大型项目:工厂模式;大型项目:抽象工厂模式。
相关文章:
C++设计模式_创建型模式_工厂方法模式
目录 C设计模式_创建型模式_工厂方法模式 一、简单工厂模式 1.1 简单工厂模式引入 1.2 简单工厂模式 1.3 简单工厂模式利弊分析 1.4 简单工厂模式的UML图 二、工厂方法模式 2.1 工厂模式和简单工厂模式比较 2.2 工厂模式代码实现 2.3 工厂模式UML 三、抽象工厂模式 3.1 战斗场景…...
matlab批量替换txt文本文件的特定行的内容
1.下图所示,我想要替换第14行。 2.运行代码后,第14行已经更改为需要的内容。 clc,clear; %%----------------------需要更改的地方------------------------------------ % 设置要操作的文本文件路径,替换为你自己的文件路径 path D:\paper_…...
Qt Creator配置MSVC编译环境、调试环境
在windows上开发,一般使用Qt Creator自带mingw编译器,编译和调试都很方便,安装Qt时勾选后,自动配置完毕。 但是有时候我们需要使用MSVC的编译器,这个时候我们没法直接使用,需要配置环境才能使用࿰…...
Linux系统运维命令:终止监听在 TCP端口80上的所有进程(使用lsof,grep,awk组合命令, 终止监听在 TCP某个端口上的所有进程)
目 录 一、需求 二、解决方法 1、解决思路 2、命令 三、实例演示和命令解释 1、实例演示 (1)查看目前有哪些在TCP端口80监听的进程 (2)、使用命令 (3)、查看效果 2、命令解…...
开源模型应用落地-业务优化篇(七)
一、背景 在本篇学习中,我们要介绍消息中间件,它可以帮助我们将核心和辅助流程分开,让它们互相独立。同时,还要关注在使用消息中间件时需要注意的地方。并且将这种思想应用到其他实际场景中。 二、术语 2.1、消息中间件 消息中间件是一种在分布式系统中用于处理消息传递的…...
序列化-反序列化--json-xml-protoBuf
序列化和反序列化 数据在网络中传输需要按照一定的规范组成。这些规定的规范有json,xml,protobuf。 序列化 也就是说数据需要通过网络传输时,需要把数据转化为需要的传输格式,所以需要把需要传输的数据生成json或者xml或者protobuf语言格式文件&#…...
ubuntu 配置nacos开机启动
在Ubuntu系统上配置Nacos服务开机启动,可以通过创建systemd服务单元文件来实现。以下是步骤: 创建Systemd服务文件: 打开终端,使用文本编辑器(如nano或vim)新建一个服务文件: sudo nano /etc/sy…...
单节点大数据平台运维脚本
单节点的大数据集群运维脚本 vi /opt/bash/bigdata-operate-script.sh#!/bin/bashsource ~/.bashrc source /etc/profilehostnamebigdata#程序运行必要组件 important_components("kafka" "clickhouse-server" "elasticsearch" "kibana&qu…...
HTML基础知识
目录 1.初识网页 2.html:超文本标记语言 2.1排版标签 标题标签 段落标签 换行标签 水平线标签 2.2文本格式化标签 2.3媒体标签 图片标签 路径 音频标签 视频标签 2.4链接标签 2.5列表标签 2.5.1无序列表 2.5.2有序列表 2.5.3自定义列表 2.6表格…...
牛客禁用题:求阶乘
思路:在新类中使用全局变量进行运算,在主类中定义新类数组,通过构造函数的调用次数返回阶乘 #include <type_traits> class add{public:static int count;static int tmp;add(){countcounttmp;tmp;} }; int add::count0; int add::t…...
spring.factories的常用配置项
概述 spring.factories 实现是依赖 spring-core 包里的 SpringFactoriesLoader 类,这个类实现了检索 META-INF/spring.factories 文件,并获取指定接口的配置的功能。 Spring Factories机制提供了一种解耦容器注入的方式,帮助外部包&am…...
数据库-第二/三章 关系数据库和标准语言SQL【期末复习|考研复习】
前言 总结整理不易,希望大家点赞收藏。 给大家整理了一下计数据库系统概论中的重点概念,以供大家期末复习和考研复习的时候使用。 参考资料是王珊老师和萨师煊老师的数据库系统概论(第五版)。 文章目录 前言第二、三章 关系数据库和标准语言SQL2.1 关系2…...
【办公类-21-05】20240227单个word按“段落数”拆分多个Word(成果汇编 只有段落文字 1拆5)
作品展示 背景需求 前文对一套带有段落文字和表格的word进行13份拆分 【办公类-21-04】20240227单个word按“段落数”拆分多个Word(三级育婴师操作参考题目1拆13份)-CSDN博客文章浏览阅读293次,点赞8次,收藏3次。【办公类-21-04…...
【前端素材】推荐优质后台管理系统网页my-Task平台模板(附源码)
一、需求分析 1、系统定义 后台管理系统是一种用于管理网站、应用程序或系统的工具,通常由管理员使用。后台管理系统是一种用于管理和控制网站、应用程序或系统的管理界面。它通常被设计用来让网站或应用程序的管理员或运营人员管理内容、用户、数据以及其他相关功…...
Linux高负载排查最佳实践
在Linux系统中,经常会因为负载过高导致各种性能问题。那么如何进行排查,其实是有迹可循,而且模式固定。 本次就来分享一下,CPU占用过高、磁盘IO占用过高的排查方法。 还是那句话,以最佳实践入手,真传一句话…...
【python开发】网络编程(上)
这里写目录标题 一、必备基础(一)网络架构1、交换机2、路由器3、三层交换机4、小型企业基础网络架构5、家庭网络架构6、互联网 (二)网络核心词汇1、子网掩码和IP2、DHCP3、内网和公网IP4、云服务器5、端口6、域名 一、必备基础 &…...
php源码 单色bmp图片取模工具 按任意方式取模 生成字节数组 自由编辑点阵
http://2.wjsou.com/BMP/index.html 想试试chatGPT4生成,还是要手工改 php 写一个网页界面上可以选择一张bmp图片,界面上就显示这张bmp图片, 点生成取模按钮,在图片下方会显示这张bmp图片的取模数据。 取模规则是按界面设置的&a…...
设计模式-命令模式(Command Pattern)
承接Qt/C软件开发项目,高质量交付,灵活沟通,长期维护支持。需求所寻,技术正适,共创完美,欢迎私信联系! 一、命令模式的说明 命令模式(Command Pattern)是一种行为设计模式…...
鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:位置设置)
设置组件的对齐方式、布局方向和显示位置。 说明: 从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 align align(value: Alignment) 设置容器元素绘制区域内的子元素的对齐方式。 卡片能力: 从API…...
ShardingJdbc实战-分库分表
文章目录 基本配置分库分表的分片策略一、inline 行表达时分片策略algorithm-expression行表达式完整案例和配置如下 二、根据实时间日期 - 按照标准规则分库分表标准分片 - Standard完整案例和配置如下 基本配置 逻辑表 逻辑表是指:水平拆分的数据库或者数据表的相…...
揭秘DXVK:Vulkan驱动的Direct3D翻译层革命
揭秘DXVK:Vulkan驱动的Direct3D翻译层革命 【免费下载链接】dxvk Vulkan-based implementation of D3D8, 9, 10 and 11 for Linux / Wine 项目地址: https://gitcode.com/gh_mirrors/dx/dxvk DXVK(Direct3D to Vulkan)是一款革命性的开…...
libcrypt-dev安装指南:解决crypt.h缺失报错
1. 当你的代码突然喊"找不到crypt.h"时 第一次在Linux环境下编译加密相关的代码时,看到终端里跳出"crypt.h: No such file or directory"的红色报错,我差点把咖啡喷在键盘上。这个场景太常见了——你从GitHub克隆了个看起来很酷的开…...
Springboot 实现多数据源(PostgreSQL 和 SQL Server)连接芬
一、环境准备 Free Spire.Doc for Python 是免费 Python 文档处理库,无需依赖 Microsoft Word,支持 Word 文档的创建、编辑、转换等操作,其中内置的 Markdown 解析能力,能高效实现 Markdown 到 Doc/Docx 格式的转换,且…...
10. 监控与可视化
10. 监控与可视化 本章介绍如何对 OR-Tools 求解过程进行监控,以及结果的可视化展示 目录 求解监控概述 内置统计信息 自定义监控 结果可视化 地图集成 监控大盘 日志与追踪 1. 求解监控概述 1.1 为什么要监控?...
OWL ADVENTURE处理复杂表格图像:从截图到结构化数据
OWL ADVENTURE处理复杂表格图像:从截图到结构化数据 每次看到同事为了把一张财务报表截图里的数据录入Excel而手动敲打半天,或者为了整理一份实验报告里的表格而焦头烂额时,我就在想,这事儿能不能让机器来干?传统的方…...
【多智能体控制】领导者-跟随者的无人机群编队控制仿真(碰撞检测、轨迹规划)【含Matlab源码 15321期】
💥💥💥💥💥💥💥💥💞💞💞💞💞💞💞💞💞Matlab领域博客之家💞&…...
微生物组数据分析难题如何解决?curatedMetagenomicData实战指南深度解析
微生物组数据分析难题如何解决?curatedMetagenomicData实战指南深度解析 【免费下载链接】curatedMetagenomicData Curated Metagenomic Data of the Human Microbiome 项目地址: https://gitcode.com/gh_mirrors/cu/curatedMetagenomicData 在人类微生物组研…...
5分钟掌握Windows和Office智能激活:KMS_VL_ALL_AIO完全指南
5分钟掌握Windows和Office智能激活:KMS_VL_ALL_AIO完全指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows系统激活而烦恼吗?每次重装系统后都要面对繁琐的…...
用TensorFlow和BERT实战:从海量安全报告中自动提取攻击技战术(TTPs)
基于TensorFlow与BERT的自动化TTPs提取系统实战指南 当安全团队每天需要处理数百份威胁报告时,人工提取攻击技战术(TTPs)的效率瓶颈就会暴露无遗。本文将展示如何构建一个能自动解析安全报告、识别关键攻击模式的智能系统,这套方案…...
Pixel Dream Workshop 企业级应用:基于 Agent 架构的自动化设计工作流
Pixel Dream Workshop 企业级应用:基于 Agent 架构的自动化设计工作流 1. 企业内容创作的痛点与机遇 在数字化营销时代,企业每天需要生产大量视觉内容——从社交媒体配图到产品详情页,从广告海报到活动宣传物料。传统设计流程面临三大核心挑…...
