文章目录

  • 工厂模式介绍
  • 简单工厂模式
    • 简单工厂模式具体的应用情景
    • 简单工厂模式的定义
  • 工厂方法模式
    • 工厂方法模式具体的应用情景
    • 工厂方法模式的定义
  • 抽象工厂模式
    • 工厂方法模式具体的应用情景1---战斗场景分类
    • 工厂方法模式具体的应用情景2---不同厂商生产不同产品
    • 抽象工厂模式的定义
    • 抽象工厂模式的优缺点
    • 工厂方法模式和抽象工厂模式的区别
  • 工厂模式总结

工厂模式介绍

使用new创建堆对象,可以实现多态。

而工厂模式,则是把创建对象的代码包装起来,做到创建对象的代码与具体的业务逻辑代码相隔离的目的。

工厂模式细分为三种:简单工厂模式、工厂方法模式、抽象工厂模式。


简单工厂模式

简单工厂模式具体的应用情景

还是假设你是一名游戏程序员,游戏策划告诉你现在有三种怪物:亡灵类怪物、元素类怪物、机械类怪物,它们和主角一样,都有生命值、魔法值、攻击力三个属性。你该如何设计?
你可以选择一个抽象类Monster为父类,然后三种怪物 M_Undead(亡灵类怪物)、M_Element(元素类怪物)、M_Mechanic(机械类怪物) 继承自父类。

#include <iostream>
using namespace std;namespace hjl_project
{//怪物父类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;}virtual ~M_Undead() {}};//元素类怪物class M_Element : public Monster{public:M_Element(int life, int magic, int attack): Monster(life, magic, attack){cout << "创建了一个元素类怪物" << endl;}virtual ~M_Element() {}};//机械类怪物class M_Mechanic : public Monster{public:M_Mechanic(int life, int magic, int attack): Monster(life, magic, attack){cout << "创建了一个机械类怪物" << endl;}virtual ~M_Mechanic() {}};
}

接下来,如果你想实例化出怪物,可以选择直接new创建:

但是上面这样创建怪物的写法,我们需要依赖具体怪物的类名(不知道类名就创建不出怪物)。后续怪物种类增加,继续采用这种方式实在是太低效且难以维护了。

从上面不难看出来,使用new+具体类名来创建对象是一种依赖具体类型的紧耦合关系。

所以我们可以选择增加一个“怪物工厂类”,来帮助我们来创建怪物。通过这样的方式,即使以后怪物种类增加了,main函数中的代码也可以尽量保持稳定。
因为main函数与各个具体怪物类对象要实现的逻辑代码隔离了,这就是简单工厂模式的实现思路。

  //怪物工厂类,用来生产怪物对象class MonsterFactory{public:// monster_type为怪物的种类,//当然如果想要指定生命值、魔法值、攻击力,也可以修改参数Monster *createMonster(string monster_type){Monster *p_monster_obj = nullptr;//创建亡灵类怪物if (monster_type == "udd"){p_monster_obj = new M_Undead(300, 50, 80);}//创建元素类怪物else if (monster_type == "ele"){p_monster_obj = new M_Element(500, 50, 80);}//创建机械类怪物else if (monster_type == "mec"){p_monster_obj = new M_Mechanic(300, 100, 80);}return p_monster_obj;}};

到此为止,我们与怪物类的依赖就变成了与“怪物工厂类”的依赖,依赖关系缩小了,提高了代码的可维护性和可扩展性。 比如,如果以后我们想给怪物属性增加一个参数“防御力”,如果采用原来new的方式,我们需要把每个new的地方都修改了,而采用工厂模式,只需要修改“怪物工厂类”里面的一个函数即可。

但是这样设计也有一个缺点,那就是如果后续我们想增加一个新的怪物类,比如“异能类怪物”,我们就需要修改“怪物工厂类”中的代码,增加新的else if分支。这违背了六大设计原则之中的 “开闭原则”。当然,如果if else分支不多(没有十几个),违背一下“开闭原则”也没问题。

