工厂模式在C++中的应用场景非常广泛,主要用于对象的创建和管理。通过使用工厂模式,可以将对象的创建与使用分离,从而提高代码的灵活性、可维护性和扩展性。以下是一些常见的应用场景:
1. 对象创建的复杂性
场景: 当对象的创建过程比较复杂,涉及多个步骤或依赖关系时,可以使用工厂模式来封装这些复杂性。
示例:
class Car {
public:
virtual void drive() = 0;
};
class Sedan : public Car {
public:
void drive() override {
std::cout << "Driving a Sedan" << std::endl;
}
};
class SUV : public Car {
public:
void drive() override {
std::cout << "Driving an SUV" << std::endl;
}
};
class CarFactory {
public:
static Car* createCar(const std::string& type) {
if (type == "Sedan") {
return new Sedan();
} else if (type == "SUV") {
return new SUV();
}
return nullptr;
}
};
2. 对象类型的动态选择
场景: 当需要根据运行时的条件动态选择创建不同类型的对象时,工厂模式可以提供一种灵活的方式。
示例:
class Shape {
public:
virtual void draw() = 0;
};
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing a Circle" << std::endl;
}
};
class Square : public Shape {
public:
void draw() override {
std::cout << "Drawing a Square" << std::endl;
}
};
class ShapeFactory {
public:
static Shape* createShape(const std::string& type) {
if (type == "Circle") {
return new Circle();
} else if (type == "Square") {
return new Square();
}
return nullptr;
}
};
3. 对象创建的统一管理
场景: 当系统中有多个地方需要创建相同类型的对象时,工厂模式可以将对象的创建集中管理,避免重复代码。
示例:
class Logger {
public:
virtual void log(const std::string& message) = 0;
};
class FileLogger : public Logger {
public:
void log(const std::string& message) override {
std::cout << "Logging to file: " << message << std::endl;
}
};
class ConsoleLogger : public Logger {
public:
void log(const std::string& message) override {
std::cout << "Logging to console: " << message << std::endl;
}
};
class LoggerFactory {
public:
static Logger* createLogger(const std::string& type) {
if (type == "File") {
return new FileLogger();
} else if (type == "Console") {
return new ConsoleLogger();
}
return nullptr;
}
};
4. 对象创建的扩展性
场景: 当系统需要支持新的对象类型时,工厂模式可以方便地扩展,而不需要修改现有的代码。
示例:
class Animal {
public:
virtual void makeSound() = 0;
};
class Dog : public Animal {
public:
void makeSound() override {
std::cout << "Woof!" << std::endl;
}
};
class Cat : public Animal {
public:
void makeSound() override {
std::cout << "Meow!" << std::endl;
}
};
class AnimalFactory {
public:
static Animal* createAnimal(const std::string& type) {
if (type == "Dog") {
return new Dog();
} else if (type == "Cat") {
return new Cat();
}
return nullptr;
}
};
5. 对象创建的依赖注入
场景: 当对象的创建依赖于其他对象或配置时,工厂模式可以提供一种依赖注入的方式。
示例:
class Database {
public:
virtual void connect() = 0;
};
class MySQLDatabase : public Database {
public:
void connect() override {
std::cout << "Connecting to MySQL database" << std::endl;
}
};
class PostgreSQLDatabase : public Database {
public:
void connect() override {
std::cout << "Connecting to PostgreSQL database" << std::endl;
}
};
class DatabaseFactory {
public:
static Database* createDatabase(const std::string& type) {
if (type == "MySQL") {
return new MySQLDatabase();
} else if (type == "PostgreSQL") {
return new PostgreSQLDatabase();
}
return nullptr;
}
};
6. 对象创建的延迟初始化
场景: 当对象的创建成本较高,且不一定立即使用时,可以使用工厂模式来实现延迟初始化。
示例:
class ExpensiveResource {
public:
ExpensiveResource() {
std::cout << "Expensive resource initialized" << std::endl;
}
void use() {
std::cout << "Using expensive resource" << std::endl;
}
};
class ResourceFactory {
private:
static ExpensiveResource* resource;
public:
static ExpensiveResource* getResource() {
if (resource == nullptr) {
resource = new ExpensiveResource();
}
return resource;
}
};
ExpensiveResource* ResourceFactory::resource = nullptr;
7. 对象创建的抽象化
场景: 当需要将对象的创建过程抽象化,以便在不同的上下文中使用时,工厂模式可以提供一种抽象的创建方式。
示例:
class Button {
public:
virtual void render() = 0;
};
class WindowsButton : public Button {
public:
void render() override {
std::cout << "Rendering a Windows button" << std::endl;
}
};
class MacOSButton : public Button {
public:
void render() override {
std::cout << "Rendering a MacOS button" << std::endl;
}
};
class ButtonFactory {
public:
static Button* createButton(const std::string& os) {
if (os == "Windows") {
return new WindowsButton();
} else if (os == "MacOS") {
return new MacOSButton();
}
return nullptr;
}
};
总结
工厂模式在C++中的应用场景非常广泛,主要用于对象的创建和管理。通过使用工厂模式,可以提高代码的灵活性、可维护性和扩展性,同时将对象的创建与使用分离,使得代码更加清晰和易于管理。