一、前言
类型:创建型模式
作用:工厂模式主要是为创建对象提供接口,将创建对象的过程隔离起来,实现了创建者与调用者的分离,提高了程序的灵活性;
核心本质:
实例化对象,用工厂方法代替new操作;
将选择实现类、创建对象统一管理和控制,从而将调用者跟我们实现类解耦;
工厂模式分类:
简单工厂模式(Simple Factory)(又称:静态工厂方法模式)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory),将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类;
二、简单(静态)工厂
2-1、介绍
简单工厂是由一个工厂(注意:是一个!)对象决定创建出哪一种产品类的实例,
实现方式的实质:工厂类根据传入的参数,动态的决定应该创建哪一个产品类(这些产品继承一个父类或接口)的实例
2-2 实例引入
背景:有一个手机生产工厂,能生产多种手机
1)先定义一个抽象手机类:
package com.creational.factory.simple;
//类说明:抽象手机类
public abstract class AbstractMobile {
}
2)定义具体的手机:华为手机
package com.creational.factory.simple;
public class HuaweiMobile extends AbstractMobile{
}
3)定义具体的手机:小米手机
package com.creational.factory.simple;
public class XiaomiMobile extends AbstractMobile{
}
4)定义一个工厂:
package com.creational.factory.simple;
public class MobileFactory {
//静态工厂方法
public static AbstractMobile product(int type) {
AbstractMobile mobile = null;
switch (type) {
case 1:
mobile = new HuaweiMobile();
System.out.println(“hello,欢迎使用华为手机!”);
break;
default:
mobile = new XiaomiMobile();
System.out.println(“hello,欢迎使用小米手机!”);
break;
}
return mobile;
}
}
5)测试
package com.creational.factory;
import com.creational.factory.simple.MobileFactory;
public class SimpleFactoryTest {
public static void main(String[] args) {
//客户要订购生产华为手机
MobileFactory.product(1);
//客户要订购生产小米手机
MobileFactory.product(2);
}
}
2-3、问题
一个工厂类集中了所有实例的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
违背了“开-闭原则”,一旦新加产品不得不修改工厂类的逻辑,这样会造成工厂逻辑过于复杂,对于系统维护和扩展不够友好;
简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成新加工厂角色,就需要修改工厂方法
2-4、应用场景
1)工厂类负责创建的对象比较少,不会造成工厂方法中业务逻辑太过复杂
2)客户端只需要传入参数,不需要关心如何创建对象
3)鉴于该模式的扩展性太差,因此一般只在很简单的情况下应用
三、工厂方法模式
3-1、介绍
定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到子类
抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口;
3-2、实例引入
1)定义一个抽象的手机类:
package com.creational.factory.method;
public abstract class AbstractMobile {
}
2)定义一个具体的手机类-华为手机:
package com.creational.factory.method;
public class HuaweiMobile extends AbstractMobile{
}
3)定义一个具体的手机类-小米手机:
package com.creational.factory.method;
public class XiaomiMobile extends AbstractMobile{
}
4)定义一个抽象工厂:
package com.creational.factory.method;
public abstract interface MobileFactory {
public abstract AbstractMobile product();
}
}
5)定义一个具体的工厂类–华为工厂:
package com.creational.factory.method;
public class HuaweiFactory implements MobileFactory{
@Override
public AbstractMobile product() {
System.out.println(“生产华为手机.”);
return new HuaweiMobile();
}
}
6)定义一个具体的工厂类–小米工厂:
package com.creational.factory.method;
public class XiaomiFactory implements MobileFactory{
@Override
public AbstractMobile product() {
System.out.println(“生产小米手机.”);
return new XiaomiMobile();
}
}
7)测试类:
public class FactoryMethodTest {
public static void main(String[] args) {
MobileFactory factory = null;
factory = new HuaweiFactory();
factory.product();
factory = new XiaomiFactory();
factory.product();
}
}
3-3、问题:
1)添加新产品时,除了增加新产品类之外,还要增加与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度,同时有更多的类需要编译和运行,会给系统带来一些额外的开销;
2)考虑到可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统实现的难度
3)目前一个具体工厂只能创建一种具体产品,如果工厂需要新生产另一种产品,仍然需要修改实例化的具体工厂类
四、抽象工厂模式
4-1、介绍