简单工厂模式的定义

定义一个工厂类,该类可以根据不同的参数创建并返回不同的类对象,被创建的对象所属的类一般都具有相同的父类。

调用者无需关心对象的具体实现细节。

实现了创建对象的代码(工厂类的createMonster),与具体的类(各种怪物类)解耦合的效果。


工厂方法模式

工厂方法模式是使用频率最高的工厂模式。该模式又被简称为 工厂模式或者多态工厂模式

上面提到简单工厂模式违背了“开闭原则”,而工厂方法模式通过增加 “新的工厂类” 来创建新的怪物类型,而不会修改原来的函数。

工厂方法模式具体的应用情景

还是以上面的怪物类型为例子。
我们需要在不修改原来createMonster函数的情况下,增加新的怪物类,如果按照上面简单工厂模式的设计思路,只有一个工厂类,是不可能做到不修改createMonster函数从而增加新的怪物类创建的。

我们可以给每个怪物类都实现一个工厂类,这些工厂类有一个共同的父类(工厂抽象类),通过每个怪物类的工厂类对象,就可以创建出不同的怪物;
如果后续要增加新的怪物类型,只需要再实现一个对应的工厂类即可,并不会修改原来的工厂类。

#include <iostream>
using namespace std;
namespace hjl_project
{//怪物父类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;}virtual ~M_Undead() {}};//元素类怪物class M_Element : public Monster{public:M_Element(int life, int magic, int attack): Monster(life, magic, attack){cout << "创建了一个元素类怪物" << endl;}virtual ~M_Element() {}};//机械类怪物class M_Mechanic : public Monster{public:M_Mechanic(int life, int magic, int attack): Monster(life, magic, attack){cout << "创建了一个机械类怪物" << endl;}virtual ~M_Mechanic() {}};//工厂父类class M_ParFactory{public:virtual Monster *createMonster() = 0;virtual ~M_ParFactory() {}};//亡灵类怪物的生产工厂class M_UndeadFactory : public M_ParFactory{public:virtual Monster *createMonster(){Monster *p_monster_obj = nullptr;return new M_Undead(300, 50, 80);}virtual ~M_UndeadFactory() {}};//元素类怪物的生产工厂class M_ElementFactory : public M_ParFactory{public:virtual Monster *createMonster(){Monster *p_monster_obj = nullptr;return new M_Element(300, 50, 80);}virtual ~M_ElementFactory() {}};//机械类怪物的生产工厂class M_MechanicFactory : public M_ParFactory{public:virtual Monster *createMonster(){Monster *p_monster_obj = nullptr;return new M_Mechanic(300, 50, 80);}virtual ~M_MechanicFactory() {}};//如果后续增加新的怪物类,只需要再实现一个该怪物类的工厂类即可//全局的用于创建怪物对象的函数,形参的类型是工厂父类类型的指针,//返回类型是怪物父类类型的指针Monster *Gbl_CreateMonster(M_ParFactory *factory){//根据factory类型,创建不同的怪物return factory->createMonster();}
}int main()
{//先创建一个亡灵怪物的工厂类,然后再通过该工厂类创建亡灵类怪物的对象hjl_project::M_ParFactory *p_udd_fy = new hjl_project::M_UndeadFactory();hjl_project::Monster *pM1 = hjl_project::Gbl_CreateMonster(p_udd_fy);//hjl_project::Monster *pM1 = p_udd_fy->createMonster();hjl_project::M_ParFactory *p_ele_fy = new hjl_project::M_ElementFactory();hjl_project::Monster *pM2 = hjl_project::Gbl_CreateMonster(p_ele_fy);hjl_project::M_ParFactory *p_mec_fy = new hjl_project::M_MechanicFactory();hjl_project::Monster *pM3 = hjl_project::Gbl_CreateMonster(p_mec_fy);delete p_udd_fy, pM1, p_ele_fy, pM2, p_mec_fy, pM3;return 0;
}

