1. 模式作用
轻松方便地构造对象实例,而不必关心构造对象实例的细节和复杂过程。
2. 分类
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
工厂模式可以分为三类:
- 1)简单工厂模式(Simple Factory) (又称静态工厂模式)
- 2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
也有将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
3. 简单工厂模式
角色:
- 抽象产品角色:多个产品的接口或(抽象类),方便工厂类返回结果。
- 具体产品角色
- 抽象工厂模式
例如生成多种型号的宝马车,普通的方式我们每次都new车的对象,如下:
public class BMW320 {
...
}
public class BMW523 {
...
}
public class Customer {
public static void main(String[] args) {
BMW320 bmw320 = new BMW320();
BMW523 bmw523 = new BMW523();
}
}
简单工厂实现
抽象产品及具体产品
abstract class BMW {
public BMW(){
}
}
public class BMW320 extends BMW {
public BMW320() {
System.out.println("制造-->BMW320");
}
}
public class BMW523 extends BMW{
public BMW523(){
System.out.println("制造-->BMW523");
}
}
抽象工厂
public class Factory {
public BMW createBMW(int type) {
switch (type) {
case 320:
return new BMW320();
case 523:
return new BMW523();
default:
break;
}
return null;
}
}
//用if也是一样效果
在需要类的时候,直接实例化工厂,调用工厂带参数的方法来获取对象。如:
Factory factory = new Factory();
BMW bmw320 = factory.createBMW(320);
BMW bmw523 = factory.createBMW(523);
4. 工厂方法模式
当生产的产品增多时,在简单工厂模式下,每次得在工厂中增加生产产品的代码,由于是一个工厂生产。不符合设计的解耦要求。引入工厂方法模式可解决这类问题。
工厂方法模式中,将工厂抽象出来。
角色
- 工厂接口:与调用者直接交互用来提供产品,可以是接口或抽象类。
- 工厂实现:决定如何实例化产品。有多少产品,就有多少工厂实现。
- 产品接口
- 产品实现
注:简单工厂模式中只有三要素,没有工厂接口。一般获得产品的方法是静态的。工厂的扩展性弱。
工厂方法实现
//1.工厂接口
public interface IFactory{
public IProduct createProduct();
}
//2.工厂实现
public class Factory implements IFactory{
@override
public IProduct createProduct(){
//work...
}
}
//3.产品接口
inteface IProduct {
public void productMethod();
}
//4.产品实现
public class Product implements IProduct{
@override
public void productMethod(){
//...
}
}
举例:
产品类(产品接口一个,为了同一产品;产品实现多个,每个产品都有产品实现类)
//产品接口
abstract class BMW {
public BMW(){
}
}
//多个产品实现
public class BMW320 extends BMW {
public BMW320() {
System.out.println("制造-->BMW320");
}
}
public class BMW523 extends BMW{
public BMW523(){
System.out.println("制造-->BMW523");
}
}
工厂类(工厂接口一个,统一工厂;工厂实现类多个,有多少产品就要多少工厂实现)
//工厂接口
interface FactoryBMW {
BMW createBMW();
}
//多个工厂实现,有几个产品就有几个工厂实现
public class FactoryBMW320 implements FactoryBMW{
@Override
public BMW320 createBMW() {
return new BMW320();
}
}
public class FactoryBMW523 implements FactoryBMW {
@Override
public BMW523 createBMW() {
return new BMW523();
}
}
用户使用:
public class Customer {
public static void main(String[] args) {
//创建特定的工厂实现
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
//用工厂的方法来生产对象
BMW320 bmw320 = factoryBMW320.createBMW();
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
BMW523 bmw523 = factoryBMW523.createBMW();
}
}
组装汽车的例子能很好解释工厂方法模式,当创建汽车对象需要创建车轮
、引擎
等时,这个过程我们将其放在工厂方法中实现,我们只需要调用工厂方法即可创建汽车对象。
工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口,但使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。
5. 抽象工厂模式
当为创建一组相关或者相互依赖的对象。
说明:当工厂创建产品时,需要调用多个方法来创建一个产品。这时,工厂方法模式就升级为抽象工厂模式。
产品类
//发动机以及型号
public interface Engine {
}
public class EngineA extends Engine{
public EngineA(){
System.out.println("制造-->EngineA");
}
}
public class EngineBextends Engine{
public EngineB(){
System.out.println("制造-->EngineB");
}
}
//空调以及型号
public interface Aircondition {
}
public class AirconditionA extends Aircondition{
public AirconditionA(){
System.out.println("制造-->AirconditionA");
}
}
public class AirconditionB extends Aircondition{
public AirconditionB(){
System.out.println("制造-->AirconditionB");
}
}
工厂类
//创建工厂的接口
public interface AbstractFactory {
//制造发动机
public Engine createEngine();
//制造空调
public Aircondition createAircondition();
}
//为宝马320系列生产配件
public class FactoryBMW320 implements AbstractFactory{
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Aircondition createAircondition() {
return new AirconditionA();
}
}
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
客户
public class Customer {
public static void main(String[] args){
//生产宝马320系列配件
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
//生产宝马523系列配件
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
}
}
6. 工厂模式的小结
主程序从产品接口的具体类中解耦出来,而且程序调用者无须关心产品的实例化过程,主程序仅仅与工厂服务定位结合在一起,可获得所有工厂能产生的实例。
具体类的变化,接口无须发生任何改变,调用者程序代码部分也无须发生任何改动。(用接口的类型接收,多态)
PersonFactory pf = new PersonFactory();
//定义接口Person实例,面向接口编程
Person p = null; //Person是产品的接口,不管是Chinese还是其他人,都用Person接收
//使用工厂获得person实例
p = pf.getPerson("chin");