Java 设计模式之工厂模式
一、简介
工厂模式为创建型模式,在创建对象时,不会向客户端暴露对象的创建逻辑,通过使用一个共同的接口或抽象类来指向新创建的对象。
在日常开发中,工厂模式分为三种:简单工厂模式、工厂方法模式、抽象工厂模式。
二、简单工厂模式
简单工厂模式又称静态工厂方法模式,由一个专门的工厂类来创建具体的实例。作用是将类的实例化与使用者分开,使用者不需要关心类是如何创建的,在一定程度上实现了解耦。
主要角色:
工厂: 负责创建所需实例,提供一个供外部使用的方法来获取具体产品。
抽象产品:负责描述产品的抽象类或接口。
具体产品:我们所需要的具体产品(类实例)
举例:
比如有 一汽大众汽车厂(工厂),可以生产不同类型的汽车(抽象产品),比如宝来和速腾(具体产品),这时候可以通过汽车厂来获取想要的具体车型。
抽象产品:
//抽象产品,描述汽车信息 abstract class Car { abstract String carInfo(); } 具体产品(宝来): public class Bora extends Car{ @Override String carInfo() { return "我是宝来汽车"; } }
具体产品(速腾):
public class Sagitar extends Car{ @Override String carInfo() { return "我是速腾汽车"; } }
工厂:
public class CarFactory{ public static Car getCar(String carType){ switch (carType){ case "bora": return new Bora(); case "sagitar": return new Sagitar(); default: return null; } } }
使用:
public static void main(String[] args) { Car car = CarFactory.getCar("bora"); }
这样一个简单工厂模式就完成了,简单理解就是说工厂类通过抽象产品类来创建出具体的产品,调用者无需知道具体产品是如何创建出来的。
优点:类的使用和创建分开,在一定程度上解耦。
缺点:当需要添加一个产品时,还需要修改工厂类,违反开闭原则。
三、 工厂方法模式
工厂方法模式相比上面的简单工厂多了抽象工厂,将产品的创建延迟到抽象工厂的子类(具体工厂)。
主要角色:
抽象工厂: 提供创建产品的接口,由子类(具体工厂)来创建具体的产品。
具体工厂:实现抽象工厂的方法,来创建具体产品。
抽象产品:负责描述产品的抽象类或接口。
具体产品:我们所需要的具体产品(类实例)
举例:
比如有 一汽大众汽车厂(抽象工厂),他有两个生产线,宝来生产线(具体工厂)和速腾生产线(具体工厂),通过这两个生产线来生产具体的产品(宝来,速腾)。
抽象产品:
//抽象产品,描述汽车信息 abstract class Car { abstract void carInfo(); }
具体产品(宝来):
public class Bora extends Car{ @Override String carInfo() { return "我是宝来汽车"; } }
具体产品(速腾):
public class Sagitar extends Car{ @Override String carInfo() { return "我是速腾汽车"; } }
抽象工厂:
abstract class CarFactory{ abstract Car getCar(); }
具体工厂(宝来生产线):
public class BoraFactory extends CarFactory{ //具体工厂继承抽象工厂 @Override Car getCar() { return new Bora(); } }
具体工厂(速腾生产线):
public class SagitarFactory extends CarFactory{ @Override Car getCar() { return new Sagitar(); } }
使用:
public static void main(String[] args) { CarFactory boraFactory = new BoraFactory(); //通过具体工厂获取实例 Car car = boraFactory.getCar(); }
工厂方法模式比简单工厂模式的优点就是符合开闭原则,如果新增一款产品,只需要创建新的具体工厂即可,缺点是:一个具体工厂只能创建一个具体产品,每增加一款产品都要新增一个类,导致类爆炸。
四、抽象工厂模式
是一种为访问类提供一个 创建一组相关 或 相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同产品不同等级的产品的结构。
抽象工厂模式是工厂方法的升级版本,工厂方法只能生产同一种等级的产品,而抽象工厂模式可以生产多个等级的产品。
主要角色:
抽象工厂: 提供创建产品的接口,包含多个创建产品的方法,可以创建多个不同等级的产品。
具体工厂:实现抽象工厂多个抽象方法,来创建具体产品。
抽象产品:负责描述产品的抽象类或接口。
具体产品:我们所需要的具体产品(类实例)
举例:
我们有一个总的汽车厂(抽象工厂),通过它生产A级车和B级车。同时还有一汽大众和上汽大众(具体工厂)来创建具体的产品,比如一起大众有A级车宝来,B级别车迈腾,上汽大众有A级车朗逸,B级车帕萨特,所以我们需要如下几个类。
抽象产品:
//A级车抽象类 public class ACar{ abstract String carInfo(); } //B级车抽象类 public class BCar{ abstract String carInfo(); }
具体产品:
//一汽大众 A级车宝来 public class Bora extends ACar{ @Override String carInfo() { return "我是A级车 一汽大众宝来"; } } //上汽大众 A级车朗逸 public class Lavida extends ACar{ @Override String carInfo() { return "我是A级车 上汽大众朗逸"; } } //一汽大众 B级车迈腾 public class Magotan extends BCar{ @Override String carInfo() { return "我是B级车 一汽大众迈腾"; } } //上汽大众 B级车迈腾 public class Passat extends BCar{ @Override String carInfo() { return "我是B级车 上汽大众帕萨特"; } }
抽象工厂:
//车厂 public abstract class CarFactory{ abstract ACar createACar(); abstract BCar createBCar(); }
具体工厂:
//一汽大众工厂 public class YiQiFactory extends CarFactory{ @Override ACar createACar() { return new Bora(); } @Override BCar createBCar() { return new Magotan(); } } //上汽大众工厂 public class ShangQiFactory extends CarFactory{ @Override ACar createACar() { return new Lavida(); } @Override BCar createBCar() { return new Passat(); } }
使用:
比如说我们看车的时候想看一汽大众的A级车或者B级车。
public static void main(String[] args) { //获取一汽大众工厂 YiQiFactory yiQiFactory = new YiQiFactory(); //获取一汽大众的A级车和B级车 ACar aCar = yiQiFactory.createACar(); BCar bCar = yiQiFactory.createBCar(); }
又比如我想去上汽大众看看。
public static void main(String[] args) { //获取上汽大众工厂 ShangQiFactory shangQiFactory = new ShangQiFactory(); //获取上汽大众的A级车和B级车 ACar aCar = shangQiFactory.createACar(); BCar bCar = shangQiFactory.createBCar(); }
抽象工厂类(车厂)衍生出多个具体工厂(一汽/上汽)。多个抽象产品类(A/B级车),衍生出多个具体产品,宝来朗逸迈腾帕萨特。再通过具体工厂创建多个界别的产品,通过上面的例子我们可以理解为:抽象工厂模式就是创建同一个品牌,不同级别的产品。
优点:低耦合,符合开闭原则,单一职责原则,
缺点:不易扩展,当新增了一个新的产品时,工厂类也需要进行修改。