增加新类,通过增加扩展而不是修改已有代码的方式来实现创建新类对象,符合“开闭原则”。

到这里,估计你会发现,我们每实现一个怪物类,就需要实现一个对应的怪物工厂类,有点麻烦,其实我们可以通过模板来优化这一步操作。

 //T代表不同怪物的类型template <class T>class M_ChildFactory : public M_ParFactory{public:virtual Monster *createMonster(){return new T(300, 50, 80);}};

工厂方法模式的定义

定义一个用于创建对象的接口(工厂父类),由子类(各种怪物的工厂类)决定要实例化的类(创建的怪物)是哪一个。
工厂方法模式使得某个类的实例化延迟到了子类。

工厂方法模式的好处:

  1. 采用封装的方式,易于修改,如果直接用new的话,后续增加参数(比如增加“防御力”属性)会很麻烦,而采用工厂类,只需要修改成员函数即可。
  2. 创建对象前如果需要一些额外的业务代码,就可以将这些代码增加到具体工厂类的createMonster函数中。
  3. 简单工厂模式把创建对象这件事放到了一个统一的地方来处理(都是通过一个类来完成),可扩展性比较差。工厂方法模式相当于建立了一个程序实现框架,从而让子类来决定对象如何创建对象。

工厂方法模式往往需要创建一个与产品等级结构(层次)相同的工厂等级结构,这也增加了各种类的层次结构和数目。


抽象工厂模式

工厂方法模式具体的应用情景1—战斗场景分类

你还是那名游戏程序员,随着你们游戏的发展,战斗场景也逐渐增多,比如战斗的场景有山脉、沼泽、城镇等。
游戏策划这时候想让你在不同的场景下创建不同的怪物,相同类型的怪物在不同场景下属性各不相同,比如亡灵类怪物在山脉中攻击力就比在城镇中高。
目前的怪物有三种:亡灵类、元素类、机械类。通过排列组合,你发现如果按照不同的场景划分不同的怪物,一共有九种类型。
如果按照工厂方法模式的设计思路,就需要创建九个工厂子类,有点麻烦。
有没有一种方法,能够让一个工厂子类能够创建多种具有相同规则的怪物对象呢?这就是抽象工厂模式的思想。

我们引入两个概念:产品等级结构和产品族。
抽象工厂模式按照产品族来生产产品(产地相同的用一个工厂来生产),即一个地点有一个工厂,该工厂负责生产本地区的所有产品。

于是,你可以创建一个抽象工厂类,这个抽象类里有三个生产接口,分别可以用来生产三种类型的怪物,后面不同的场景如沼泽、山脉等都可以通过继承这个抽象工厂类,来重写这三个生产接口。这样,就可以生产出九种不同类型的怪物了。

