创建型模式中的工厂模式
分为三种:简单工厂模式,工厂方法模式,抽象工厂模式
他们都属于创建型模式,下一篇博客会把23种设计模式进行分类
简单工厂模式
定义:定义了一个创建对象的类,由这个类来封装实例化对象的行为
存在的问题:类的创建依赖于工厂类,想要更改拓展程序时必须修改工厂类,违背了开放-封闭原则。
如何解决:可以定义一个创建对象的抽象方法同时创建多个不同的工厂类实现该抽象方法。其实就是工厂方法模式
大话设计模式是一本经典的设计模式入门书籍,其中对于简单工厂模式、工厂方法模式和抽象工厂模式都有比较详细的讲解以及相应的Java代码示例。下面是这三种模式的文章。
一、简单工厂模式代码示例
简单工厂模式是最简单的工厂模式,它提供一个工厂类,根据传入的参数动态创建出相应的产品对象。简单工厂模式的核心在于工厂类,它负责根据传入的条件来创建出相应的产品对象。下面是Java代码示例:
1.产品类
public class Product {
public void method() {
System.out.println("我是产品");
}
}
2.工厂类
public class Factory {
public static Product createProduct(String type) {
Product product = null;
if ("A".equals(type)) {
product = new ProductA();
} else if ("B".equals(type)) {
product = new ProductB();
}
return product;
}
}
3.客户端调用
public class Client {
public static void main(String[] args) {
Product productA = Factory.createProduct("A");
Product productB = Factory.createProduct("B");
productA.method();
productB.method();
}
}
简单工厂模式的优点在于可以使客户端代码和具体产品类的创建过程解耦,客户端只需要知道要创建的产品类型即可,而无需知道具体的创建细节。缺点在于每次添加新产品都需要修改工厂类的代码,违背了开闭原则。
工厂方法模式
定义:定义了一个创建对象的抽象方法,由子类决定要实例化的类。
存在的问题:客户端需要创建类的具体实例,增加了用户的操作复杂性。
如何解决这一问题:我们可以把工厂类抽象为接口,用户只需要去找默认的工厂提出自己的需求(传入参数),便能得到自己想要产品,而不用根据产品去寻找不同的工厂,方便用户操作。这也就是接下来要说的抽象工厂模式。
二、工厂方法模式代码示例
工厂方法模式是针对简单工厂模式的缺点而提出的一种解决方案,它将具体产品的创建过程推迟到具体工厂类中,从而使得客户端只需要关注工厂类即可。下面是Java代码示例:
1.产品类
public interface Product {
void method();
}
2.具体产品类
public class ProductA implements Product {
@Override
public void method() {
System.out.println("我是产品A");
}
}
public class ProductB implements Product {
@Override
public void method() {
System.out.println("我是产品B");
}
}
3.工厂类
public interface Factory {
Product createProduct();
}
public class FactoryA implements Factory {
@Override
public Product createProduct() {
return new ProductA();
}
}
public class FactoryB implements Factory {
@Override
public Product createProduct() {
return new ProductB();
}
}
4.客户端调用
public class Client {
public static void main(String[] args) {
Factory factoryA = new FactoryA();
Factory factoryB = new FactoryB();
Product productA = factoryA.createProduct();
Product productB = factoryB.createProduct();
productA.method();
productB.method();
}
}
工厂方法模式将具体产品的创建过程推迟到具体工厂类中,从而使得每个工厂只需要关注自己负责的产品对象即可。这样可以解决简单工厂模式中每次添加新产品都需要修改工厂类的问题。但是工厂方法模式会造成类的数量增加,增加了系统的复杂度。
抽象工厂模式
定义:定义了一个接口用于创建相关或有依赖关系的对象族,而无需明确指定具体类。
三、抽象工厂模式代码示例
抽象工厂模式是针对工厂方法模式的缺点而提出的解决方案,它的核心在于抽象工厂类,它定义了一个负责创建一系列相关或相互依赖对象的接口。具体工厂类实现这个接口,从而创建出具体的产品对象。下面是Java代码示例:
1.产品类
public interface ProductA {
void method();
}
public interface ProductB {
void method();
}
2.具体产品类
public class ProductA1 implements ProductA {
@Override
public void method() {
System.out.println("我是产品A1");
}
}
public class ProductA2 implements ProductA {
@Override
public void method() {
System.out.println("我是产品A2");
}
}
public class ProductB1 implements ProductB {
@Override
public void method() {
System.out.println("我是产品B1");
}
}
public class ProductB2 implements ProductB {
@Override
public void method() {
System.out.println("我是产品B2");
}
}
3.抽象工厂类
public interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
public class Factory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ProductA1();
}
@Override
public ProductB createProductB() {
return new ProductB1();
}
}
public class Factory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ProductA2();
}
@Override
public ProductB createProductB() {
return new ProductB2();
}
}
4.客户端调用
public class Client {
public static void main(String[] args) {
AbstractFactory factory1 = new Factory1();
AbstractFactory factory2 = new Factory2();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
productA1.method();
productB1.method();
productA2.method();
productB2.method();
}
}
抽象工厂模式将一系列相关或相互依赖的产品对象放在同一个工厂中创建,这样可以保证产品之间的兼容性。但是具体添加新的产品时,就需要修改抽象工厂类的接口,这样会影响到工厂类的所有子类。此外,抽象工厂模式也会造成类的数量增加,增加了系统的复杂度。
工厂模式适用场合
当有很多产品需要创建而这些产品又具有共同的接口就可以适用
使用选择
简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品)
抽象工厂 :用来生产不同产品族的全部产品。(支持拓展增加产品;支持增加产品族)
通俗来讲:工厂方法像工厂中的一个生产线,而抽象工厂是一个工厂。
三个模式对比区别
下面是简单工厂模式、工厂方法模式和抽象工厂模式的区别表格:
维度 | 简单工厂模式 | 工厂方法模式 | 抽象工厂模式 |
---|---|---|---|
定义 | 由一个工厂类负责创建所有产品 | 定义一个用于创建对象的接口,让子类决定实例化哪个类 | 提供一个用于创建相关或相互依赖对象的接口,无需指定具体的类 |
核心 | 工厂类 | 工厂接口和具体工厂类 | 抽象工厂类和具体工厂类 |
产品 | 产品由工厂类负责创建 | 工厂接口定义产品的创建方法,具体的产品由具体工厂类负责创建 | 抽象工厂类定义一系列产品的创建接口,由具体工厂类实现 |
客户端 | 客户端只需要知道工厂类和产品类,无需知道具体的创建细节 | 客户端需要知道工厂接口、具体的工厂类和产品类,需要实例化具体的工厂类 | 客户端需要知道抽象工厂类、具体的工厂类和产品类,需要实例化具体的工厂类 |
添加新产品 | 需要修改工厂类的代码 | 只需要增加一个新的具体工厂类和具体产品类 | 需要修改抽象工厂类的接口和所有的具体工厂类 |
优缺点 | 简单易理解,但不符合开闭原则 | 符合开闭原则,但增加了系统的复杂度 | 保证产品之间的兼容性,但增加了系统的复杂度 |
适用场景 | 创建产品对象比较少,且客户端只知道传入工厂类的参数 | 需要创建一组相关或相互依赖的产品对象,且具体的产品类不用知道 | 需要创建一组相关或相互依赖的产品对象,且产品之间是有关联的 |