在《设计模式》一书中,工厂模式叫做工厂方法模式,定义为:定义创建对象的接口,让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到其子类。
使用工厂模式的情形主要有一下几种情况:
- 编译时无法准确预期要创建的对象的类
- 类想让其子类决定在运行时创建什么
简单的说,有时你会通过很多if……else来判断类生成哪种类型的对象(大多指有相同父类的子类)
比如下面的一个方法:
public Fruit getfruit(String type){Fruit fruit = null;if(type.equals("orange")){fruit = new Orange();}else if(type.equals("apple")){fruit = new Apple();}return fruit;}
(其中Orange和Apple是Fruit的子类)
针对上述代码,工厂模式的思想就是把if……else抽取出来,通过工厂来决定创建那个子类的实例。
下面我们将为简单工厂模式编写一个例子:
package com.cnblogs.ipolaris.test;public abstract class Fruit{ public abstract void describe();}
抽象类Fruit作为Apple和Orange的父类
package com.cnblogs.ipolaris.test;public class Apple extends Fruit { @Override public void describe() { System.out.println("I'am an apple"); }}
package com.cnblogs.ipolaris.test;public class Orange extends Fruit { @Override public void describe() { System.out.println("I'am an orange"); }}
为Apple和Orange编写工厂
package com.cnblogs.ipolaris.test;public interface BaseFruitFactory { public Fruit getFruit();}
package com.cnblogs.ipolaris.test;public class AppleFactory implements BaseFruitFactory { @Override public Fruit getFruit() { // TODO Auto-generated method stub return new Apple(); }}
package com.cnblogs.ipolaris.test;public class OrangFactory implements BaseFruitFactory { @Override public Fruit getFruit() { // TODO Auto-generated method stub return new Orange(); }}
下面来测试工厂
package com.cnblogs.ipolaris.test;public class SimFactoryTest { public static void main(String[] args){ //当想得到一个苹果的时候,实例一个apple工厂,从工厂取苹果 BaseFruitFactory factory = new AppleFactory(); getfruit(factory); //当想得到一个桔子的时候,实例一个orange工厂,从工厂取桔子 factory = new OrangFactory(); getfruit(factory); } public static void getfruit(BaseFruitFactory factory){ Fruit fruit = factory.getFruit(); fruit.describe(); }}
输出为:I'am an apple
I'am an orange
当我们想创建其他的水果时,只要写一个Fruit的子类,然后为其编写一个工厂类,SimFactoryTest类中不需要做任何修改,因而这是一种松耦合的设计,虽然增加了类的个数,但是便于维护。