工厂模式分为:简单工厂模式、工厂模式、抽象工厂模式。
为什么要用到工厂模式呢?因为解耦。消费端无需知道产品如何被创建,只需要告诉生产者(工厂)我要生产某样具体的产品。
简单工厂模式
上图来自百科的简单工厂UML类图,左侧紫色块是产品接口,下方是两个具体产品,产品A和产品B,右侧Creator是工厂,可以生产产品A、产品B。
下面用汽车的例子实现一下简单工厂模式
//产品接口--车
public interface Car {
//描述生产了一部车
void car();
}
//产品实现类--奥迪
public class Aodi implements Car {
@Override
public void car() {
System.out.println("生产奥迪一辆");
}
}
//产品实现类--宝马
public class Baoma implements Car {
@Override
public void car() {
System.out.println("生产宝马一辆");
}
}
//产品实现类--特斯拉
public class Tesila implements Car {
@Override
public void car() {
System.out.println("生产特斯拉一辆");
}
}
//工厂类--车厂
public class CarFactory {
//生产具体的汽车
public static Car createCar(String carname) {
Car car = null;
if(carname.equals("奥迪")) {
car = new Aodi();
}else if(carname.equals("宝马")){
car = new Baoma();
}else if(carname.equals("特斯拉")) {
car = new Tesila();
}
return car;
}
}
//消费端
public class CarCustomer {
public static void main(String[] args) {
Car car1 = CarFactory.createCar("奥迪");
car1.car();
Car car2 = CarFactory.createCar("宝马");
car2.car();
Car car3 = CarFactory.createCar("特斯拉");
car3.car();
}
}
运行结果:
上面工厂模式有三部分
产品接口:Car,相当于类图中的IProduct,接口中有一个生产车的抽象方法。
产品实现类:Aodi、Baoma、Tesila,三种具体的产品,相当于类图中的Product_A、Product_B,都实现了Car接口的生产车的方法。
工厂类:CarFactory,相当于类图中的Creator,里面有一个createCar的方法,通过传进的具体参数来生产创建具体的产品实例。这类里的createCar创建实例的方法是静态的,故简单工厂模式又可以称为静态工厂模式。
第四部分CarCustomer类是消费者,有生产者就有消费者。消费者只需要知道自己需要生产什么具体产品,根本不需要知道宝马、奥迪这些具体的产品是如何生产的,达到了解耦的作用。
假设不使用工厂模式,消费者就如下执行,该方式的消费者就需要知道奥迪、宝马、特斯拉的具体地址,然后分别跑过去跟宝马说你给我生产一辆宝马,跟奥迪的说你给我生产一辆奥迪,跟特斯拉的说你给我生产一辆特斯拉。对比上面的消费者,上方式的消费者只需要委托给工厂。
在这里插入图片描述
在我现在的公司,用的就是上述的简单工厂模式,具体的产品类有几十个,工厂类里就对应有几十个elseif。(不要误以为我公司很厉害,其实是一个小型的外包公司,在我看来,这几十个产品类是不合理的,这里就涉及到公司里的一些问题了,就不方便公开了。)
说回简单工厂模式,有个缺点,就是违背了设计原则的开闭原则(对修改关闭,对拓展开放)。
工厂模式
工厂模式,先上代码,产品接口跟具体产品不变
//工厂接口
public interface CarFactory {
//生产车量
Car createCar();
}
//奥迪工厂实现类
public class AodiFactoryImp implements CarFactory {
@Override
public Car createCar() {
return new Aodi();
}
}
//宝马工厂实现类
public class BaomaFactoryImp implements CarFactory {
@Override
public Car createCar() {
return new Baoma();
}
}
工厂模式跟简单工厂模式的区别就是工厂也提供了工厂接口,由工厂的实现类去创建具体的产品实例。假设要新增一个产品(特斯拉),只要添加一个具体的产品类,然后创建一个工厂去实现工厂接口
public class TesilaFactoryImp implements CarFactory {
@Override
public Car createCar() {
return new Tesila();
}
}
public class CarCustomer {
public static void main(String[] args) {
CarFactory car1 = new AodiFactoryImp();
car1.createCar().car();
CarFactory car2 = new BaomaFactoryImp();
car2.createCar().car();
CarFactory car3 = new TesilaFactoryImp();
car3.createCar().car();
}
}
工厂模式,解决了简单工厂模式开闭原则的缺点。
抽象工厂模式
先看上面的UML类图,右侧有两个产品接口,分别都有两个具体产品;左侧上方是工厂接口,有两个生产产品的方法,下方绿块和红块都分别实现了工厂接口的方法。
抽象工厂模式跟工厂模式的区别在于前者是两个以上的产品等级结构。怎么理解这个产品等级结构。
根据抽象工厂模式UML类图,然后我举了一个车的例子画了个草图,应该这个图比较清晰了吧,可以对照着来看看。产品等级结构指的就是汽油车产品和能源车产品,等级结构是2,还能再加个汽油能源混合产品,等级结构就变成3了。工厂模式的等级结构是1,因为它只有一个产品等级结构。
抽线工厂模式还有一个产品族的概念。产品族就是同一系列的产品,指的就是上图右侧奥迪汽油车和奥迪能源车是同一系列产品,是一个产品族;宝马汽油车和宝马能源车是同一系列车,是一个产品族,上图有两个产品族。
—产品
//产品工厂--汽油车接口
public interface OilCarProduct {
//生产一辆汽油车
void car();
}
//产品接口--能源车
public interface EnergyCarProduct {
//生产一辆能源车
void car();
}
//具体汽油车产品--奥迪
public class AodiOil implements OilCarProduct {
@Override
public void car() {
System.out.println("生产了一辆奥迪汽油车");
}
}
//具体能源车产品--奥迪
public class AodiEnergy implements EnergyCarProduct {
@Override
public void car() {
System.out.println("生产了一辆奥迪能源车");
}
}
//具体汽油车产品--宝马
public class BaomaOil implements OilCarProduct {
@Override
public void car() {
System.out.println("生产了一辆宝马汽油车");
}
}
//具体汽油车产品--宝马
public class BaomaOil implements OilCarProduct {
@Override
public void car() {
System.out.println("生产了一辆宝马汽油车");
}
}
//具体能源车产品--宝马
public class BaomaEnergy implements EnergyCarProduct {
@Override
public void car() {
System.out.println("生产了一辆宝马能源车");
}
}
-–工厂
//工厂接口
public interface CarFactory {
//生产汽油车
OilCarProduct createOilProduct();
//生产能源车
EnergyCarProduct createEnergyProduct();
}
//奥迪工厂-奥迪产品族
public class AodiFactory implements CarFactory {
@Override
public OilCarProduct createOilProduct() {
return new AodiOil();
}
@Override
public EnergyCarProduct createEnergyProduct() {
return new AodiEnergy();
}
}
//宝马工厂-宝马产品族
public class BaomaFactory implements CarFactory {
@Override
public OilCarProduct createOilProduct() {
return new BaomaOil();
}
@Override
public EnergyCarProduct createEnergyProduct() {
return new BaomaEnergy();
}
}
—消费端
//消费者
public class CarCustomer {
public static void main(String[] args) {
CarFactory car1 = new AodiFactory();
car1.createOilProduct().car();
car1.createEnergyProduct().car();
CarFactory car2 = new BaomaFactory();
car2.createOilProduct().car();
car2.createEnergyProduct().car();
}
}
运行结果
三种模式都有各自的实现场景,也不能评论那种模式的好与坏,只要经过深思熟虑,并且达到了解耦的功效,那你用的模式就是对的。
这篇工厂设计模式篇幅比较长,也花了比较多的时间,不知道大家看完有没有更清晰了呢?