工厂方法模式

1.什么是工厂方法模式

1.百度百科

工厂方法模式(FACTORY METHOD)是一种常用的对象创建型设计模式,此模式的核心精神是封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂、具体工厂、抽象产品、具体产品

2.维基百科

**
In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.
**

3.LZ的理解

首先工厂方法模式是创建多个对象的一种设计模式。工厂要创建产品就必须知道我需要哪些对象来组成产品。然而每个产品除了核心功能外其他功能都是有增有减少。为了封装这个变化我们在工厂模式中只定义一个抽象工厂而的创建对象将推迟到具体实现工厂去创建。从而在工厂结构不变化的情况下改变具体创建对象的功能。是符合开闭原则的。

4.核心角色

抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。


具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。


抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。


具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。

2.工厂方法模式解决了什么问题

1.让调用方与具体的产品、工厂解除耦合。

让调用方只需要依赖抽象工厂和抽象产品就能完成业务。

3.工厂方法模式用法

1.静态工厂方法

为了使用工厂方法模式我们先看一个工厂方法模式的特殊实现静态工厂方法模式

静态工厂方法模式Static Factory Method)是属于创建型模式,又叫做简单工厂模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

就拿汽车制造来举例子:我想要一辆XX车


这个车要能开,首先来个车的接口

public interface Car {

	public void dirver();

}

实现2个车的创建方法

public class BMWCar implements Car {
	public BMWCar() {
		System.out.println("BMW建造好了");
	}

	@Override
	public void dirver() {
		System.out.println("BMW可以开走了");
	}

}

public class JMNCar implements Car {

	public JMNCar() {
		System.out.println("JMN建造好了");
	}

	@Override
	public void dirver() {
		System.out.println("JMN可以开走了");

	}

}

汽车的简单工厂用于创建汽车

/**
 * 汽车工厂
 */
public class CarFactory {

	public static Car createCar(String carName) {

		if("BMW".equals(carName)) {
			return new BMWCar();
		}else if("JMN".equals(carName)) {
			return new JMNCar();
		}else {
			return null;
		}
	}

}

客户需要一辆汽车时

/**
 * 顾客想要定制汽车
 */
public class Customer {
	public static void main(String[] args) {
		Car car = CarFactory.createCar("BMW");
		car.dirver();
		car = CarFactory.createCar("JMN");
		car.dirver();
		car = CarFactory.createCar("RPL");
		car.dirver();
	}
}

这第三种车并不存在。所以会抛出空指针。


这是一个静态工厂方法将变化的if-else从繁杂的客户调用中抽取出来。客户调用方便。对象创建自动完成。但是这种方式的工厂有个问题,要增加一种新车时还是要修改工厂方法。
随着车越来越多if的分支也会越来越多,修改运行中的业务不符合开闭原则。所以我们要另想办法去封装这个变化。

2.工厂方法模式

依据工厂方法模式的定义我们先定义4个角色。

我们先抽象出产品功能的接口(抽象产品)

public interface Car {
	/**
	 * 驾驶
	 */
	public void drive();
	/**
	 * 载人
	 */
	public void manned();

}

我们将这个抽象产品具体化(具体产品)

public class BMWCar implements Car {
	public BMWCar() {
		System.out.println("BMW建造好了");
	}



	@Override
	public void drive() {
		System.out.println("BMW可以开走了");
	}

	@Override
	public void manned() {
		System.out.println("BMW还能载人了");
	}

}

public class JMNCar implements Car {

	public JMNCar() {
		System.out.println("JMN建造好了");
	}

	@Override
	public void drive() {
		System.out.println("JMN可以开走了");
	}

	@Override
	public void manned() {
		System.out.println("JMN还能载人了");
	}

}

然后我们将工厂抽象(抽象工厂)

public interface CreatorFactory {

	public Car createCar();
}

最后工厂的实现(具体工厂)

public class BMWCreatorFactory implements CreatorFactory {

	@Override
	public Car createCar() {
		return new BMWCar();
	}

}

public class JMNCreatorFactory implements CreatorFactory {

	@Override
	public Car createCar() {
		return new JMNCar();
	}

}

客户端调用


public class Customer {

	 public static void main(String[] args) {
		 CreatorFactory bmwCreatorFactory = new BMWCreatorFactory();
		 Car bmwCar = bmwCreatorFactory.createCar();
		 bmwCar.drive();
		 bmwCar.manned();

		 CreatorFactory jmnCreatorFactory = new JMNCreatorFactory();
		 Car jmn = jmnCreatorFactory.createCar();
		 jmn.drive();
		 jmn.manned();		 
	}

}

相对于简单工厂模式,工厂方法模式将变化提取了出去以固定的架构和方式去调用创建对象的工厂。当我们需要添加新的实例时。只需要编写产品的具体实现。和产品具体创建方法的实现就行。架构稳定扩展方便。

4.工厂方法模式的问题

1.相对于直接new其创建过程及其复杂。随着类数量越来越多其项目也会变得极其复杂。

5.总结

工厂方法模式就是提供一个抽象的工厂、抽象的产品。而需要新增业务是需要实现工厂、实现产品。而调用方不需要关心具体是哪个去实现了接口。只需依赖抽象工厂和抽象方法完成工作。

posted @ 2017-12-13 14:55  枫飘雪落  阅读(324)  评论(0编辑  收藏  举报