设计模式(五)——工厂方法模式
工厂方法模式(Factory Method Pattern)其定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法模式的优点
1. 工厂方法模式可以降低模块间的耦合性,使用工厂方法模式创建一个对象,不再需要知道创建该对象的艰辛过程和必要信息,只需要提供一个产品的约束条件(例如,类名或约束字符串)就可以获取需要的对象。
2. 工厂方法有良好的扩展性。
3. 屏蔽了产品类,调用者只需要关系产品类的接口。因为产品类的具体对象实例是由工厂产生的。
假设如下场景:
有一个汽车工厂,老板想要生产各种类型汽车,他不想管你们怎么生产,他只给工厂工作人员一个汽车图纸,说,我要这个类型的汽车,然后就可以生产出来,注意工厂还是原来的工厂,不可能说新来一种类型的汽车我就新建一个工厂,那我们的实现方式如下:
首先定义一个汽车的接口:
package com.gy.designpattern.factorymethod;
/**
* ClassName:Car <br/>
* Function: 定义一个汽车的公共接口. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-4 下午2:04:52 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public interface Car {
public void run();
}
然后定义两种类型的汽车:
package com.gy.designpattern.factorymethod;
/**
* ClassName:AudiCar <br/>
* Function: 奥迪汽车模型. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-4 下午2:07:13 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public class AudiCar implements Car{
/**
*奥迪可以跑.
* @see com.gy.designpattern.factorymethod.Car#run()
*/
@Override
public void run(){
System.out.println("奥迪在跑!");
}
}
package com.gy.designpattern.factorymethod;
/**
* ClassName:BenzCar <br/>
* Function: 奔驰汽车模型 <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-4 下午2:09:00 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public class BenzCar implements Car{
/**
* 奔驰可以跑.
* @see com.gy.designpattern.factorymethod.Car#run()
*/
@Override
public void run(){
System.out.println("奔驰在跑!");
}
}
然后我们定义个汽车生产工厂:
package com.gy.designpattern.factorymethod;
import java.util.List;
import java.util.Random;
import com.gy.designpattern.util.ClassUtils;
/**
* ClassName:CarFactory <br/>
* Function: 汽车生产工厂. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-4 下午2:10:29 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public class CarFactory {
/**
* createCar:定义一个汽车生产车间,只要我们把汽车类型传进去就可以产生这类汽车. <br/>
* @author gongyong
* @param c
* @return
* @since JDK 1.6
*/
public static Car createCar(Class c){
Car car=null;
try{
car =(Car)Class.forName(c.getName()).newInstance();
}catch(Exception e){
}
return car;
}
/**
* createCar:这个方法就强大了,可以随机创建所有实现了car接口的各种CAR. <br/>
* 这个不是必须的,是我为了偷懒改进的一个方法
* @author gongyong
* @return
* @since JDK 1.6
*/
public static Car createCar(){
Car car=null;
//获得实现了car接口的各种car类型,ClassUtils是一个自己写的工具类
List<Class> concreteCarList=ClassUtils.getAllClassByInterface(Car.class);
Random random=new Random();
int rand=random.nextInt(concreteCarList.size());
car=createCar(concreteCarList.get(rand));
return car;
}
}
我们注意到上面用到了一个ClassUtils,这个类是我自己实现的一个工具类,网上类似的例子很多,这里我不写出来了,有兴趣可以自己写一个,有需要给我留言,嘿嘿。
最后,工厂建好了,老板说,开工:
package com.gy.designpattern.factorymethod;
/**
* ClassName:Boss <br/>
* Function: Boss说要生产哪种汽车就生产哪种. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-4 下午2:16:48 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public class Boss {
public static void main(String[] args){
//老板说生产奔驰车
Car benzCar=CarFactory.createCar(BenzCar.class);
benzCar.run();
//老板说生产奥迪车
Car audiCar=CarFactory.createCar(AudiCar.class);
audiCar.run();
//老板说爱生产啥是啥,只要是汽车
for(int i=0;i<100;i++){
Car car=CarFactory.createCar();
car.run();
}
}
}
看见了吧,so easy啊,老板再也不用担心我们造汽车了~