工厂模式(Factory Pattern)提供了一种创建对象的最佳方式。我们不必关心对象的创建细节,只需要根据不同情况获取不同产品即可
1、简单工厂模式
简单工厂模式中用于被创建实例的方法通常为静态(static)方法又称为静态工厂模式,它不属于23种设计模式,但现实中却经常会用到。
- 抽象类或接口:定义了产品的规范,描述了产品的主要特性和功能。例如示例中,
Product定义获取汽车产品
- 具体实现:实现了抽象产品角色所定义的接口。例如示例中,
Product的实现类主要负责生产具体汽车
- 工厂:在工厂类中提供了静态工厂方法,它负责实现创建所有具体产品类的实例。工厂类可以被外界直接调用,创建所需的产品对象。
SimpleFactory根据类型生产所需产品
public class SimpleFactoryDemo {
public static void main(String[] args) {
// 获取产品
Product benz = SimpleFactory.getProduct("benz");
// 调用产品方法
benz.getProduct();
Product bmw = SimpleFactory.getProduct("bmw");
bmw.getProduct();
Product audi = SimpleFactory.getProduct("audi");
audi.getProduct();
}
}
/**
* 定义一个产品的接口
* 设计接口中定义的方法原则:不会因为产品变化而变化
* @author liushiwei
*/
interface Product{
/**
* 获取产品
*/
public void getProduct();
}
/**
* 奔驰
*/
class Benz implements Product{
@Override
public void getProduct() {
System.out.println("奔驰汽车");
}
}
/**
* 宝马
*/
class Bmw implements Product{
@Override
public void getProduct() {
System.out.println("宝马汽车");
}
}
/**
* 奥迪
*/
class Audi implements Product{
@Override
public void getProduct() {
System.out.println("奥迪汽车");
}
}
/**
* 工厂类,负责生产所需的产品
*/
class SimpleFactory{
public static Product getProduct(String type){
if(StringUtils.isEmpty(type)){
return null;
}else{
if("audi".equals(type)){
return new Audi();
}else if("bmw".equals(type)){
return new Bmw();
}else if("benz".equals(type)){
return new Benz();
}else{
return null;
}
}
}
}
- 优点:简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
- 缺点:很明显工厂类集中了所有实例的创建逻辑,违背开闭原则
2、工厂方法模式
工厂方法模式由抽象工厂、具体工厂、抽象产品和具体产品等4个要素构成。
- 抽象类或接口:定义了产品的规范,描述了产品的主要特性和功能。例如示例中,
Product定义获取汽车产品
- 具体实现:实现了抽象产品角色所定义的接口。例如示例中,
Product的实现类主要负责生产具体汽车
- 抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
AbstractFactory定义创建产品方法
- 工厂:主要是实现抽象工厂中的方法,完成具体产品的创建。
AudiFactory实现AbstractFactory创建具体产品
/**
* 工厂方法模式
* @author liushiwei
*/
public class FactoryMethodDemo {
public static void main(String[] args) {
// 创建工厂
AbstractFactory bmwFactory = new BmwFactory();
// 获取产品
Product product = bmwFactory.newProduct();
// 生产产品
product.getProduct();
// 获取产品
AbstractFactory audiFactory = new AudiFactory();
// 调用产品方法
Product audiProduct = audiFactory.newProduct();
audiProduct.getProduct();
}
}
/**
* 定义一个产品的接口
* 设计接口中定义的方法原则:不会因为产品变化而变化
* @author liushiwei
*/
interface Product{
/**
* 获取产品
*/
public void getProduct();
}
/**
* 奔驰
*/
class Benz implements Product{
@Override
public void getProduct() {
System.out.println("奔驰汽车");
}
}
/**
* 宝马
*/
class Bmw implements Product{
@Override
public void getProduct() {
System.out.println("宝马汽车");
}
}
/**
* 奥迪
*/
class Audi implements Product{
@Override
public void getProduct() {
System.out.println("奥迪汽车");
}
}
/**
* 抽象工厂
*/
interface AbstractFactory{
/**
* 获取具体产品
* @return
*/
public Product newProduct();
}
/**
* 奥迪工厂
*/
class AudiFactory implements AbstractFactory {
@Override
public Product newProduct() {
return new Audi();
}
}
/**
* 宝马工厂
*/
class BmwFactory implements AbstractFactory {
@Override
public Product newProduct() {
return new Bmw();
}
}
-
特点
- 一个产品对应一个工厂类,用于生产某种类型产品
-
优点
- 方便添加新产品
- 添加新产品只需添加相应工厂类,符合开闭原则
-
缺点
- 产品多时,工厂泛滥。
-
Spring中BeanFactory的getBean() 方法
3、抽象工厂
抽象工厂模式 (Abstract Factory)就是对一组具有相同主题的工厂进行封装
。抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产同一类(例如:多家只生产发动机的工厂)的产品,而抽象工厂模式可生产多个类的产品。例如:奥迪工厂可以生产发动机、底盘、车架等等一系列产品簇
/**
* 抽象工厂
* @author liushiwei
*/
public class FactoryMethodDemo {
public static void main(String[] args) {
// 创建工厂
AbstractFactory audiFactory = new BenzFactory();
// 创建一个发动机车间
Engine engine = audiFactory.newEngine();
// 创建一个底盘车间
Chassis chassis = audiFactory.newChassis();
// 生产发动机
engine.productionEngine();
// 生产底盘
chassis.productionChassis();
}
}
/**
* 发动机
*/
abstract class Engine{
/**
* 生产发动机
*/
public abstract void productionEngine();
}
/**
* 轮胎
*/
abstract class Chassis{
/**
* 生产轮胎
*/
public abstract void productionChassis();
}
/**
* 奔驰发车间
*/
class BenzEngine extends Engine{
@Override
public void productionEngine() {
System.out.println("生产奔驰发动机");
}
}
/**
* 奔驰底盘车间
*/
class BenzChassis extends Chassis{
@Override
public void productionChassis() {
System.out.println("生产奔驰底盘");
}
}
/**
* 奥迪发动机车间
*/
class AudiEngine extends Engine{
@Override
public void productionEngine() {
System.out.println("生产奥迪发动机");
}
}
/**
* 奥迪发动机车间
*/
class AudiChassis extends Chassis{
@Override
public void productionChassis() {
System.out.println("生产奥迪底盘");
}
}
/**
* 抽象工厂
*/
abstract class AbstractFactory{
/**
* 发动机车间
* @return
*/
public abstract Engine newEngine();
/**
* 底盘车间
* @return
*/
public abstract Chassis newChassis();
}
/**
* 奔驰工厂
*/
class BenzFactory extends AbstractFactory {
@Override
public Engine newEngine() {
return new BenzEngine();
}
@Override
public Chassis newChassis() {
return new BenzChassis();
}
}
/**
* 奥迪工厂
*/
class AudiFactory extends AbstractFactory {
@Override
public Engine newEngine() {
return new AudiEngine();
}
@Override
public Chassis newChassis() {
return new AudiChassis();
}
}
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦
。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了; 而对于抽象工厂模式,当减少一个 方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。