在《设计模式》一书中,工厂模式叫做工厂方法模式,定义为:定义创建对象的接口,让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到其子类。
使用工厂模式的情形主要有一下几种情况:
- 编译时无法准确预期要创建的对象的类
- 类想让其子类决定在运行时创建什么
简单的说,有时你会通过很多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类中不需要做任何修改,因而这是一种松耦合的设计,虽然增加了类的个数,但是便于维护。