#include <iostream>
using namespace std;
namespace hjl_project
{//怪物父类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_Swamp : public Monster{public:M_Undead_Swamp(int life, int magic, int attack): Monster(life, magic, attack){cout << "生产出一个沼泽亡灵类怪物" << endl;}};//沼泽元素类怪物class M_Element_Swamp : public Monster{public:M_Element_Swamp(int life, int magic, int attack): Monster(life, magic, attack){cout << "生产出一个沼泽元素类怪物" << endl;}};//沼泽机械类怪物class M_Mechanic_Swamp : public Monster{public:M_Mechanic_Swamp(int life, int magic, int attack): Monster(life, magic, attack){cout << "生产出一个沼泽机械类怪物" << endl;}};//-----------------------------山脉地区的怪物----------------//山脉亡灵类怪物class M_Undead_Mountain : public Monster{public:M_Undead_Mountain(int life, int magic, int attack): Monster(life, magic, attack){cout << "生产出一个山脉亡灵类怪物" << endl;}};//山脉元素类怪物class M_Element_Mountain : public Monster{public:M_Element_Mountain(int life, int magic, int attack): Monster(life, magic, attack){cout << "生产出一个山脉元素类怪物" << endl;}};//山脉机械类怪物class M_Mechanic_Mountain : public Monster{public:M_Mechanic_Mountain(int life, int magic, int attack): Monster(life, magic, attack){cout << "生产出一个山脉机械类怪物" << endl;}};//-----------------------------城市地区的怪物----------------//城市亡灵类怪物class M_Undead_Town : public Monster{public:M_Undead_Town(int life, int magic, int attack): Monster(life, magic, attack){cout << "生产出一个城市亡灵类怪物" << endl;}};//城市元素类怪物class M_Element_Town : public Monster{public:M_Element_Town(int life, int magic, int attack): Monster(life, magic, attack){cout << "生产出一个城市元素类怪物" << endl;}};//城市机械类怪物class M_Mechanic_Town : public Monster{public:M_Mechanic_Town(int life, int magic, int attack): Monster(life, magic, attack){cout << "生产出一个城市机械类怪物" << endl;}};//-----------------工厂类-----------------class M_ParFactory{public://创建亡灵类怪物virtual Monster *createMonster_Undead() = 0;//创建元素类怪物virtual Monster *createMonster_Element() = 0;//创建机械类怪物virtual Monster *createMonster_Mechanic() = 0;virtual ~M_ParFactory() {}};//沼泽地区的工厂class M_Factory_Swamp : public M_ParFactory{public://创建亡灵类怪物virtual Monster *createMonster_Undead(){return new M_Undead_Swamp(300, 50, 120);}//创建元素类怪物virtual Monster *createMonster_Element(){return new M_Element_Swamp(400, 50, 120);}//创建机械类怪物virtual Monster *createMonster_Mechanic(){return new M_Mechanic_Swamp(300, 150, 120);}};//山脉地区的工厂class M_Factory_Mountain : public M_ParFactory{public://创建亡灵类怪物virtual Monster *createMonster_Undead(){return new M_Undead_Mountain(30, 50, 120);}//创建元素类怪物virtual Monster *createMonster_Element(){return new M_Element_Mountain(40, 50, 120);}//创建机械类怪物virtual Monster *createMonster_Mechanic(){return new M_Mechanic_Mountain(30, 150, 120);}};//城市地区的工厂class M_Factory_Town : public M_ParFactory{public://创建亡灵类怪物virtual Monster *createMonster_Undead(){return new M_Undead_Town(30, 500, 120);}//创建元素类怪物virtual Monster *createMonster_Element(){return new M_Element_Town(40, 500, 120);}//创建机械类怪物virtual Monster *createMonster_Mechanic(){return new M_Mechanic_Town(30, 1500, 120);}};
}int main()
{//创建一个山脉地区的工厂,然后创建一个山脉地区的亡灵类怪物hjl_project::M_ParFactory *p_mou_fy = new hjl_project::M_Factory_Mountain();hjl_project::Monster *pM1 = p_mou_fy->createMonster_Undead();//创建一个沼泽地区的工厂,然后创建一个沼泽地区的机械类怪物hjl_project::M_ParFactory *p_swa_fy = new hjl_project::M_Factory_Swamp();hjl_project::Monster *pM2 = p_swa_fy->createMonster_Mechanic();//创建一个沼泽地区的工厂,然后创建一个沼泽地区的元素类怪物hjl_project::M_ParFactory *p_tow_fy = new hjl_project::M_Factory_Town();hjl_project::Monster *pM3 = p_tow_fy->createMonster_Element();return 0;
}

工厂方法模式具体的应用情景2—不同厂商生产不同产品

