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 從實際項目角度:小項目用簡單工廠模式,中大型項目:工廠模式;大型項目:抽象工廠模式。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711345.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711345.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711345.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MDS300-16-ASEMI整流模塊MDS300-16參數、封裝、尺寸

編輯&#xff1a;ll MDS300-16-ASEMI整流模塊MDS300-16參數、封裝、尺寸 型號&#xff1a;MDS300-16 品牌&#xff1a;ASEMI 封裝&#xff1a;M25 最大重復峰值反向電壓&#xff1a;1600V 最大正向平均整流電流(Vdss)&#xff1a;300A 功率(Pd)&#xff1a;大功率 芯片…

centos 安裝 glibc2.25

在 CentOS 7 系統上安裝 glibc 2.25 需要非常謹慎&#xff0c;因為 glibc 是系統核心庫之一&#xff0c;升級它可能導致與系統其他組件的兼容性問題。CentOS 7 自帶的 glibc 版本較低&#xff0c;直接替換為高版本可能會導致依賴于舊版 glibc 的系統軟件崩潰。 以下是一般情況…

Flink——芒果TV的實時數倉建設實踐

目錄 一、芒果TV實時數倉建設歷程 1.1 階段一&#xff1a;Storm/Flink JavaSpark SQL 1.2 階段二&#xff1a;Flink SQLSpark SQL 1.3 階段三&#xff1a;Flink SQLStarRocks 二、自研Flink實時計算調度平臺介紹 2.1 現有痛點 2.2 平臺架構設計 三、Flink SQL實時數倉分…

面試筆記系列三之spring基礎知識點整理及常見面試題

目錄 如何實現一個IOC容器? 說說你對Spring 的理解&#xff1f; 你覺得Spring的核心是什么&#xff1f; 說一下使用spring的優勢&#xff1f; Spring是如何簡化開發的&#xff1f; IOC 運行時序 prepareRefresh() 初始化上下文環境 obtainFreshBeanFactory() 創建并…

Linux系統加固:如何有效管理系統賬號

Linux系統加固&#xff1a;如何有效管理系統賬號 1.1 口令重復次數限制1.2 避免系統存在uid相同的賬號1.3 空密碼的帳戶1.4 口令復雜度1.5 口令生存期1.6 登錄失敗次數鎖定策略 &#x1f496;The Begin&#x1f496;點點關注&#xff0c;收藏不迷路&#x1f496; 在Linux系統中…

為什么軟考報名人數越來越多?

2020年軟考報名人數404666人&#xff0c;廣東省報考人數超過14萬人。 ●2021年軟考通信考試報名人數突破100萬人&#xff0c;估計軟考有90多萬。 ●2022年軟考通信考試共129萬人&#xff0c;估計軟考占了120多萬人。 ●2023年軟考具體報名人數沒有公布&#xff0c;但工業和信…

【AI+應用】aliyun的EMO圖生視頻模型引起的思考如何做AI數字人

昨天2 月 29 日消息&#xff0c;2 月 28 日&#xff0c;阿里巴巴集團智能計算研究院日前上線了一款新的 AI 圖片 - 音頻 - 視頻模型技術 EMO&#xff0c;官方稱其為 " 一種富有表現力的音頻驅動的肖像視頻生成框架 "。據悉&#xff0c;用戶只需要提供一張照片和一段任…

springboot235基于SpringBoot的房屋交易平臺的設計與實現

房屋交易平臺設計與實現 摘 要 信息數據從傳統到當代&#xff0c;是一直在變革當中&#xff0c;突如其來的互聯網讓傳統的信息管理看到了革命性的曙光&#xff0c;因為傳統信息管理從時效性&#xff0c;還是安全性&#xff0c;還是可操作性等各個方面來講&#xff0c;遇到了互…

死記硬背spring bean 的生命周期

1.bean的生命周期 我們平常經常使用類似于new Object()的方式去創建對象&#xff0c;在這個對象沒有任何引用的時候&#xff0c;會被gc給回收掉。而對于spring而言&#xff0c;它本身存在一個Ioc容器&#xff0c;就是用來管理對象的&#xff0c;而對象的生命周期也完全由這個容…

Spring之AOP入門

