电影订票网站开发,如何制作网页代码,那些域名可以做后缀做网站,广告网站建设与制作公司1 简单工厂模式的概念
简单工厂模式#xff08;Simple Factory Pattern#xff09;是设计模式中的一种创建型模式。它的主要目的是将对象的实例化与使用解耦#xff0c;使得客户端无需关心对象的创建细节#xff0c;只需通过工厂类来获取所需的对象。
在简单工厂模式中Simple Factory Pattern是设计模式中的一种创建型模式。它的主要目的是将对象的实例化与使用解耦使得客户端无需关心对象的创建细节只需通过工厂类来获取所需的对象。
在简单工厂模式中通常会有一个工厂类它负责根据客户端的请求创建并返回相应的对象。客户端只需调用工厂类的方法并传入相应的参数即可获取所需的对象而无需关心对象的创建过程。
在简单工厂模式中通常包括以下几个角色
1工厂Creator角色 工厂角色是简单工厂模式的核心它负责实现创建所有实例的内部逻辑。
2抽象产品Product角色 抽象产品角色是简单工厂模式所创建的所有对象的父类它负责描述所有实例所共有的公共接口。
3具体产品Concrete Product角色 具体产品角色是简单工厂模式的创建目标所有创建的对象都是充当这个角色的某个具体类的实例。
简单工厂模式允许客户端只需要传入一个正确的参数就可以获取所需要的对象而无需知道其创建的细节。这有利于明确各个类的职责并优化整个软件体系结构。
2 简单工厂模式的实现步骤
在 C 实现简单工厂模式的实现步骤如下
1定义产品接口 首先你需要定义一个抽象的产品接口这个接口将声明所有产品对象都需要实现的方法。这确保了工厂方法能够返回统一类型的产品对象而客户端则可以通过这个接口来操作这些对象。
2实现具体产品类 接下来创建实现了产品接口的具体产品类。这些类将实现接口中定义的方法并且提供具体的功能。
3创建工厂类 然后你需要创建一个工厂类这个类将负责根据客户端的请求创建并返回相应的产品对象。工厂类通常包含一个静态方法这个方法接收一个参数如产品类型或标识符然后基于这个参数来实例化并返回相应的产品对象。
4客户端调用工厂方法 客户端代码不需要直接实例化产品对象而是调用工厂类的静态方法并传入所需的参数。工厂方法根据这些参数创建并返回相应的产品对象。
5客户端使用产品对象 客户端现在可以通过产品接口来使用返回的产品对象而无需关心对象是如何创建的。
6处理资源释放 由于工厂模式通常涉及到动态内存分配例如使用 new 关键字创建对象因此客户端在使用完产品对象后需要负责释放这些对象所占用的资源如使用 delete 关键字。这通常是客户端调用工厂方法后需要注意的一个方面。
如下为样例代码
#include iostream
#include memory
#include string // 产品抽象接口
class Product {
public:virtual void use() 0;virtual ~Product() {} // 虚析构函数确保正确释放派生类对象
};// 具体产品类A
class ProductA : public Product {
public:void use() override {std::cout Using ProductA std::endl;}
};// 具体产品类B
class ProductB : public Product {
public:void use() override {std::cout Using ProductB std::endl;}
};// 工厂类
class SimpleFactory {
public:// 使用智能指针返回产品对象 static std::unique_ptrProduct createProduct(const std::string type) {if (type A) {return std::make_uniqueProductA(); // 使用make_unique创建ProductA对象 }else if (type B) {return std::make_uniqueProductB(); // 使用make_unique创建ProductB对象 }else {return nullptr; // 或者抛出一个异常 }}
};// 客户端代码
int main()
{// 使用工厂方法创建产品对象并自动管理其生命周期 auto productA SimpleFactory::createProduct(A);if (productA) {productA-use();// 不需要手动deleteunique_ptr会在离开作用域时自动释放内存 }auto productB SimpleFactory::createProduct(B);if (productB) {productB-use();// 同样不需要手动delete }return 0;
}上面代码的输出为
Using ProductA
Using ProductB3 简单工厂模式的应用场景
C 简单工厂模式的应用场景主要包括以下几种情况
1创建对象不需要知道具体类的情况 当客户端需要创建某个产品对象但并不需要知道具体是哪个类的时候可以使用简单工厂模式。工厂类根据客户端的请求和提供的参数返回相应的产品对象客户端只需要通过产品接口来操作这些对象。
2减少客户端与具体产品类的耦合 在传统的设计中客户端通常需要直接实例化具体的产品类。这会导致客户端与产品类紧密耦合不利于代码的维护和扩展。通过使用简单工厂模式客户端只需与工厂类交互从而降低了与具体产品类的耦合度。
3需要创建的对象较少且不会经常变动 简单工厂模式适用于产品类型相对较少且不太可能经常变动的场景。如果产品类型非常多或者经常需要添加新的产品类型简单工厂模式可能会导致工厂类变得庞大而难以维护。在这种情况下可能需要考虑使用其他更高级的工厂模式如工厂方法模式或抽象工厂模式。
4隐藏产品类的具体实现细节 简单工厂模式可以隐藏产品类的具体实现细节使得客户端无需关心产品对象的创建过程。这有助于将对象的创建与使用分离提高代码的可读性和可维护性。
5统一创建接口 当多个产品类具有相似的创建逻辑时可以使用简单工厂模式来统一这些产品的创建接口。这样客户端可以通过统一的接口来创建不同类型的产品对象简化了代码结构。
3.1 简单工厂模式应用于创建对象不需要知道具体类的情况
以下是一个简单工厂模式应用于创建对象而不需要知道具体类的样例。在这个例子中有一个 Shape 接口和两个实现了这个接口的类Circle 和 Rectangle。客户端代码通过简单工厂类 ShapeFactory 来创建这些形状对象而无需知道它们的具体类。
#include iostream
#include string
#include memory // 用于std::unique_ptr // 形状接口
class Shape {
public:virtual void draw() 0;virtual ~Shape() {} // 虚析构函数确保正确释放派生类对象
};// 圆形类
class Circle : public Shape {
public:void draw() override {std::cout Drawing a circle. std::endl;}
};// 矩形类
class Rectangle : public Shape {
public:void draw() override {std::cout Drawing a rectangle. std::endl;}
};// 形状工厂类
class ShapeFactory {
public:// 根据类型创建形状对象 static std::unique_ptrShape createShape(const std::string shapeType) {if (shapeType Circle) {return std::make_uniqueCircle();}else if (shapeType Rectangle) {return std::make_uniqueRectangle();}else {return nullptr; // 或者抛出一个异常 }}
};// 客户端代码
int main()
{// 使用工厂创建形状对象无需知道具体类 std::unique_ptrShape shape1 ShapeFactory::createShape(Circle);if (shape1) {shape1-draw(); // 输出Drawing a circle. }std::unique_ptrShape shape2 ShapeFactory::createShape(Rectangle);if (shape2) {shape2-draw(); // 输出Drawing a rectangle. }// 无需担心shape1和shape2的具体类型它们都被当作Shape接口使用 return 0;
}上面代码的输出为
Drawing a circle.
Drawing a rectangle.在这个例子中客户端代码通过调用 ShapeFactory::createShape 方法并传入形状类型“Circle或Rectangle”来创建形状对象。由于返回的是 Shape 接口的 unique_ptr客户端代码可以统一地调用 draw 方法而无需关心实际创建的是哪种形状对象。这种方式使得客户端代码更加灵活并且容易扩展新的形状类型因为只需要在工厂类中添加新的创建逻辑即可。
3.2 简单工厂模式应用于减少客户端与具体产品类的耦合
以下是一个简单工厂模式应用于减少客户端与具体产品类耦合的 C 样例。在这个例子中有一个 Payment 接口和两个实现了该接口的类CreditCardPayment 和 CashPayment。客户端代码通过 PaymentFactory 简单工厂类来创建支付对象从而减少了与具体支付类的耦合。
#include iostream
#include string
#include memory // 用于std::unique_ptr // 支付接口
class Payment {
public:virtual void pay() 0;virtual ~Payment() {} // 虚析构函数确保正确释放派生类对象
};// 信用卡支付类
class CreditCardPayment : public Payment {
public:void pay() override {std::cout Processing credit card payment. std::endl;}
};// 现金支付类
class CashPayment : public Payment {
public:void pay() override {std::cout Processing cash payment. std::endl;}
};// 支付工厂类
class PaymentFactory {
public:// 根据支付方式创建支付对象 static std::unique_ptrPayment createPayment(const std::string paymentType) {if (paymentType CreditCard) {return std::make_uniqueCreditCardPayment();}else if (paymentType Cash) {return std::make_uniqueCashPayment();}else {return nullptr; // 或者抛出一个异常 }}
};// 客户端代码
int main()
{// 使用工厂创建支付对象减少与具体支付类的耦合 std::unique_ptrPayment payment1 PaymentFactory::createPayment(CreditCard);if (payment1) {payment1-pay(); // 输出Processing credit card payment. }std::unique_ptrPayment payment2 PaymentFactory::createPayment(Cash);if (payment2) {payment2-pay(); // 输出Processing cash payment. }// 客户端代码不需要直接实例化CreditCardPayment或CashPayment只需要通过Payment接口和工厂类进行交互 return 0;
}上面代码的输出为
Processing credit card payment.
Processing cash payment.在这个例子中客户端代码不需要知道 CreditCardPayment 或 CashPayment 类的具体实现细节。它只需要调用 PaymentFactory::createPayment 方法并传入支付方式“CreditCard” 或 “Cash”工厂类就会返回相应的支付对象。由于返回的是 Payment 接口的 unique_ptr客户端代码可以统一地调用 pay 方法而无需关心实际创建的是哪种支付对象。
这种方式减少了客户端与具体支付类的耦合使得客户端代码更加简洁和易于维护。如果需要添加新的支付方式只需要在工厂类中添加新的创建逻辑而无需修改客户端代码。这符合开闭原则即对扩展开放对修改封闭。
4 简单工厂模式的优点与缺点
C 简单工厂模式的优点主要包括
1封装性好 简单工厂模式封装了对象创建的细节客户端不需要直接实例化具体的产品类。这有助于隐藏具体产品类的实现细节使得客户端代码更加简洁和易于维护。
2解耦 简单工厂模式降低了客户端与具体产品类之间的耦合度。客户端只需要与工厂类交互而不需要知道具体产品类的实现细节。这有助于减少代码的依赖性和提高系统的可维护性。
3代码复用 工厂类集中了产品对象的创建逻辑可以在多个地方重用该工厂类来创建对象提高了代码的复用性。
4扩展性好 当需要添加新的产品类时只需要在工厂类中添加相应的创建逻辑而无需修改客户端代码。这符合开闭原则即对扩展开放对修改封闭。
然而C 简单工厂模式也存在一些缺点
1违反单一职责原则 简单工厂类通常负责创建多种类型的产品对象这可能导致工厂类的职责过多违反了单一职责原则。当产品类型较多时工厂类的代码可能会变得庞大而难以维护。
2类型判断逻辑复杂 简单工厂模式通常需要根据客户端提供的参数或类型信息来判断需要创建哪种类型的产品对象。随着产品类型的增加类型判断逻辑可能会变得复杂和易错。
3不易于扩展新的产品族 简单工厂模式是针对一个产品族设计的如果需要添加新的产品族即一组具有共同主题的产品可能需要修改工厂类的代码这违反了开闭原则。
4不易于使用继承等面向对象特性 由于简单工厂模式通常直接返回具体产品类的实例而不是通过继承等面向对象特性来创建对象因此可能无法充分利用面向对象编程的优势。
需要注意的是简单工厂模式是一种相对简单的工厂模式适用于产品类型较少且不太可能经常变动的场景。在更复杂的场景中可能需要考虑使用抽象工厂模式来应对更多的变化和扩展需求。