网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
-
结构组成
模式结构包括如下:- Factory:工厂角色
工厂角色负责实现创建所有实例的内部逻辑 - Product:抽象产品角色
抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口 - ConcreteProduct:具体产品角色
具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
- Factory:工厂角色
-
简单工厂的缺点
扩展性非常差,当需要添加新的产品时,需要更改工厂类,违背了开放-封闭原则(软件实体(类、模块、函数等等)应该可以扩展,但是不可以修改。) -
简单工厂代码
Phone()为抽象类,用于子类的共同函数,开放接口为show(),用于显示品牌信息。
ApplePhone()、SamsungPhone()、NokiaPhone()为子类,具体类实现过程在此类中实现。
#include <iostream>
#include <string>
class Phone{
public:
virtual ~Phone() {}
virtual void show() = 0;
};
class ApplePhone : public Phone {
public:
void show() {
std::cout << "ApplePhone created" << std::endl;
}
};
class SamsungPhone : public Phone {
public:
void show() {
std::cout << "SamsungPhone created" << std::endl;
}
};
class NokiaPhone : public Phone {
public:
void show() {
std::cout << "NokiaPhone created" << std::endl;
}
};
enum PhoneType
{
APPLE,
SAMSUNG,
NOKIA
};
class PhoneFactory {
public:
Phone\* createPhone(PhoneType phone_type) {
switch (phone_type)
{
case APPLE:
return new ApplePhone();
case SAMSUNG:
return new SamsungPhone();
case NOKIA:
return new NokiaPhone();
default:
return nullptr;
}
}
};
int main()
{
PhoneFactory phoneFactory;
Phone\* pApplePhone = phoneFactory.createPhone(APPLE);
if (pApplePhone) {
pApplePhone->show();
delete pApplePhone;
pApplePhone = nullptr;
}
return 0;
}
运行结果:
ApplePhone created
工厂方法模式(Factory Method Pattern)
- 模式动机
现在对该系统进行修改,不再设计一个工厂类来统一负责所有产品的创建,而是将具体手机的创建过程交给专门的工厂子类去完成,我们先定义一个抽象的手机工厂类,再定义具体的工厂类来生成苹果手机、三星手机、诺基亚手机等,它们实现在抽象手机工厂类中定义的方法。这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引进新的产品,如果出现新的手机类型,只需要为这种新类型的按钮创建一个具体的工厂类就可以获得该新牌子手机的实例,这一特点无疑使得工厂方法模式具有超越简单工厂模式的优越性,更加符合“开闭原则”。(大白话:现在工厂专门为每一个品牌设立了子工厂,由子工厂负责具体产品的生产)
工厂方法模式和简单工厂模式的区别在于,工厂方法将创建具体实例的过程封装到了具体工厂类中,由具体的工厂类来实现某一个产品的创建。当有新的产品需要创建时,只需添加新的工厂类即可。
-
模式定义
工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。 -
UML结构图
-
模式结构:
- Product:抽象产品
- ConcreteProduct:具体产品
- Factory:抽象工厂
- ConcreteFactory:具体工厂
-
优点:
- 用户只需关注具体某一种产品的实现,对其他产品的实例化过程进行隐藏。
- 所有具体类都共用同一个抽象类
- 当有新的产品需求时,只需增加新的具体产品类和新的具体工厂类,不用对抽象类进行删改。满足了开放-封闭原则
-
缺点:
- 在增加新的产品时,需要同时增加具体产品类和具体工厂类,增加了系统的编译负担。
- 在创建实例时,需要将抽象类暴漏给用户,因为有太多抽象类,不容易让用户理解。
-
工厂方法模式代码
#include <iostream>
#include <string>
class Phone {
public:
virtual ~Phone() {}
virtual void show() = 0;
};
class ApplePhone : public Phone {
public:
void show() {
std::cout << "ApplePhone created" << std::endl;
}
};
class SamsungPhone : public Phone {
public:
void show() {
std::cout << "SamsungPhone created" << std::endl;
}
};
class NokiaPhone : public Phone {
public:
void show() {
std::cout << "NokiaPhone created" << std::endl;
}
};
class PhoneFactory {
public:
virtual ~PhoneFactory() {}
virtual Phone\* createPhone() = 0;
};
class AppleFactory : public PhoneFactory{
public:
Phone\* createPhone() {
return new ApplePhone();
}
};
class SamsungFactory : public PhoneFactory {
public:
Phone\* createPhone() {
return new SamsungPhone();
}
};
class NokiaFactory : public PhoneFactory {
public:
Phone\* createPhone() {
return new NokiaPhone();
}
};
int main()
{
PhoneFactory\* pPhoneFactory = new AppleFactory();
Phone\* pApplePhone = pPhoneFactory->createPhone();
pApplePhone->show();
delete pApplePhone;
delete pPhoneFactory;
return 0;
}
抽象工厂模式(Abstract Factory Pattern)
- 模式动机
在工厂方法中,子工厂只有一条手机生产线。但在抽象工厂模式中子工厂中不止要生产手机,还要生产平板,电脑等产品。 - UML结构图
- 模式组成
AbstractFactory:抽象工厂
ConcreteFactory:具体工厂
AbstractProduct:抽象产品
Product:具体产品 - 抽象工厂的优点:
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。 - 抽象工厂的缺点:
产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。 - 模式代码实例
#include <iostream>
#include <string>
class Phone {
public:
virtual ~Phone() {}
virtual void show() = 0;
};
class Pad {
public:
virtual ~Pad(){}
virtual void show() = 0;
};
class ApplePhone : public Phone {
public:
void show() {
std::cout << "ApplePhone created" << std::endl;
}
};
class SamsungPhone : public Phone {
public:
void show() {
std::cout << "SamsungPhone created" << std::endl;
}
};
class NokiaPhone : public Phone {
public:
void show() {
std::cout << "NokiaPhone created" << std::endl;
}
};
class ApplePad : public Pad {
public:
void show() {
std::cout << "ApplePad created" << std::endl;
}
};
class SamsungPad : public Pad {
void show() {
std::cout << "SamsungPad created" << std::endl;
}
};
class NokiaPad : public Pad {
void show() {
std::cout << "NokiaPad created" << std::endl;
}
};
class Factory {
public:
virtual ~Factory() {}
virtual Phone\* createPhone() = 0;
virtual Pad\* createPad() = 0;
};
class AppleFactory : public Factory {
public:
Phone\* createPhone() {
return new ApplePhone();
}
Pad\* createPad() {
return new ApplePad();
}
};
class SamsungFactory : public Factory {
public:
Phone\* createPhone() {
return new SamsungPhone();
}
Pad\* createPad() {
return new SamsungPad();
}
};
class NokiaFactory : public Factory {
public:
Phone\* createPhone() {
return new NokiaPhone();
}
Pad\* createPad() {
return new NokiaPad();
}
};
int main()
{
Factory\* pPhoneFactory = new AppleFactory();
Phone\* pApplePhone = pPhoneFactory->createPhone();
Pad\* pApplePad = pPhoneFactory->createPad();
pApplePhone->show();
pApplePad->show();
delete pApplePad;
delete pApplePhone;
delete pPhoneFactory;
return 0;
}
单例模式(Singleton Pattern)
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。
在单例模式中,一个类只有一个实例,并且该实例在整个应用程序中都可以被访问。这样可以确保系统中某些资源的全局唯一性,并且可以提供一个方便的访问点来访问该实例。
通常情况下,单例模式通过私有构造函数和静态方法来实现。私有构造函数用于防止在外部创建该类的实例,而静态方法则用于返回该类唯一的实例。
单例模式有多种实现方式,如懒汉式、饿汉式、双重检查锁定等,每种实现方式都有其特点和适用场景。
- 使用场景
- 资源共享:有些对象需要占用系统资源,如数据库连接池、线程池、日志对象等,这些对象需要全局唯一,以避免资源竞争和浪费。
- 配置信息:有些配置信息只需要被加载一次,如系统配置信息、数据库配置信息等,这些配置信息也需要全局唯一,以避免重复加载和浪费。
- 日志记录:有些应用需要记录系统运行日志,如应用程序启动日志、错误日志等,这些日志对象需要全局唯一,以确保日志记录的一致性和完整性。
- 状态缓存:有些应用需要缓存一些状态信息,如用户登录状态、购物车状态等,这些状态信息需要全局唯一,以确保状态的一致性和完整性。
- 懒汉式单例模式
在系统运行时,实例不会自动创建,而是等到使用到该类的时候才会创建一个实例对象。
优点:可以延迟实例的创建时间,从而节省系统资源。
缺点:线程是不安全的,当存在多个线程的时候,会创建多个实例。
![img](https://img-blog.csdnimg.cn/img_convert/085220fb43a6bef725ce95d0cd46d507.png)
![img](https://img-blog.csdnimg.cn/img_convert/c825bcf03a6afcbd59a141f74d3048e5.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
存在多个线程的时候,会创建多个实例。
[外链图片转存中…(img-eDFlh3Vm-1715878345361)]
[外链图片转存中…(img-s5E6KVHw-1715878345362)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!