简单工厂、工厂方法、抽象工厂的区别
在软件开发中,设计模式是一种被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。在创建型设计模式中,简单工厂、工厂方法和抽象工厂是三种常见的模式,它们各有特点,适用于不同的场景。本文将详细阐述这三种模式的核心定义、侧重点以及运用场景,并通过Java语言进行示例说明。
一、核心定义
简单工厂模式(Simple Factory Pattern)
简单工厂模式又称静态工厂方法模式,是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。简单工厂模式的核心思想就是有一个专门的类来负责创建实例的过程。
简单工厂模式由以下角色组成:
- 工厂角色(Factory Role):是简单工厂模式的核心,负责创建所有的类的内部逻辑。工厂类必须能够被外界调用,创建所需要的产品对象。
- 抽象产品角色(Abstract Product Role):简单工厂模式所创建的所有对象的父类,父类可以是接口也可以是抽象类,负责描述所有实例所共有的公共接口。
- 具体产品角色(Concrete Product Role):具体产品类继承自抽象产品类,可以有多个,是简单工厂所创建的具体实例对象。
简单工厂模式的UML图如下:
示例代码:
// 抽象产品角色
abstract class AbstractProduct {
public abstract void show();
}
// 具体产品角色A
class ConcreteProductA extends AbstractProduct {
@Override
public void show() {
System.out.println("This is a ProductA");
}
}
// 具体产品角色B
class ConcreteProductB extends AbstractProduct {
@Override
public void show() {
System.out.println("This is a ProductB");
}
}
// 工厂角色
class Factory {
public AbstractProduct createProduct(String type) {
if (type.equals("A")) {
return new ConcreteProductA();
} else if (type.equals("B")) {
return new ConcreteProductB();
}
return null;
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Factory factory = new Factory();
AbstractProduct productA = factory.createProduct("A");
productA.show();
AbstractProduct productB = factory.createProduct("B");
productB.show();
}
}
工厂方法模式(Factory Method Pattern)
工厂方法模式是一种创建型设计模式,它定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。其核心思想是将对象的创建与使用解耦,客户端无需知道具体产品的创建细节。
工厂方法模式由以下角色组成:
- 产品(Product):定义了工厂方法所创建对象的接口,是创建对象的超类型。
- 具体产品(Concrete Product):实现了产品接口的具体类,由工厂方法创建。
- 工厂(Creator):声明了工厂方法,用于返回一个产品对象,工厂方法的返回类型是产品类型。
- 具体工厂(Concrete Creator):实现了工厂方法,返回具体产品的实例。
工厂方法模式的UML图如下:
示例代码:
// 产品接口
interface Product {
void operation();
}
// 具体产品A
class ConcreteProductA implements Product {
@Override
public void operation() {
System.out.println("ConcreteProductA operation");
}
}
// 具体产品B
class ConcreteProductB implements Product {
@Override
public void operation() {
System.out.println("ConcreteProductB operation");
}
}
// 工厂接口
interface Creator {
Product factoryMethod();
}
// 具体工厂A
class ConcreteCreatorA implements Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductA();
}
}
// 具体工厂B
class ConcreteCreatorB implements Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductB();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Creator creatorA = new ConcreteCreatorA();
Product productA = creatorA.factoryMethod();
productA.operation();
Creator creatorB = new ConcreteCreatorB();
Product productB = creatorB.factoryMethod();
productB.operation();
}
}
抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式的核心思想是将对象的创建与使用分离开来,从而实现系统的松耦合。
抽象工厂模式由以下角色组成:
- 抽象产品A(AbstractProductA):定义产品A的接口。
- 具体产品A1(ConcreteProductA1):实现抽象产品A的接口,属于一个具体工厂。
- 具体产品A2(ConcreteProductA2):实现抽象产品A的接口,属于另一个具体工厂。
- 抽象产品B(AbstractProductB):定义产品B的接口。
- 具体产品B1(ConcreteProductB1):实现抽象产品B的接口,属于一个具体工厂。
- 具体产品B2(ConcreteProductB2):实现抽象产品B的接口,属于另一个具体工厂。
- 抽象工厂(AbstractFactory):声明创建抽象产品A和抽象产品B的接口。
- 具体工厂1(ConcreteFactory1):实现抽象工厂接口,创建具体产品A1和具体产品B1。
- 具体工厂2(ConcreteFactory2):实现抽象工厂接口,创建具体产品A2和具体产品B2。
- 客户端(Client):使用抽象工厂和抽象产品来创建具体产品。
抽象工厂模式的UML图如下:
示例代码:
// 抽象产品A
public interface AbstractProductA {
void use();
}
// 具体产品A1
public class ConcreteProductA1 implements AbstractProductA {
@Override
public void use() {
System.out.println("Using ConcreteProductA1");
}
}
// 具体产品A2
public class ConcreteProductA2 implements AbstractProductA {
@Override
public void use() {
System.out.println("Using ConcreteProductA2");
}
}
// 抽象产品B
public interface AbstractProductB {
void use();
}
// 具体产品B1
public class ConcreteProductB1 implements AbstractProductB {
@Override
public void use() {
System.out.println("Using ConcreteProductB1");
}
}
// 具体产品B2
public class ConcreteProductB2 implements AbstractProductB {
@Override
public void use() {
System.out.println("Using ConcreteProductB2");
}
}
// 抽象工厂
public interface AbstractFactory {
AbstractProductA createA();
AbstractProductB createB();
}
// 具体工厂1
public class ConcreteFactory1 implements AbstractFactory {
@Override
public AbstractProductA createA() {
return new ConcreteProductA1();
}
@Override
public AbstractProductB createB() {
return new ConcreteProductB1();
}
}
// 具体工厂2
public class ConcreteFactory2 implements AbstractFactory {
@Override
public AbstractProductA createA() {
return new ConcreteProductA2();
}
@Override
public AbstractProductB createB() {
return new ConcreteProductB2();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
AbstractProductA productA1 = factory1.createA();
AbstractProductB productB1 = factory1.createB();
productA1.use();
productB1.use();
AbstractFactory factory2 = new ConcreteFactory2();
AbstractProductA productA2 = factory2.createA();
AbstractProductB productB2 = factory2.createB();
productA2.use();
productB2.use();
}
}
二、运用场景
简单工厂
简单工厂模式适用于以下场景:
- 当一个系统只需要一个具体产品对象,而无需对产品对象进行扩展时,可以使用简单工厂模式。例如,一个简单的日志记录器,系统只需要一种日志记录方式,不需要对日志记录器进行扩展。
- 当客户端不需要知道对象的创建过程,只需要知道如何使用对象时,可以使用简单工厂模式。简单工厂将对象的创建过程封装起来,使得客户端只需要调用工厂方法来获取所需的对象实例,而无需了解具体的创建细节。
- 当需要对对象的创建过程进行集中管理和控制时,可以使用简单工厂模式。简单工厂可以根据需要对对象的创建过程进行调整和优化,而无需影响客户端代码。
工厂方法
工厂方法模式适用于以下场景:
- 客户只知道创建产品的工厂名,而不知道具体的产品名。例如,TCL电视工厂、海信电视工厂等。
- 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
- 客户不关心创建产品的细节,只关心产品的品牌。
抽象工厂
抽象工厂模式适用于以下场景:
- 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
- 系统中有多个产品族,但每次只使用其中的某一族产品。
- 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。
三、侧重点
简单工厂
简单工厂模式的侧重点在于将对象的创建逻辑封装在工厂类中,使得客户端代码与具体的产品类解耦。它通过一个工厂类来创建其他类的实例,而无需暴露对象的创建逻辑。简单工厂模式适用于创建对象的过程相对简单,且客户端不需要了解具体创建过程的情况。
工厂方法
工厂方法模式的侧重点在于将对象的实例化延迟到其子类。它定义了一个用于创建对象的接口,但由子类决定实例化哪一个类。工厂方法模式使得系统在不修改原来代码的情况下可以引进新的产品,即满足开闭原则。它适用于创建对象的过程相对复杂,且需要扩展新的产品类的情况。
抽象工厂
抽象工厂模式的侧重点在于创建一系列相关或相互依赖的对象。它提供了一种创建一系列相关对象的接口,而无需指定它们的具体类。抽象工厂模式使得客户端代码与具体的产品类解耦,同时使得系统可以轻松地切换不同的产品族。它适用于需要创建的对象是一系列相互关联或相互依赖的产品族的情况。