现在有一款玩具娃娃,它的部件有 身体、衣服、鞋子组成;这些部件由三个国家的厂商制作:中国、日本、美国。
你需要制作两个娃娃,第一个娃娃的要求:身体、衣服、鞋子全部采用中国厂商制作。第二个娃娃的要求:身体由中国厂商制作,衣服由日本厂商制作,鞋子由美国厂商制作。

你可以这样设计:
由于身体、衣服、鞋子三种部件都可以被不同的厂商生产,所以可以设置身体、衣服、鞋子的抽象类,然后继承实现不同厂商生产的子类,比如中国生产的身体类。
实现一个工厂抽象类,其中三个抽象函数来生产三种部件,不同厂商通过继承和多态来实现生产属于自己的三种部件。
最后设置娃娃类,通过传入三种部件的抽象指针,来组装娃娃。

#include <iostream>
using namespace std;
namespace hjl_project2
{//身体抽象类class Body{public:virtual void getName() = 0;virtual ~Body() {}};//衣服抽象类class Clothes{public:virtual void getName() = 0;virtual ~Clothes() {}};//鞋子抽象类class Shoes{public:virtual void getName() = 0;virtual ~Shoes(){};};//------------------娃娃类-----------class Doll{public:Doll(Body *p_body, Clothes *p_clothes, Shoes *p_shoes): body(p_body), clothes(p_clothes), shoes(p_shoes){}//组装接口void Assemble(){cout << "组装一个娃娃" << endl;body->getName();clothes->getName();shoes->getName();}private:Body *body;Clothes *clothes;Shoes *shoes;};//-------------工厂类------------class AbstractFactory{public://工厂稳定地创建三个部件virtual Body *createBody() = 0;virtual Clothes *createClothes() = 0;virtual Shoes *createShoes() = 0;virtual ~AbstractFactory() {}};//中国厂商实现三个部件class China_Body : public Body{public:void getName(){cout << "中国厂商生产身体部件" << endl;}};class China_Clothes : public Clothes{public:void getName(){cout << "中国厂商生产衣服部件" << endl;}};class China_Shoes : public Shoes{public:void getName(){cout << "中国厂商生产鞋子部件" << endl;}};//中国工厂class ChinaFactory : public AbstractFactory{public:Body *createBody(){return new China_Body;}Clothes *createClothes(){return new China_Clothes;}Shoes *createShoes(){return new China_Shoes;}};//日本厂商实现三个部件class Japan_Body : public Body{public:void getName(){cout << "日本厂商生产身体部件" << endl;}};class Japan_Clothes : public Clothes{public:void getName(){cout << "日本厂商生产衣服部件" << endl;}};class Japan_Shoes : public Shoes{public:void getName(){cout << "日本厂商生产鞋子部件" << endl;}};//日本工厂class JapanFactory : public AbstractFactory{public:Body *createBody(){return new Japan_Body;}Clothes *createClothes(){return new Japan_Clothes;}Shoes *createShoes(){return new Japan_Shoes;}};//美国厂商实现三个部件class America_Body : public Body{public:void getName(){cout << "美国厂商生产身体部件" << endl;}};class America_Clothes : public Clothes{public:void getName(){cout << "美国厂商生产衣服部件" << endl;}};class America_Shoes : public Shoes{public:void getName(){cout << "美国厂商生产鞋子部件" << endl;}};//美国工厂class AmericaFactory : public AbstractFactory{public:Body *createBody(){return new America_Body;}Clothes *createClothes(){return new America_Clothes;}Shoes *createShoes(){return new America_Shoes;}};}
int main()
{//创建第一个娃娃// 1.创建一个中国工厂hjl_project2::AbstractFactory *p_china_factory = new hjl_project2::ChinaFactory();// 2.创建中国工厂生产的部件hjl_project2::Body *p_china_body = p_china_factory->createBody();hjl_project2::Clothes *p_china_clothes = p_china_factory->createClothes();hjl_project2::Shoes *p_china_shoes = p_china_factory->createShoes();// 3.使用部件创建娃娃,然后组装hjl_project2::Doll *p_obj1 = new hjl_project2::Doll(p_china_body, p_china_clothes, p_china_shoes);p_obj1->Assemble();cout << "----------------------------------" << endl;//创建第二个娃娃// 1.创建另外的日本和美国工厂hjl_project2::AbstractFactory *p_japan_factory = new hjl_project2::JapanFactory();hjl_project2::AbstractFactory *p_america_factory = new hjl_project2::AmericaFactory();// 2.创建生产部件hjl_project2::Body *p_china_body2 = p_china_factory->createBody();hjl_project2::Clothes *p_japan_clothes = p_japan_factory->createClothes();hjl_project2::Shoes *p_america_shoes = p_america_factory->createShoes();// 3.使用部件创建娃娃,然后组装hjl_project2::Doll *p_obj2 = new hjl_project2::Doll(p_china_body2, p_japan_clothes, p_america_shoes);p_obj2->Assemble();delete p_china_factory, p_china_body, p_china_clothes, p_china_shoes, p_obj1, p_japan_factory, p_america_factory, p_china_body2, p_japan_clothes, p_america_shoes, p_obj2;return 0;
}

抽象工厂模式的定义

提供一个接口(抽象工厂类),让该接口负责创建一系列相关或者互相依赖的对象(情景1中的三种怪物抽象类型,情景2中的三种部件抽象类型),而无需指定它们具体的类(三种具体的怪物,亡灵类等,三种部件的具体类型,中国厂商生产的身体类型等)。

抽象工厂模式的优缺点

