在软件设计中,创建型设计模式用于处理对象创建的复杂性。本文将对比三种常见的创建型设计模式:简单工厂模式、工厂方法模式和抽象工厂模式。
一,简单工厂模式
定义:简单工厂模式(Simple Factory Pattern)定义了一个工厂类,该类可以根据传入的参数决定创建哪一种产品实例。
结构:
- 产品(Product):定义产品的接口。
- 具体产品(ConcreteProduct):实现具体产品。
- 工厂(Factory):定义一个方法,根据参数创建具体产品实例。
优点:
- 简单易懂,适合小规模系统。
- 客户端无需知道具体产品类,降低耦合度。
缺点:
- 工厂类集中了所有产品创建逻辑,违反单一职责原则。
- 不易于扩展,一旦增加新产品,需要修改工厂类。
二,工厂方法模式
定义:工厂方法模式(Factory Method Pattern)定义了一个创建对象的接口,但由子类决定实例化哪一个类。这样,工厂方法将实例化操作推迟到子类。
结构:
- 抽象产品(Product):定义产品的接口。
- 具体产品(ConcreteProduct):实现具体产品。
- 抽象工厂(Creator):声明工厂方法,返回产品对象。
- 具体工厂(ConcreteCreator):实现工厂方法,返回具体产品实例。
优点:
- 代码符合开闭原则,易于扩展。
- 客户端无需知道具体产品类,降低耦合度。
缺点:
- 每增加一个产品,需要增加一个具体工厂,增加了系统复杂性。
三,抽象工厂模式
定义:抽象工厂模式(Abstract Factory Pattern)提供了一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。
结构:
- 抽象产品(AbstractProduct):定义产品的接口。
- 具体产品(ConcreteProduct):实现具体产品。
- 抽象工厂(AbstractFactory):声明创建一系列产品的方法。
- 具体工厂(ConcreteFactory):实现创建具体产品的系列方法。
优点:
- 保持产品族的一致性,确保相关产品一起使用。
- 符合开闭原则,易于扩展。
缺点:
- 增加了系统的复杂性,尤其是当产品族和产品等级结构增加时。
- 扩展产品族较为困难,需要修改抽象工厂接口。
四,示例代码对比
简单工厂模式:
// 产品接口
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) {
switch (type) {
case "A":
return new ConcreteProductA();
case "B":
return new ConcreteProductB();
default:
throw new IllegalArgumentException("Unknown product type");
}
}
}
// 客户端代码
public class SimpleFactoryDemo {
public static void main(String[] args) {
Product productA = SimpleFactory.createProduct("A");
productA.use();
Product productB = SimpleFactory.createProduct("B");
productB.use();
}
}
工厂方法模式:
// 产品接口
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");
}
}
// 抽象工厂
abstract class Factory {
public abstract Product createProduct();
}
// 具体工厂A
class ConcreteFactoryA extends Factory {
public Product createProduct() {
return new ConcreteProductA();
}
}
// 具体工厂B
class ConcreteFactoryB extends Factory {
public Product createProduct() {
return new ConcreteProductB();
}
}
// 客户端代码
public class FactoryMethodDemo {
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
Product productA = factoryA.createProduct();
productA.use();
Factory factoryB = new ConcreteFactoryB();
Product productB = factoryB.createProduct();
productB.use();
}
}
抽象工厂模式:
// 产品接口
interface ProductA {
void use();
}
interface ProductB {
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");
}
}
// 具体产品B1
class ConcreteProductB1 implements ProductB {
public void use() {
System.out.println("Using Product B1");
}
}
// 具体产品B2
class ConcreteProductB2 implements ProductB {
public void use() {
System.out.println("Using 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 AbstractFactoryDemo {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
productA1.use();
productB1.use();
AbstractFactory factory2 = new ConcreteFactory2();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
productA2.use();
productB2.use();
}
}
五,对比总结
复杂度:
- 简单工厂模式最简单,适用于小规模系统。
- 工厂方法模式适中,适用于需要扩展单一产品的系统。
- 抽象工厂模式最复杂,适用于需要创建一系列相关产品的系统。
扩展性:
- 简单工厂模式扩展性最差,需要修改工厂类。
- 工厂方法模式扩展单一产品较为容易。
- 抽象工厂模式扩展产品族较为容易,但扩展单一产品较为复杂。
使用场景:
- 简单工厂模式适用于产品种类较少且变化不频繁的场景。
- 工厂方法模式适用于需要创建单一产品且产品种类不多的场景。
- 抽象工厂模式适用于需要创建一系列相关产品的场景,确保产品族的一致性。
如果你对设计模式、软件架构、编程技巧等内容感兴趣,欢迎关注我们的同名微信公众号【技术拾光者】。在这里,我们将定期分享最新的技术文章和实用的编程技巧,帮助你不断提升自己的技术水平。
扫描下方二维码,立即关注我们吧!
感谢你的阅读和支持,我们期待与你在微信公众号上交流更多有趣的技术话题!