抽象工厂模式相对于工厂方法模式来说,就是工厂方法模式是针对一个产品系列的,而抽象工厂模式是针对多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类。在抽象工厂模式中,客户端不再负责对象的创建,而是把这个责任丢给了具体的工厂类,客户端只负责对对象的调用,从而明确了各个类的职责。并且当一系列相互关联的产品被设计到一个工厂类里后,客户端的调用将会变得非常简单,而且,如果要更换这一系列的产品,则只需要更换一个工厂类即可。
如果客户端需要创建一些产品结构,而这些产品结构又分别属于不同的产品类别,则可以使用抽象工厂模式,抽象工厂模式中抽象工厂类负责定义创建对象的接口,具体这一系列对象的创建工作由实现抽象工厂的具体工厂类来完成。
package com.strife.pattern.factory;
/**
* 抽象工厂
*
* @author mengzhenghao
* @date 2022/5/28
*/
public class AbstractFactory {
public static void main(String[] args) throws Exception {
CarProductFactory factory = new ChinaCarFactory();
factory.getCar("hq");
factory.getCar("df");
factory = new GermanyCarFactory();
factory.getCar("ad");
factory.getCar("bm");
}
}
/** 抽象工厂 */
interface CarProductFactory {
/** 生产汽车 */
AbstractCarProduct getCar(String type) throws Exception;
}
/** 中国汽车工厂 */
class ChinaCarFactory implements CarProductFactory {
@Override
public AbstractCarProduct getCar(String type) throws Exception {
AbstractCarProduct product = null;
for (ChinaCarEnumType carEnumType : ChinaCarEnumType.values()) {
if (type.equals(carEnumType.getCarType())) {
product = (AbstractCarProduct) Class.forName(carEnumType.getClazz()).newInstance();
product.name = carEnumType.getCarName();
product.material();
product.origin();
break;
}
}
if (product == null) {
throw new RuntimeException("暂时不能生产该汽车");
}
return product;
}
}
/** 德国汽车工厂 */
class GermanyCarFactory implements CarProductFactory {
@Override
public AbstractCarProduct getCar(String type) throws Exception {
AbstractCarProduct product = null;
for (GermanyCarEnumType carEnumType : GermanyCarEnumType.values()) {
if (type.equals(carEnumType.getCarType())) {
product = (AbstractCarProduct) Class.forName(carEnumType.getClazz()).newInstance();
product.name = carEnumType.getCarName();
product.material();
product.origin();
break;
}
}
if (product == null) {
throw new RuntimeException("暂时不能生产该汽车");
}
return product;
}
}
/** 汽车生产抽象类 */
abstract class AbstractCarProduct {
/** 汽车名称 */
protected String name ;
/** 材料 */
abstract void material() ;
/** 产地 */
abstract void origin() ;
}
/** 红旗车 */
class HQCar extends AbstractCarProduct {
@Override
void material() {
System.out.println(super.name+"材料...");
}
@Override
void origin() {
System.out.println(super.name+"在中国北京生产");
}
}
/** 东风车 */
class DFCar extends AbstractCarProduct {
@Override
void material() {
System.out.println(super.name+"材料...");
}
@Override
void origin() {
System.out.println(super.name+"在中国南京生产");
}
}
/** 奥迪车 */
class ADCar extends AbstractCarProduct {
@Override
void material() {
System.out.println(super.name+"材料...");
}
@Override
void origin() {
System.out.println(super.name+"在德国柏林生产");
}
}
/** 宝马车 */
class BMCar extends AbstractCarProduct {
@Override
void material() {
System.out.println(super.name+"材料...");
}
@Override
void origin() {
System.out.println(super.name+"在德国慕尼黑生产");
}
}
enum ChinaCarEnumType {
/** 红旗车 */
HQ("hq", "红旗", "com.strife.pattern.factory.HQCar"),
/** 东风车 */
DF("df", "东风", "com.strife.pattern.factory.DFCar");
private final String carType;
private final String carName;
private final String clazz;
ChinaCarEnumType(String carType, String carName, String clazz) {
this.carType = carType;
this.carName = carName;
this.clazz = clazz;
}
public String getCarType() {
return carType;
}
public String getCarName() {
return carName;
}
public String getClazz() {
return clazz;
}
}
enum GermanyCarEnumType {
/** 奥迪车 */
AD("ad", "奥迪", "com.strife.pattern.factory.ADCar"),
/** 宝马车 */
BM("bm", "宝马", "com.strife.pattern.factory.BMCar");
private final String carType;
private final String carName;
private final String clazz;
GermanyCarEnumType(String carType, String carName, String clazz) {
this.carType = carType;
this.carName = carName;
this.clazz = clazz;
}
public String getCarType() {
return carType;
}
public String getCarName() {
return carName;
}
public String getClazz() {
return clazz;
}
}