  1. 增加新的场景,如森林场景,怪物种类不变,则只需要增加一个新的子工厂。符合“开闭原则”。即只增加一个新的产品族,就只需要一个新的工厂子类,这是抽象工厂模式的优点。
  2. 如果增加了新的怪物种类,比如“异能类怪物”,那就需要在工厂父类和子类中都增加响应的接口。不符合“开闭原则”,不太适合抽象工厂模式。即增加新产品等级结构,则需要修改抽象层的代码,这是抽象工厂模式的缺点,应避免在产品等级结构不稳定的情况下使用该模式。

工厂方法模式和抽象工厂模式的区别

工厂方法模式适合于用一个工厂生产一个产品。
抽象工厂模式适合于用一个工厂生产多个产品。


工厂模式总结

  1. 从代码的实现复杂度来看,简单工厂模式最简单,工厂方法模式次之,抽象工厂模式最复杂。如果将简单工厂模式的代码修改得符合“开闭原则”,就变成了工厂方法模式;如果修改工厂方法模式的代码,使得一个工厂支持多个产品的生产,那就成了抽象工厂模式。

  2. 从需要的工厂数量上来看,简单工厂数量最少只有一个,工厂方法模式需要的工厂数量最多,抽象工厂模式能够有效减少工厂方法模式中工厂的数量。

  3. 从实际应用上,如果产品数量很少又不经常修改产品类型,只需要使用简单工厂模式即可;如果产品数量很多或者为了满足“开闭原则”,则可以使用工厂方法模式;如果有很多厂商并且一个厂商生产很多产品,则要使用抽象工厂模式。

C++设计模式----工厂模式相关推荐

  1. Java设计模式-工厂模式(3)抽象工厂模式

    在Java设计模式-工厂模式(2)工厂方法模式 我们知道了工厂方法模式解决了简单工厂模式中的缺陷,做到了满足开闭原则,但是时代是进步的,进而又产生新的问题,工厂难道只能生产一种东西吗.我们所见到的工厂 ...

  2. Java设计模式-工厂模式(2)工厂方法模式

    在Java设计模式-工厂模式(1)简单工厂模式 中我们介绍了简单工厂模式,提到了简单工厂模式违背了开闭原则,而"工厂方法模式"是对简单工厂模式的进一步抽象化,其好处是可以使系统在不 ...

  3. Java设计模式-工厂模式(1)简单工厂模式