1.AOP介紹 AOP&#xff08;Aspect Oriented Programming&#xff09;面向切面編程&#xff0c;一種編程范式&#xff0c;指導開發者如何組織程序結構&#xff0c;作用是在不改動原始設計的基礎上為其進行功能增強 2.AOP的核心概念 概念定義SpringAOP&#xff08;注解開發&am…

性能測試-反編譯jar

方法一&#xff0c;使用jd-gui 1、官網下載&#xff1a;Java Decompiler 2、下載mac版本后&#xff0c;解壓&#xff0c;如下所示&#xff1a; 雙擊 JD_GUI&#xff0c;提示錯誤&#xff0c;如下所示&#xff1a; 已經安裝了java 17&#xff0c;是java 1.8以上版本&#xff0…

Unity中URP下實現水體(水面高光)

文章目錄 前言一、實現高光反射原理1、原理&#xff1a;2、公式&#xff1a; 二、實現1、定義 _SpecularColor 作為高光反射的顏色2、定義 _SpecularIntensity 作為反射系數&#xff0c;控制高光反射的強度3、定義 _Smoothness 作為高光指數&#xff0c;用于模型高光范圍4、模擬…

ADO.NET+kafka實現發布訂閱保存到數據庫

??????ADO.NETkafka實現發布訂閱保存到數據庫 在.NET應用程序中&#xff0c;ADO.NET通常用于數據庫操作&#xff0c;而Apache Kafka是一個分布式流處理平臺&#xff0c;它允許發布&#xff08;Producer&#xff09;和訂閱&#xff08;Consumer&#xff09;消息流。使用A…

深入理解c指針(四)

目錄 六、assert斷言 七、指針的使用和傳址調用 1、strlen的模擬實現 2、傳值調用和傳址調用 3、練習-字符串逆序 在深入理解c指針&#xff08;三&#xff09;提到&#xff0c;在實際使用指針前可以檢測其是否指到有效空間&#xff1a; #include<stdio.h> int mai…

度量與評估客戶體驗:以客戶為中心的方法和工具

在當今的市場環境中&#xff0c;客戶體驗已經成為企業成功的關鍵因素。一個優秀的客戶體驗不僅能夠提升客戶滿意度&#xff0c;增強客戶忠誠度&#xff0c;還能夠吸引新的潛在客戶。然而&#xff0c;要實現這一目標&#xff0c;企業首先需要了解如何度量和評估客戶體驗。本文將…

day08_分類品牌管理商品規格管理商品管理

文章目錄 1 分類品牌管理1.1 菜單添加1.2 表結構介紹1.3 頁面制作1.4 品牌列表加載1.4.1 后端接口BrandControllerBrandServiceBrandMapperBrandMapper.xml 1.4.2 前端對接brand.jscategoryBrand.vue 1.5 分類數據加載1.6 列表查詢1.6.1 需求說明1.6.2 后端接口需求分析Categor…

linux nasm匯編中調用printf不報錯,但調用scanf報錯。拋出了分段錯誤(核心轉儲)

當我寫了如下匯編時 ; nasm -f elf64 -g -F dwarf charsin.asm ; gcc charsin.o -no-pie -o charsin ; ld -o eatclib eatclib.o ; gdb eatclib[SECTION .data]SPrompt db Enter string data, followed by Enter: ,0IPrompt db Enter an integer value, followed by Enter: ,1…

Python進階教學一

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 一、函數1.高階函數2.返回函數3.匿名函數4.裝飾器 二、實例1.類和實例2.限制訪問3. 繼承和多態4.實例屬性和類屬性 一、函數 1.高階函數 1.1 map1.2 reduce1.3 fi…

Dsco Dropship EDI需求分析

供應商要想從Dsco處通過EDI獲取訂單&#xff0c;需要部署自己的EDI系統&#xff0c;與Dsco的EDI供應商CommerceHub 建立連接&#xff0c;分為兩個方向&#xff1a; 1.從CommerceHub 的 Dsco 平臺獲取 EDI 850 采購訂單 2.向Dsco發送庫存&#xff08;846&#xff09;、訂單狀態…

MySQL的內外連接

1.內連接 內連接實際上就是利用 WHERE 子句&#xff08;連接條件&#xff09;對兩張表形成的笛卡爾積&#xff08;內連接&#xff09;進行篩選&#xff0c;我們之前學習的查詢基本都是內連接&#xff0c;也是在實際生產中被使用得最多的連接查詢。 另外內連接還可以使用下面的…