工厂模式
基本概念
工厂顾名思义就是可以创建不同产品,该模式用于封装和管理对象的创建,是一种创建型模式。
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
1. 简单工厂模式
创建生产汽车的接口
public interface Car {
void make();
}
生产奔驰和生产宝马
class BenChiCar implements Car{
@Override
public void make() {
System.out.println("奔驰");
}
}
class BaoMaCar implements Car{
@Override
public void make() {
System.out.println("宝马");
}
}
创建简单工厂类
class CarFactory{
public static Car makeCar(String carType) {
if(carType.equalsIgnoreCase("benchi")){
return new BenChiCar();
}
else if(carType.equalsIgnoreCase("baoma")) {
return new BaoMaCar();
}
return null;
}
}
使用简单工厂类创建对象
public void test(){
Car benchi = CarFactory.makeCar("benchi");
Car baoma = CarFactory.makeCar("baoma");
}
因为工厂类中的makeCar方法是静态的,所以也被称为静态工厂。
缺点:
如果要生产新车,比如特斯拉,那么需要对工厂中的代码进行修改。
2. 工厂方法模式
和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂,也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。
创建抽象工厂类
interface AbstractFactory {
public Car makeCar();
}
创建生产奔驰的工厂和创建生产宝马的工厂
class BenchiFactory implements AbstractFactory{
@Override
public Car makeCar() {
return new BenChiCar();
}
}
class BaoMaFactory implements AbstractFactory{
@Override
public Car makeCar() {
return new BaoMaCar();
}
}
利用工厂生产汽车
public void test(){
BenchiFactory benchiFactory= new BenchiFactory();
BaoMaFactory baoMaFactory=new BaoMaFactory();
Car benchi=baoMaFactory.makeCar();
Car baoma = baoMaFactory.makeCar();
}
3. 抽象工厂模式
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。
在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。我们依然拿生产汽车的例子来说明他们之间的区别。
现在工厂除了生产汽车之外,也要生产手机。因此定义手机的接口
interface Bike{
void make();
}
生产奔驰和宝马的自行车
class BenChiBike implements Bike{
@Override
public void make() {
System.out.println("奔驰自行车");
}
}
class BaoMaBike implements Bike{
@Override
public void make() {
System.out.println("宝马自行车");
}
}
定义抽象工厂类
interface AbstractFactory {
Car makeCar();
Bike makeBike();
}
创建奔驰工厂和宝马工厂
class BenchiFactory implements AbstractFactory{
@Override
public Car makeCar() {
return new BenChiCar();
}
@Override
public Bike makeBike() {
return new BenChiBike();
}
}
class BaoMaFactory implements AbstractFactory{
@Override
public Car makeCar() {
return new BaoMaCar();
}
@Override
public Bike makeBike() {
return new BaoMaBike();
}
}
使用工厂类分别创建自行车和车
public void test(){
BenchiFactory benchiFactory= new BenchiFactory();
BaoMaFactory baoMaFactory=new BaoMaFactory();
Car baomacar=baoMaFactory.makeCar();
Bike baomabike=baoMaFactory.makeBike();
Car benchicar = benchiFactory.makeCar();
Bike benchibike = benchiFactory.makeBike();
}
抽象工厂模式的优点: 抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。
抽象工厂模式的缺点: 产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
4. 拓展——动态工厂
简单工厂模式的缺点就是随着生产Car的增多,需要不断修改代码。如果新加入个特斯拉的话那么需要对工厂类的代码进行修改。为了解决这种问题,利用反射来实现动态工厂。
编写工厂类
class Factory{
private Factory(){}
public static Car getCar(String car_name){
Car car=null;
try {
car=(Car)Class.forName(car_name).getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return car;
}
}
利用动态工厂生产宝马车和奔驰车
public void test(){
Car benchicar = Factory.getCar("包名.BenChiCar");
Car baomacar = Factory.getCar("包名.BaoMaCar");
}
动态工厂拓展
如果该工厂不仅要生产汽车,还要生产自行车,那么如何进行修改呢?比较笨的方法是在动态工厂类中在加一个getBike的方法。但这有个问题就是如果不断产生新业务就需要不断修改代码。
解决方案:将要返回的接口类型作为参数传入方法。
class Factory{
private Factory(){}
public static <T>T getInstance(String name,Class<T> clazz){
T instance=null;
try {
instance=(T)Class.forName(name).getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return instance;
}
}
获取自行车和汽车
public void test(){
Car benchicar = Factory.getInstance("包名.BenChiCar",Car.class);
Car baomacar = Factory.getInstance("包名.BaoMaCar",Car.class);
Bike benchibike=Factory.getInstance("包名.BenChiBike",Bike.class);
Bike baomabike=Factory.getInstance("包名.BaoMaBike",Bike.class);
}
JAVA中的使用
Calendar类用到了工厂类,用到的是简单工厂模式。