工厂模式简介
在Java中要得到一个对象最简单的办法就是直接new一个对象,比如:
A a = new A();
那么需要在10个类中用到,我们就要在这10个不同的类中new A(),如果有一天因为某些原因需要将A类名改为B,那么我们就需要在这10个类中一一去改,这样麻烦又容易出错。这个时候就可以用到工厂模式,其实它就是对new A()再做了一层封装,只需要调用工厂模式提供的方法去得到对象,具体的new 操作放到了背后。
工厂模式的简单实现
这里模拟一个汽车工厂生产不同汽车的过程。
1、创建一个接口,描述工厂创建汽车的核心功能
public interface Car {
void makeCar();
}
2、创建几个不同的汽车类型,在java中就是几个类,下面分别创建RedCar、BlackCar、WhiteCar。
RedCar
public class RedCar implements Car {
@Override
public void makeCar() {
System.out.println("生产了一辆红色汽车");
}
}
BlackCar
public class BlackCar implements Car{
@Override
public void makeCar() {
System.out.println("生产了一辆黑色汽车");
}
}
WhiteCar
public class WhiteCar implements Car{
@Override
public void makeCar() {
System.out.println("生产了一辆白色汽车");
}
}
3、在决定好要创建哪几种类型的汽车之后就是创建生产汽车的工厂,CarFactory。
//创建工厂
public static class CarFactory {
//获取生产汽车的类型
public Car getCarType(String type) {
if (type == null) {
return null;
}
if (type.equals("redcar")) {
return new RedCar();
}else if (type.equals("blackcar")) {
return new BlackCar();
}else if (type.equals("whitecar")) {
return new WhiteCar();
}
return null;
}
}
4、具体的生产过程,根据需要生产出不同的汽车。
//得到工厂对象
CarFactory carFactory = new CarFactory();
//生产红色汽车
RedCar redCar = (RedCar) carFactory.getCarType("redcar");
redCar.makeCar();
//生产黑色汽车
BlackCar blackCar = (BlackCar) carFactory.getCarType("blackcar");
blackCar.makeCar();
//生产白色汽车
WhiteCar whiteCar = (WhiteCar) carFactory.getCarType("whitecar");
whiteCar.makeCar();
打印结果:
生产了一辆红色汽车
生产了一辆黑色汽车
生产了一辆白色汽车
到这里一个简单的工厂模式就实现了,它的好处正如开头说的不需要每次都去new。但看前面的也发现一个问题,如果还需要一辆绿色的车我们就需要创建一个对应的GreenCar类,然后还要创建GreenCar对象。
优化
前面提到的问题,可以通过java的反射去解决。优化后CarFactory的代码:
public static class CarFactory {
//获取生产汽车的类型,这里传入的是类
public Object getCarType(Class<?extends Car> class1) {
Object object = null;
try {
//根据传入的类名得到对象,就不需要每次去创建一个对象
object = Class.forName(class1.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}
}
总结
工厂模式抽象了对象创建的具体细节,创建的时候只需要用特定函数封装特定接口的创建细节。