简单工厂模式
简单工厂模式相关类的创建和使用步骤如下:
(1)创建一个新的类,可以将这个类称之为工厂类。对于简单工厂模式来说,需要的工厂类只有一个。
(2)在这个工厂类中添加一个公共的成员函数,通过这个函数来创建我们需要的对象,关于这个函数一般将其称之为工厂函数。
(3)关于使用,首先创建一个工厂类对象,然后通过这个对象调用工厂函数,这样就可以生产出一个指定类型的实例对象了。
#include<iostream>
#include<memory>
using namespace std;
class Animal
{
public:
virtual void sound(){};
};
class Dog : public Animal
{
public:
void sound()override
{
cout<<"汪汪"<<endl;
}
};
class Cat : public Animal
{
public:
void sound()override
{
cout<<"喵喵"<<endl;
}
};
enum class Type{DOG,CAT};
class Animalfactory
{
public:
Animalfactory(){};
~Animalfactory(){};
Animal * ptr = nullptr;
Animal* createAnimal(Type type)
{
switch (type)
{
case Type::DOG:
ptr = new Dog;
break;
case Type::CAT:
ptr = new Cat;
break;
}
return ptr;
}
};
int main()
{
Animalfactory * fac = new Animalfactory();
std::shared_ptr<Animal> p = std::shared_ptr<Animal>(fac->createAnimal(Type::DOG));
p->sound();
return 0;
}
抽象工厂模式
抽象工厂模式适用于比较复杂的多变的业务场景,总体上就是给一系列功能相同但是属性会发生变化的组件添加一个抽象类,这样就可以非常方便地进行后续的拓展,再搭配工厂类就可以创建出我们需要的对象了。
抽象工厂模式遵守开闭原则,而工厂模式不遵守。工厂模式创建的对象对应的类不需要提供抽象类【这产品类组件中没有可变因素】
抽象工厂模式创建的对象对应的类有抽象的基类【这个产品类组件中有可变因素】
以下代码以汽车制造为例,假设现在需要建造电动汽车和燃油汽车,且两种汽车需要不同的发动机类型。因此需要创建电动汽车工厂和燃油汽车工厂,两种汽车工厂类对于气场工厂基类。
#include <iostream>
#include <memory>
// 抽象产品:汽车零部件
class CarPart {
public:
virtual ~CarPart() {}
virtual void start() const = 0;
};
// 具体产品:电动汽车电机
class ElectricCarMotor : public CarPart {
public:
void start() const override {
std::cout << "Electric car motor started." << std::endl;
}
};
// 具体产品:燃油汽车发动机
class GasolineEngine : public CarPart {
public:
void start() const override {
std::cout << "Gasoline engine started." << std::endl;
}
};
// 抽象工厂:汽车工厂
class CarFactory {
public:
virtual ~CarFactory() {}
virtual std::unique_ptr<CarPart> createCarPart() const = 0;
};
// 具体工厂:电动汽车工厂
class ElectricCarFactory : public CarFactory {
public:
std::unique_ptr<CarPart> createCarPart() const override {
return std::make_unique<ElectricCarMotor>();
}
};
// 具体工厂:燃油汽车工厂
class GasolineCarFactory : public CarFactory {
public:
std::unique_ptr<CarPart> createCarPart() const override {
return std::make_unique<GasolineEngine>();
}
};
int main() {
// 使用电动汽车工厂创建一个电动汽车
std::unique_ptr<CarFactory> electricCarFactory = std::make_unique<ElectricCarFactory>();
std::unique_ptr<CarPart> carPart = electricCarFactory->createCarPart();
carPart->start(); // 输出:Electric car motor started.
// 使用燃油汽车工厂创建一个燃油汽车
std::unique_ptr<CarFactory> gasolineCarFactory = std::make_unique<GasolineCarFactory>();
carPart = gasolineCarFactory->createCarPart();
carPart->start(); // 输出:Gasoline engine started.
return 0;
}
适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,它将一个类的接口转换成客户端所期望的另一种接口。适配器让原本不兼容的类可以一起工作。
适配器模式包含以下几个角色:
目标接口(Target):客户端所期望的接口,即客户端需要使用的接口。
源接口(Adaptee):需要被适配的接口,即原本不符合客户端需要的接口。
适配器(Adapter):将源接口转换成目标接口的类。
适配器模式的常见应用场景包括:
在使用一个已有的类时,发现它的接口与需求不符合,可以使用适配器模式将其接口转换成客户端所期望的接口。
在开发过程中,可以使用适配器模式来兼容不同的接口和框架。
简单来说:将一个类的接口转换成用户希望的另一个接口,使不兼容的对象能够相互配合并一起工作,这种模式就叫适配器模式
#include<iostream>
#include<string>
#include<memory>
using namespace std;
//目标接口
class MedioPlayer
{
public:
virtual void play(string filename) = 0;
};
//源接口
class Vedio
{
public:
virtual void play(string filename) = 0;
};
class Mp4 : public Vedio
{
public:
void play(string filename)
{
std::cout<<"play mp4 file"<<std::endl;
}
};
class Vlc : public Vedio
{
public:
void play(string filename)
{
std::cout<<"play Vlc"<<std::endl;
}
};
//适配器
class MedioPlayerApapter : public MedioPlayer
{
public:
MedioPlayerApapter(Vedio *v):vedio(v){}
~MedioPlayerApapter(){}
void play(string filename) override
{
if (filename.find(".mp4") != std::string::npos) vedio->play(filename);
else if (filename.find(".vlc") != std::string::npos) vedio->play(filename);
else std::cout<<"Invalid vedio"<<std::endl;
}
void setVedio(Vedio *v)
{
vedio = v;
}
private:
Vedio *vedio;
};
int main()
{
std::shared_ptr<Vedio> mp4 = std::make_shared<Mp4>();
std::shared_ptr<Vedio> vlc = std::make_shared<Vlc>();
std::shared_ptr<MedioPlayerApapter> p = std::make_shared<MedioPlayerApapter>(mp4.get());
p->play("xx.mp4");
p->setVedio(vlc.get());
p->play("xx.vlc");
}
后续比较常见的设计模式用到再继续更新。