什么是工厂模式?
顾名思义,工厂模式是现实生活中工厂的映射,由个人生产商品(new对象)变成由专业的工厂生产商品。
按照生产产品的场景不同,工厂模式分为,简单工厂模式、工厂方法模式、抽象工厂模式。
简单工厂模式对应农耕社会小作坊,工厂方法模式对应业革命流水线,抽象工厂对应现代产业链代工厂。我们的项目代码同样是由简到繁一步一步迭代而来的,但对于调用者来说,却越来越简单。
- 简单工厂模式解决了产品的生产问题,生产和消费分离
- 工厂方法模式解决了产品由谁生产的问题,用户开始关注品牌,工厂和产品分离
使用场景
复杂对象的创建,对象创建和业务解耦分离,上述复杂对象指的是类的构造函数参数过多等对类的构造有影响的情况,因为类的构造过于复杂,如果直接在其他业务类内使用,则两者的耦合过重,后续业务更改,就需要在任何引用该类的源代码内进行更改,光是查找所有依赖就很消耗时间了,更别说要一个一个修改了。
简单工厂模式 Simple Factory Pattern
我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”。
在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern)。
对应小工作坊,比如小酒厂,提供高粱酒、小麦酒等产品,用户不关心制作过程。
代码实现
- 抽象产品(Product):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
- 具体产品(ProductA和ProductB):是简单工厂模式的创建目标。
- 简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。 ```java
/**
- 产品 */ interface Product { }
/**
- 产品A */ class ProductA implements Product { }
/**
- 产品B */ class ProductB implements Product { }
/**
- 产品类型 */ enum ProductType { //产品A A, //产品B B; }
class SimpleFactory { /**
* 根据参数创建相应的产品
*
* @param productType 产品类型
* @return 具体的产品 Product
*/
public static Product makeProduct(ProductType productType) {
switch (productType) {
case A:
return new ProductA();
case B:
return new ProductB();
default:
return null;
}
}
}
//简单工厂测试 public class SimpleFactoryPattern { public static void main(String[] args) { Product a = SimpleFactory.makeProduct(ProductType.A); Product b = SimpleFactory.makeProduct(ProductType.B);
System.out.println(a);
System.out.println(b);
}
}
<a name="1PXmL"></a>
## JDK中的简单工厂模式
Java中的Calendar类,在创建Calendar实例时,就使用了简单工厂。
<a name="CZskL"></a>
# 工厂方法模式 Factory Method Pattern
对应现实中流水线工厂,用户只知道创建产品的工厂名,而不知道具体的产品名,还是拿酒来说,如 青岛啤酒、崂山啤酒等。<br />青岛啤酒厂可以生产高粱酒,也可以生产小麦酒。<br />崂山啤酒厂也可以生产高粱酒,也可以生产小麦酒。<br />用户更关注品牌。
<a name="HtC03"></a>
## 代码实现
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ProductA,ProductB):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
- 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
- 具体工厂(Factory1,Factory2):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
```java
/**
* 产品
*/
interface Product {
}
/**
* 产品A
*/
class ProductA implements Product {
}
/**
* 产品B
*/
class ProductB implements Product {
}
/**
* 产品类型
*/
enum ProductType {
//产品A
A,
//产品B
B;
}
/**
* 工厂方法类接口
*/
interface FactryMeathod {
//抽象生产产品方法
Product makeProduct(ProductType productType);
}
/**
* 工厂1
* 可以生产产品A也可以生产产品B
*/
class FactryMeathod1 implements FactryMeathod {
/**
* 根据参数创建相应的产品
*
* @param productType 产品类型
* @return 具体的产品 Product
*/
@Override
public Product makeProduct(ProductType productType) {
switch (productType) {
case A:
return new ProductA();
case B:
return new ProductB();
default:
return null;
}
}
}
/**
* 工厂2
* 可以生产产品A也可以生产产品B
*/
class FactryMeathod2 implements FactryMeathod {
/**
* 根据参数创建相应的产品
*
* @param productType 产品类型
* @return 具体的产品 Product
*/
@Override
public Product makeProduct(ProductType productType) {
switch (productType) {
case A:
return new ProductA();
case B:
return new ProductB();
default:
return null;
}
}
}
//工厂方法测试
public class FactoryMethodPattern {
public static void main(String[] args) {
FactryMeathod f1 = new FactryMeathod1();
Product a1 = f1.makeProduct(ProductType.A);
Product b1 = f1.makeProduct(ProductType.B);
System.out.println(a1);
System.out.println(b1);
//此时增加需求,我只需增加一个新的工厂实现FactryMeathod2 即可,无需修改FactryMeathod1
FactryMeathod f2 = new FactryMeathod2();
Product a2 = f2.makeProduct(ProductType.A);
Product b2 = f2.makeProduct(ProductType.B);
System.out.println(a2);
System.out.println(b2);
}
}
JDK中的工厂方法模式
Collection中的iterator方法java.util.Collection
接口中定义了一个抽象的iterator()
方法,该方法就是一个工厂方法。
对于iterator()
方法来说Collection
就是一个根抽象工厂,下面还有List
等接口作为抽象工厂,再往下有ArrayList
等具体工厂。java.util.Iterator
接口是根抽象产品,下面有ListIterator
等抽象产品,还有ArrayListIterator
等作为具体产品。
JDBC也是工厂方法模式
在使用JDBC
进行数据库开发时,如果数据库由MySQL改为Oracle或其他,则只需要改一下数据库驱动名称就可以,其他都不用修改。
抽象工厂模式 Abstract Factory Pattern
抽象工厂类比现实中的集团,有一个超级工厂可以创建其他工厂,由其他工厂在创建具体的产品。比如海尔,海尔旗下有多个品牌,比如卡萨帝和统帅
卡萨帝可以生产空调、冰箱、洗衣机
统帅也可以生产空调、冰箱、洗衣机
代码实现
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ProductA,ProductB):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
- 抽象工厂(Abstract Factory):超级工厂,用于创建具体的工厂
- 具体工厂(Factory1,Factory2):完成具体产品的创建。
```java
/**
- 产品 */ interface Product { }
/**
- 产品A */ class ProductA implements Product { }
/**
- 产品B */ class ProductB implements Product { }
/**
- 产品类型 */ enum ProductType { //产品A A, //产品B B; }
/**
- 工厂类型 */ enum FactoryType { //工厂1 f1, //工厂2 f2; }
/**
- 工厂接口 */ interface Factry { //生产产品抽象方法 Product makeProduct(ProductType productType); }
/**
- 工厂1
- 可以生产产品A也可以生产产品B
/
class Factry1 implements Factry {
/*
- 根据参数创建相应的产品 *
- @param productType 产品类型
- @return 具体的产品 Product
*/
@Override
public Product makeProduct(ProductType productType) {
switch (productType) {
} } }case A:
return new ProductA();
case B:
return new ProductB();
default:
return null;
/**
- 工厂2
- 可以生产产品A也可以生产产品B
/
class Factry2 implements Factry {
/*
- 根据参数创建相应的产品 *
- @param productType 产品类型
- @return 具体的产品 Product
*/
@Override
public Product makeProduct(ProductType productType) {
switch (productType) {
} } }case A:
return new ProductA();
case B:
return new ProductB();
default:
return null;
/**
- 抽象工厂
*/
class AbstractFactory {
//创建工厂方法
public static Factry createFactory(FactoryType factoryType) {
} }switch (factoryType) {
case f1:
return new Factry1();
case f2:
return new Factry2();
default:
throw new RuntimeException("工厂类型不正确");
}
//抽象工厂模式测试 public class FactoryMethodPattern { public static void main(String[] args) { Factry f1 = AbstractFactory.createFactory(FactoryType.f1); Product a1 = f1.makeProduct(ProductType.A); Product b1 = f1.makeProduct(ProductType.B); System.out.println(a1); System.out.println(b1);
Factry f2 = AbstractFactory.createFactory(FactoryType.f2);
Product a2 = f2.makeProduct(ProductType.A);
Product b2 = f2.makeProduct(ProductType.B);
System.out.println(a2);
System.out.println(b2);
}
}
JDK中抽象工厂模式
Calendar类的getInstance()方法就是抽象工厂应用的绝佳例子