工厂模式(Factory pattern)
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,这种设计模式属于创建型模式。
在工厂模式中,创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
**tips:**GOF 23 种设计模式中只有「工厂方法模式」与「抽象工厂模式」,简单工厂其实不是一个标准的的设计模式,简单工厂模式可以看为工厂方法模式的一种特例。
代码
三合一可以直接跳到代码。
- [简单工厂模式(Simple Factory)](#简单工厂模式(Simple Factory))
- [工厂方法模式(Factory Method)](#工厂方法模式(Factory Method))
- [抽象工厂模式(Abstract Factory)](#抽象工厂模式(Abstract Factory))
介绍
作用
- 定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
主要解决:
- 接口选择的问题。
何时使用:
- 计划不同条件下创建不同实例时。
如何解决:
- 在工厂类中创建对应的子类并返回抽象的产品。
关键代码:
- 在工厂类中创建对应产品
应用实例:
- 经典披萨
优点:
- 对调用者分离隐藏具体的产品类。具体的产品类,无论内在逻辑是什么、如何变动,调用者只需要使用工厂对应的方式去获取产品即可。
- 降低耦合度。产品与调用者之间的耦合度因为工厂这个中间逻辑存在而被削弱。
- 扩展性好。产品的增加仅仅需要将该产品写入到工厂类中即可被使用。
分类
简单工厂模式(Simple Factory)
UML
代码
//工厂
public class FactoryPattern {
public AbstractProduct getProduct(int i) {
AbstractProduct product;
switch (i) {
case 1:
product = new ProductA();
break;
case 2:
product = new ProductB();
break;
default:
throw new UnsupportedOperationException("不支持该操作");
}
return product;
}
public static void main(String[] args) {
FactoryPattern factory = new FactoryPattern();
AbstractProduct product1 = factory.getProduct(1);
AbstractProduct product2 = factory.getProduct(2);
}
}
//抽象产品类
abstract class AbstractProduct {
public AbstractProduct() {
//在调用构造器的时候调用抽象方法
sayHello();
}
abstract void sayHello();
}
//A具体产品类
class ProductA extends AbstractProduct {
public ProductA() {
super();
}
@Override
public void sayHello() {
System.out.println("项目一");
}
}
//B具体产品类
class ProductB extends AbstractProduct {
public ProductB() {
super();
}
@Override
public void sayHello() {
System.out.println("项目二");
}
}
优点
- 客户端通过使用一个工厂类,在其中以某种选择的方式,将某产品具体实例化,然后返回对应产品。
- 对象的创建与使用分离,无需知道产品相关细节。
缺点
- 工厂类笨重,依旧需要修改工厂类的判断逻辑代码。
- 如要增加新产品需要更改工厂类,违背开闭原则。
- 单一分类,如果产品也有分类那么将不适用。
工厂方法模式(Factory Method)
UML
代码
//工厂的抽象类
public abstract class FactoryMethodPattern {
abstract FactoryMethodAbstractProduct getProduct();
public static void main(String[] args) {
FactoryMethodPattern aFactory = new AFactory();
FactoryMethodPattern bFactory = new BFactory();
FactoryMethodAbstractProduct productA = aFactory.getProduct();
FactoryMethodAbstractProduct productB = bFactory.getProduct();
}
}
//工厂的实现类,每个工厂对应着一个产品
//也可以结合简单工厂,将每个子工厂作为一个简单工厂,使用参数分割工厂制造过程
class AFactory extends FactoryMethodPattern {
@Override
public FactoryMethodAbstractProduct getProduct() {
return new FactoryMethodProductA();
}
}
class BFactory extends FactoryMethodPattern {
@Override
public FactoryMethodAbstractProduct getProduct() {
return new FactoryMethodProductB();
}
}
//抽象产品类
abstract class FactoryMethodAbstractProduct {
public FactoryMethodAbstractProduct() {
sayHello();
}
abstract void sayHello();
}
class FactoryMethodProductA extends FactoryMethodAbstractProduct {
public FactoryMethodProductA() {
super();
}
@Override
public void sayHello() {
System.out.println("项目一");
}
}
class FactoryMethodProductB extends FactoryMethodAbstractProduct {
public FactoryMethodProductB() {
super();
}
@Override
public void sayHello() {
System.out.println("项目二");
}
}
优点
- 遵循了开闭原则,扩展性强。
- 屏蔽产品的具体实现,调用者只关心产品的接口。
- 拓展时无需改变原有代码,可维护性高。仅需创建新产品、创建对应工厂。
缺点
- 如果有较多的产品就会产生大量的类。难以维护
抽象工厂模式(Abstract Factory)
UML
代码
下述代码较多。简述如下
- 两类产品
- 1类
- 2类
- 每类产品两个型号
- A型
- B型
- 每类产品对应一个工厂类
- 每个工厂类中两个方法分别对应两个型号
public abstract class AbstractFactoryPattern {
abstract AbstractFactoryAbstractProduct1 getProduct1();
abstract AbstractFactoryAbstractProduct2 getProduct2();
public static void main(String[] args) {
AbstractFactoryPattern aFactory = new AAbstractFactory();
AbstractFactoryPattern bFactory = new BAbstractFactory();
AbstractFactoryAbstractProduct1 product1A = aFactory.getProduct1();
AbstractFactoryAbstractProduct1 product1B = bFactory.getProduct1();
AbstractFactoryAbstractProduct2 product2A = aFactory.getProduct2();
AbstractFactoryAbstractProduct2 product2B = bFactory.getProduct2();
}
}
class AAbstractFactory extends AbstractFactoryPattern {
@Override
public AbstractFactoryAbstractProduct1 getProduct1() {
return new AbstractFactoryAbstractProduct1A();
}
@Override
public AbstractFactoryAbstractProduct2 getProduct2() {
return new AbstractFactoryAbstractProduct2A();
}
}
class BAbstractFactory extends AbstractFactoryPattern {
@Override
public AbstractFactoryAbstractProduct1 getProduct1() {
return new AbstractFactoryAbstractProduct1B();
}
@Override
public AbstractFactoryAbstractProduct2 getProduct2() {
return new AbstractFactoryAbstractProduct2B();
}
}
//抽象产品类
abstract class AbstractFactoryAbstractProduct1 {
public AbstractFactoryAbstractProduct1() {
sayHello();
}
abstract void sayHello();
}
class AbstractFactoryAbstractProduct1A extends AbstractFactoryAbstractProduct1 {
public AbstractFactoryAbstractProduct1A() {
super();
}
@Override
public void sayHello() {
System.out.println("项目1A");
}
}
class AbstractFactoryAbstractProduct1B extends AbstractFactoryAbstractProduct1 {
public AbstractFactoryAbstractProduct1B() {
super();
}
@Override
public void sayHello() {
System.out.println("项目1B");
}
}
//抽象产品类
abstract class AbstractFactoryAbstractProduct2 {
public AbstractFactoryAbstractProduct2() {
sayHello();
}
abstract void sayHello();
}
class AbstractFactoryAbstractProduct2A extends AbstractFactoryAbstractProduct2 {
public AbstractFactoryAbstractProduct2A() {
super();
}
@Override
public void sayHello() {
System.out.println("项目2A");
}
}
class AbstractFactoryAbstractProduct2B extends AbstractFactoryAbstractProduct2 {
public AbstractFactoryAbstractProduct2B() {
super();
}
@Override
public void sayHello() {
System.out.println("项目2B");
}
}
优点
- 符合开闭原则。
- 抽象工厂模式只有在一类产品时才需要新增工厂。
- 工厂创建产品的个数介于简单工厂模式和工厂方法模式之间。
缺点
- 结构需要提前构思,抽象工厂类的设计需要考虑未来产品的型号。
优点
- 符合开闭原则。
- 抽象工厂模式只有在一类产品时才需要新增工厂。
- 工厂创建产品的个数介于简单工厂模式和工厂方法模式之间。
缺点
- 结构需要提前构思,抽象工厂类的设计需要考虑未来产品的型号。
- 一旦进行型号的修改,就需要关联诸多相关工厂的实现。
uml图取自此处