起飞页怎么做网站,建设银行租房平台网站,如何选择网站空间,镇江百度代理文章目录 C 工厂模式引言一、简单工厂模式概念实现步骤示例代码优缺点 二、工厂方法模式概念实现步骤示例代码优缺点 三、抽象工厂模式概念实现步骤示例代码优缺点 C 工厂模式
引言
在 C 编程中#xff0c;对象的创建是一个常见且基础的操作。然而#xff0c;当项目规模逐渐… 文章目录 C 工厂模式引言一、简单工厂模式概念实现步骤示例代码优缺点 二、工厂方法模式概念实现步骤示例代码优缺点 三、抽象工厂模式概念实现步骤示例代码优缺点 C 工厂模式
引言
在 C 编程中对象的创建是一个常见且基础的操作。然而当项目规模逐渐增大对象的创建逻辑变得复杂时直接在代码中使用 new 关键字创建对象会带来诸多问题比如代码的可维护性变差、难以扩展等。工厂模式应运而生它为对象的创建提供了一种更加灵活、可扩展的解决方案。本文将详细介绍 C 中的工厂模式包括简单工厂模式、工厂方法模式和抽象工厂模式并通过具体的例子帮助大家理解。
一、简单工厂模式
概念
简单工厂模式是工厂模式的基础版本它定义了一个工厂类该类可以根据传入的参数决定创建并返回哪种产品类的实例。简单来说就是把对象的创建逻辑封装在一个工厂类中。
实现步骤
定义产品基类创建一个抽象的产品基类所有具体产品类都要继承这个基类。创建具体产品类实现产品基类的接口创建具体的产品类。创建工厂类在工厂类中定义一个创建产品的方法根据传入的参数决定创建哪种具体产品。
示例代码
#includeiostream
#includememory// 定义水果抽象基类包含纯虚函数 name
class Fruit{public:// 纯虚函数用于输出水果名称派生类需实现virtual void name()0;
};// 苹果类继承自 Fruit 类
class Apple:public Fruit{public:// 重写基类的 name 函数输出苹果名称void name() override{std::coutApplestd::endl;}
};// 香蕉类继承自 Fruit 类
class Banana:public Fruit{public:// 重写基类的 name 函数输出香蕉名称void name() override{std::coutBananastd::endl;}
};// 工厂类用于创建不同类型的水果对象
class Factory{public:// 静态方法根据传入的水果名称创建对应的水果对象static std::unique_ptrFruit createFruit(std::string fruit_name){if(fruit_nameapple){// 创建苹果对象并返回其 unique_ptrreturn std::unique_ptrFruit(new Apple());}else if(fruit_namebanana){// 创建香蕉对象并返回其 unique_ptrreturn std::unique_ptrFruit(new Banana());}else{// 若名称不匹配返回空指针return nullptr;}}
};int main()
{// 使用工厂类创建苹果对象std::unique_ptrFruit fruit Factory::createFruit(apple);// 调用苹果对象的 name 函数输出名称fruit-name(); // 使用工厂类创建香蕉对象fruit Factory::createFruit(banana);// 调用香蕉对象的 name 函数输出名称fruit-name();// 再次使用工厂类创建苹果对象fruit Factory::createFruit(apple);return 0;
}优缺点
优点实现简单将对象的创建和使用分离提高了代码的可维护性。缺点工厂类职责过重违反了开闭原则对扩展开放对修改关闭。如果需要新增产品就需要修改工厂类的代码。
二、工厂方法模式
概念
工厂方法模式是在简单工厂模式的基础上进行了改进它将创建对象的具体逻辑延迟到子类中实现。定义一个创建对象的抽象方法让子类决定实例化哪个具体产品类。
实现步骤
定义产品基类同简单工厂模式。创建具体产品类同简单工厂模式。定义抽象工厂类定义一个抽象的工厂类其中包含一个抽象的创建产品的方法。创建具体工厂类继承抽象工厂类实现创建产品的方法决定创建哪种具体产品。
示例代码
#includeiostream
#includememory// 定义抽象基类 Fruit包含纯虚函数 name
// 任何继承自该类的具体水果类都必须实现 name 函数
class Fruit {
public:// 纯虚函数用于输出水果名称virtual void name() 0;
};// 定义 Apple 类继承自 Fruit 类
class Apple : public Fruit {
public:// 重写基类的纯虚函数 name输出苹果名称void name() override {std::cout Apple std::endl;}
};// 定义 Banana 类继承自 Fruit 类
class Banana : public Fruit {
public:// 重写基类的纯虚函数 name输出香蕉名称void name() override {std::cout Banana std::endl;}
};// 定义抽象工厂类 Factory包含纯虚函数 create
// 具体的工厂类需要实现该函数来创建水果对象
class Factory {
public:// 纯虚函数用于创建水果对象virtual std::shared_ptrFruit create() 0;
};// 定义 AppleFactory 类继承自 Factory 类
class AppleFactory : public Factory {
public:// 重写基类的纯虚函数 create创建苹果对象std::shared_ptrFruit create() override {return std::make_sharedApple();}
};// 定义 BananaFactory 类继承自 Factory 类
class BananaFactory : public Factory {
public:// 重写基类的纯虚函数 create创建香蕉对象std::shared_ptrFruit create() override {return std::make_sharedBanana();}
};int main() {// 创建一个指向 AppleFactory 的智能指针std::shared_ptrFactory fruit_factory(new AppleFactory());// 调用工厂的 create 方法创建苹果对象std::shared_ptrFruit fruit fruit_factory-create();// 调用水果对象的 name 方法输出名称fruit-name();// 重置工厂指针指向 BananaFactoryfruit_factory.reset(new BananaFactory());// 调用新工厂的 create 方法创建香蕉对象fruit fruit_factory-create();// 调用水果对象的 name 方法输出名称fruit-name();return 0;
}优缺点
优点符合开闭原则当需要新增产品时只需要新增具体产品类和对应的具体工厂类不需要修改现有代码。缺点类的数量会增多增加了系统的复杂度。
三、抽象工厂模式
概念 抽象工厂模式工厂方法模式通过引入工厂等级结构解决了简单工厂模式中工厂类职责太重的问题。但由于工厂方法模式中的每个工厂只生产一类产品可能会导致系统中存在大量的工厂类势必会增加系统的开销。此时我们可以考虑将一些相关的产品组成一个产品族位于不同产品等级结构中功能相关联的产品组成的家族由同一个工厂来统一生产这就是抽象工厂模式的基本思想。 实现步骤
定义产品族的抽象基类为每个产品族定义一个抽象基类。创建具体产品类实现每个产品族的具体产品类。定义抽象工厂类定义一个抽象的工厂类其中包含多个创建不同产品的抽象方法。创建具体工厂类继承抽象工厂类实现创建不同产品的方法决定创建哪些具体产品。
示例代码
#includeiostream
#includememory// 水果抽象基类定义了输出水果名称的纯虚函数
class Fruit {
public:virtual void name() 0;
};// 苹果类继承自 Fruit 类实现了输出苹果名称的方法
class Apple : public Fruit {
public:void name() override {std::cout Apple std::endl;}
};// 香蕉类继承自 Fruit 类实现了输出香蕉名称的方法
class Banana : public Fruit {
public:void name() override {std::cout Banana std::endl;}
};// 动物抽象基类定义了输出动物名称的纯虚函数
class Animal {
public:virtual void name() 0;
};// 羊类继承自 Animal 类实现输出名称方法
class Lamb : public Animal {
public:void name() override {std::cout Lamb std::endl;}
};// 狗类继承自 Animal 类实现了输出狗名称的方法
class Dog : public Animal {
public:void name() override {std::cout Dog std::endl;}
};// 抽象工厂类定义了获取水果和动物对象的纯虚函数
class Factory {
public:virtual std::shared_ptrFruit getFruit(const std::string name) 0;virtual std::shared_ptrAnimal getAnimal(const std::string name) 0;
};// 水果工厂类继承自 Factory 类实现了获取水果对象的方法获取动物对象返回空指针
class FruitFactory : public Factory {
public:virtual std::shared_ptrFruit getFruit(const std::string name);virtual std::shared_ptrAnimal getAnimal(const std::string name);
};// 动物工厂类继承自 Factory 类实现了获取动物对象的方法获取水果对象返回空指针
class AnimalFactory : public Factory {
public:virtual std::shared_ptrFruit getFruit(const std::string name);virtual std::shared_ptrAnimal getAnimal(const std::string name);
};// 工厂管理类提供静态方法根据名称创建对应的工厂对象
class FactoryManager {
public:static std::shared_ptrFactory creaete(const std::string name);
};int main() {// 通过工厂管理类创建水果工厂对象std::shared_ptrFactory fruit_factory FactoryManager::creaete(fruit);// 从水果工厂获取苹果对象并输出名称std::shared_ptrFruit fruit fruit_factory-getFruit(apple);fruit-name();// 从水果工厂获取香蕉对象并输出名称fruit fruit_factory-getFruit(banana);fruit-name();return 0;
}优缺点
优点将一系列相关的产品对象的创建封装在一起保证了产品之间的一致性同时也符合开闭原则。缺点实现复杂当产品族需要增加新的产品时需要修改抽象工厂类和所有具体工厂类的代码。