    Java设计模式-工厂模式(1)简单工厂模式 一.前言 1)例子 2)类图关系 3)代码实现 二.简单工厂模式 2.1.概述: 2.2.类图关系: 2.3.代码修改: 2.4.优缺点 2.5.扩展-简 ...

  4. 设计模式---工厂模式

    设计模式---工厂模式 工厂方法模式 概述:工厂方法模式中抽象工厂负责定义创建对象的接口,具体创建工作由继承抽象工厂的具体类实现. 优点:客户端不需要再负责对象的创建,从而明确了各个类的职责,如果有新 ...

  5. java设计模式工厂模式_Java中的工厂设计模式

    java设计模式工厂模式 Welcome to the Factory Design Pattern in Java tutorial. Factory Pattern is one of the C ...

  6. java设计模式工厂模式_Java中的复合设计模式

    java设计模式工厂模式 Composite pattern is one of the Structural design pattern. Composite design pattern is ...

  7. java设计模式工厂模式_Java中的桥梁设计模式

    java设计模式工厂模式 Today we will look into Bridge Design Pattern in java. When we have interface hierarchi ...

  8. java设计模式工厂模式_Java中的外观设计模式

    java设计模式工厂模式 Facade Design Pattern is one of the Structural design patterns (such as Adapter pattern ...

  9. 设计模式-工厂模式(学习)

    设计模式-工厂模式(学习) 在程序的世界里,就像射雕英雄传一样,我们的技能就像是武功一样,我们只有不断去学习练习才能有机会像郭靖一样成为"天下第一". 我认为技能和武功是很类似的, ...

  10. 设计模式-工厂模式的3中不同实现[JAVA]

    设计模式-工厂模式的3中不同实现[JAVA] 工厂模式简介 In Factory pattern, we create object without exposing the creation log ...

最新文章

  1. eclipse: Program g++ not found in PATH
  2. ftp部署一个可供centos6、centos7系统使用的yum网络仓库
  3. Mybatis 一对多 结果集映射 简单入门 易懂
  4. NYOJ 108 士兵杀敌(一)
  5. 从1.5k到18k, 一个程序员的5年成长之路
  6. 空间组网(卫星组网)概述
  7. vue学习-路由router
  8. ZK 在XML编辑器中设置.zul文件
  9. .Net .Net Core 下使用FastDFS 文件上传下载
  10. 计算机机房实训计划,计算机专业实习计划安排.docx
  11. 企业工商信息数据API接口
  12. UC手机浏览器js加入收藏夹
  13. 从基本组件到结构创新,67页论文解读深度卷积神经网络架构
  14. NPN PNP 接近开关
  15. HDD硬盘securityATAerase事故(HDD被LOCKED)
  16. 2020年中国球墨铸管行业发展背景、竞争格局及政策环境分析,城市管道建设带来行业增量,新兴铸管是行业龙头「图」
  17. 华为手机不小心点了始终_华为手机有一个设置,用过一次就再也离不开了,你打开了吗?...
  18. 图片压缩-speedpdf免费无损在线压缩图片
  19. 服务器硬件基础设施,【通讯技术】细节定成败,NFV中的硬件基础设施管理
  20. GFD233A 3BHE022294R0103

热门文章

  1. Highcharts 半圈圆环图
  2. 用python画一个双层圆环筒状闭环源码
  3. OMAPL138upp
  4. MediBang Paint Pro,专门为漫画爱好者打造的绘图工具
  5. vue element 表格内的复制粘贴功能
  6. 行人重识别——将多个数据集格式统一为market1501格式,打造超大规模的REID数据集
  7. MySQL(MariaDB) 菜鸟入门“秘籍”
  8. 生猪养殖生产计划问题
  9. 计算机信息系统安全管理的目标,信息安全方针目标与策略.doc
  10. 2021-04-05 web前端CSS之权重,盒子边框内外边距