工厂模式

  • 一、工厂模式的作用
  • 二、简单工厂模式
  • 三、工厂方法模式
  • 四、抽象工厂模式
  • 五、总结


一、工厂模式的作用

  • 原本我们是用new来创建新对象,而现在我们用一个工厂类来代替创建新对象的工作
  • 实现创建者和调用者的分离,调用者与实现类解耦(当实现类发生改变时,调用者的代码不需要做任何改变)

二、简单工厂模式

  • 也称静态工厂模式
  • 比如我们要造汽车,可以造Tesla也可以造Vw,我们构建一个工厂类来负责汽车对象的创建

简单工厂模式结构:

Java 工厂类和普通类区别 java工厂类有什么作用_ide

//一个Car的接口
public interface Car {
	public void name();
}
//Tesla实现类
public class Tesla implements Car{
	@Override
	public void name() {
		System.out.println("Tesla");		
	}
}
//Vw实现类
public class Vw implements Car{
	@Override
	public void name() {
		System.out.println("Vw");
	}
}
//现在我们来建一个简单工厂来做创建对象的工作
public class CarFactory {
	public static Car getCar(String car)
	{
		if(car.equals("vw"))
		{
			return new Vw();
		}
		else if(car.equals("tesla"))
		{
			return new Tesla();
		}	
		return null;
	}
}
//在Consumer类中通过调用工厂创建对象
public class Consumer {
	public static void main(String[] args) {
		Car vw = CarFactory.getCar("vw"); 
		Car tesla = CarFactory.getCar("tesla");
	}
}

简单工厂模式小结:

  • 简单工厂模式的结构,代码,编程以及管理上的复杂度都较小
  • 但每次增加一个新产品必须要修改原有代码

三、工厂方法模式

  • 同样的Car接口,Vw,Tesla实现类
  • 然而现在我们要为工厂也构建一个接口,并且为每一种产品构建一个工厂实现类

工厂方法模式结构:

Java 工厂类和普通类区别 java工厂类有什么作用_System_02

//工厂接口
public interface CarFactory {
	Car getCar();
}
//Tesla工厂实现类
public class TeslaFactory implements CarFactory{
	@Override
	public Car getCar() {
		return new Tesla();
	}
}
//Vw工厂实现类
public class VwFactory implements CarFactory {
	@Override
	public Car getCar() {
		return new Vw();
	}
}
//调用各自工厂实现类来创建对象
public class Consumer {
	public static void main(String[] args) {
		Car vw = new VwFactory().getCar(); 
		Car tesla = new TeslaFactory().getCar();
	}
}

工厂方法模式小结:

  • 横向扩展,增加新产品不需要改动原有代码,但要新构建一个工厂实现类,代码量大大增加
  • 当业务变得很复杂的时候,我们可能会需要很多的工厂接口与工厂实现类,此时工厂方法模式就不再适用

四、抽象工厂模式

  • 抽象工厂是工厂的工厂
  • 抽象工厂模式提供了创建一系列相关或相互依赖对象的接口,无需指定他们具体的类

抽象工厂模式结构:

Java 工厂类和普通类区别 java工厂类有什么作用_工厂方法模式_03

  • 我们有华为和小米两家公司,每个公司都有手机和路由器两个产品
  • 华为的手机和路由器属于一个产品族;而小米的手机和路由器属于另一个产品族
  • 同一个产品族的产品将由一个工厂来生产,因此华为的产品都由华为工厂来创建,小米的产品都由小米工厂来创建
  • 而华为工厂和小米工厂都会去实现一个工厂接口,也就是我们所说的工厂的工厂
//手机接口
public interface IphoneProduct {
	void start();
}
//路由器接口
public interface IRouterProduct {
	void start();
}
//抽象产品工厂,工厂的工厂
public interface IProductFactory {
	//生产手机
	IphoneProduct iphoneProduct();
	
	//生产路由器
	IRouterProduct iRouterProduct();
}
//小米工厂
public class XiaomiFactory implements IProductFactory{
	@Override
	public IphoneProduct iphoneProduct() {
		return new XiaomiPhone();
	}

	@Override
	public IRouterProduct iRouterProduct() {
		return new XiaomiRouter();
	}
}
//华为工厂
public class HuaweiFactory implements IProductFactory{
	@Override
	public IphoneProduct iphoneProduct() {
		return new HuaweiPhone();
	}

	@Override
	public IRouterProduct iRouterProduct() {
		return new HuaweiRouter();
	}
}
//小米手机
public class XiaomiPhone implements IphoneProduct{
	@Override
	public void start() {
		System.out.println("start xiaomi phone");		
	}
}
//小米路由器
public class XiaomiRouter implements IRouterProduct{
	@Override
	public void start() {
		System.out.println("start xiaomi router");		
	}
}
//华为手机
public class HuaweiPhone implements IphoneProduct{
	@Override
	public void start() {
		System.out.println("start huawei phone");		
	}
}
//华为路由器
public class HuaweiRouter implements IRouterProduct{
	@Override
	public void start() {
		System.out.println("start huawei router");
	}
}
public class Consumer {
	public static void main(String[] args) {
		//调用小米工厂创建小米手机对象,小米路由器对象
		XiaomiFactory xiaomiFactory = new XiaomiFactory();
		IphoneProduct xiaomiPhone = xiaomiFactory.iphoneProduct();
		IRouterProduct xiaomiRouter = xiaomiFactory.iRouterProduct();

		//调用华为工厂创建华为手机对象,华为路由器对象
		HuaweiFactory huaweiFactory = new HuaweiFactory();
		IphoneProduct huaweiPhone = huaweiFactory.iphoneProduct();
		IRouterProduct huaweiRouter = huaweiFactory.iRouterProduct();
		
		xiaomiPhone.start();
		xiaomiRouter.start();
		huaweiPhone.start();
		huaweiRouter.start();
	}
}

输出:

start xiaomi phone
start xiaomi router
start huawei phone
start huawei router

抽象工厂模式小结:

  • 优点
  • 具体产品在应用层的代码隔离,无需关心创建的细节,创建对象时只要调用相应的工厂即可
  • 将一个系列的产品统一到一起创建
  • 缺点
  • 产品族中扩展新的产品困难
  • 增加了系统抽象性和理解难度

五、总结

  • 简单工厂模式:虽然某种程度上不符合设计原则,但实际使用最多
  • 工厂方法模式:不修改已有类的前提下,通过增加新的工厂类实现扩展
  • 抽象工厂模式:不可以增加产品,可以增加产品族