使用工厂模式创建对象的好处在于,具体的实现类可以随意换(解耦)。因为在返回创建的对象的时候,我将此对象向上转型。那么如果需求变动,我可以再写一个这个接口的实现类,只用修改这个工厂类中的代码。而使用这个工厂类创建对象后的各种逻辑代码我都可以不用改。
工厂模式(Factory Pattern)是一种创建型设计模式,旨在提供一个创建对象的接口,而不指定具体类。工厂模式可以分为三种主要类型:简单工厂模式、工厂方法模式和抽象工厂模式。下面将详细介绍这三种模式及其使用场景。
简单工厂模式:适用于对象创建逻辑相对简单且变化较少的情况。是由一个工厂对象创建产品实例,简单工厂模式的工厂类一般是使用静态方法,通过不同的参数的创建不同的对象实例 可以生产结构中的任意产品,不能增加新的产品
抽象工厂模式: 提供一个创建一系列相关或相互依赖对象的接口,而无需制定他们具体的类,生产多个系列产品 生产不同产品族的全部产品,不能新增产品,可以新增产品族。适用于创建相关或依赖对象的场景,通过增加新的具体工厂来支持不同的产品族
工厂方法模式:适用于需要扩展产品家族的情况,通过增加新的具体工厂来实现。
每种工厂模式都有其独特的使用场景和优缺点,选择合适的模式可以提高代码的灵活性和可维护性。
- 简单工厂模式
工厂类通常是单一的,通过传入参数控制创建哪种具体产品。
使用静态方法来实现工厂功能。
扩展性较差,新增产品时需要修改工厂类。 - 工厂方法模式
通过抽象工厂方法定义创建对象的接口。
每个具体工厂类负责创建一个具体产品的实例。
扩展性好,新增产品只需添加具体工厂类,符合开闭原则。 - 抽象工厂模式
提供一个接口用于创建一系列相关或互相依赖的对象。
涉及多个抽象产品接口和具体工厂类。
强调产品族的概念,保证一系列产品的一致性和兼容性。
选择哪种工厂模式取决于实际需求和应用场景。如果只是需要简单的对象创建,可以使用简单工厂模式;如果需要扩展性和灵活性,可以考虑使用工厂方法模式;如果涉及多个产品族且需要保证产品的一致性,则抽象工厂模式是合适的选择。
1. 简单工厂模式(Simple Factory)
定义
简单工厂模式由一个工厂类根据传入的参数决定创建哪一种产品类的实例。它通常不是一种真正的设计模式,更像是一种编程习惯。
结构
工厂类(Factory Class):负责创建具体的产品实例。
产品类(Product Class):被创建的对象,通常是一些具有共同接口或父类的具体类。
示例
假设我们有一个接口 Product 和两个实现类 ConcreteProductA 和 ConcreteProductB。
// 产品接口
interface Product {
void use();
}
// 具体产品A
class ConcreteProductA implements Product {
public void use() {
System.out.println("Using Product A");
}
}
// 具体产品B
class ConcreteProductB implements Product {
public void use() {
System.out.println("Using Product B");
}
}
// 工厂类
class SimpleFactory {
public static Product createProduct(String type) {
if (type.equals("A")) {
return new ConcreteProductA();
} else if (type.equals("B")) {
return new ConcreteProductB();
}
throw new IllegalArgumentException("Unknown product type");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Product productA = SimpleFactory.createProduct("A");
productA.use();
Product productB = SimpleFactory.createProduct("B");
productB.use();
}
}
2. 工厂方法模式(Factory Method)
工厂方法模式定义了一个创建对象的接口,但由子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
抽象工厂(Creator):声明工厂方法,该方法返回一个新创建的产品对象。
具体工厂(ConcreteCreator):实现工厂方法来创建具体的产品对象。
产品接口(Product):定义产品的接口。
具体产品(ConcreteProduct):实现产品接口的具体类。
示例
假设我们继续使用上面的 Product 接口和具体实现类 ConcreteProductA 和 ConcreteProductB。
// 抽象工厂
abstract class Factory {
public abstract Product createProduct();
public void someOperation() {
// 使用产品
Product product = createProduct();
product.use();
}
}
// 具体工厂A
class ConcreteFactoryA extends Factory {
public Product createProduct() {
return new ConcreteProductA();
}
}
// 具体工厂B
class ConcreteFactoryB extends Factory {
public Product createProduct() {
return new ConcreteProductB();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
factoryA.someOperation();
Factory factoryB = new ConcreteFactoryB();
factoryB.someOperation();
}
}
3. 抽象工厂模式(Abstract Factory)
抽象工厂模式提供一个接口,用于创建一系列相关或互相依赖的对象,而无需指定它们具体的类。
抽象工厂(AbstractFactory):声明创建一组产品的方法,每个方法对应一个产品。
具体工厂(ConcreteFactory):实现抽象工厂中的方法,生成具体的产品对象。
抽象产品(AbstractProduct):为每种产品声明接口。
具体产品(ConcreteProduct):实现抽象产品接口的具体类。
假设我们有两个产品族:ProductA 和 ProductB,每个产品族有两个版本。
// 抽象产品A
interface ProductA {
void use();
}
// 具体产品A1
class ConcreteProductA1 implements ProductA {
public void use() {
System.out.println("Using Product A1");
}
}
// 具体产品A2
class ConcreteProductA2 implements ProductA {
public void use() {
System.out.println("Using Product A2");
}
}
// 抽象产品B
interface ProductB {
void eat();
}
// 具体产品B1
class ConcreteProductB1 implements ProductB {
public void eat() {
System.out.println("Eating Product B1");
}
}
// 具体产品B2
class ConcreteProductB2 implements ProductB {
public void eat() {
System.out.println("Eating Product B2");
}
}
// 抽象工厂
interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA1();
}
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA2();
}
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
productA1.use();
productB1.eat();
AbstractFactory factory2 = new ConcreteFactory2();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
productA2.use();
productB2.eat();
}
}