设计模型之工厂模式
1.工厂模式
1.1 定义
一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。
工厂方法模式的主要优点有:
用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;
工厂方法模式的缺点是:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
1. 2 模式的结构
- 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct()
来创建产品。 - 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
1. 3 UML类图
1. 4 问题由来
在现实生活中社会分工越来越细,越来越专业化。各种产品有专门的工厂生产,彻底告别了自给自足的小农经济时代,这大大缩短了产品的生产周期,提高了生产效率。同样,在软件开发中能否做到软件对象的生产和使用相分离呢?能否在满足“开闭原则”的前提下,客户随意增删或改变对软件相关对象的使用呢?
1. 5 解决思路
定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体工厂类当中,这样即可以满足生产和使用相分离。如果要创建的产品不多,只要一个工厂类就可以完成,但实际确是有多种产品,这时对工厂的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,也即满足了开闭原则。这样就可以做到生产和使用相分离,并且满足“开闭原则”
1. 6 解决方案
/**
* @author tbb
* 汽车工厂
*/
public interface CarFactory
{
Car produceCar();
}
/**
* @author tbb
* 汽车模型
*/
public interface Car
{
/**
* 品牌
*/
void brand();
}
/**
* @author tbb
* 奔驰汽车工厂
*/
public class BenzCarFactory implements CarFactory
{
@Override
public Car produceCar()
{
return new BenzCar();
}
}
/**
* @author tbb
* 奥迪汽车工厂
*/
public class AudiCarFactory implements CarFactory
{
@Override
public Car produceCar()
{
return new AudiCar();
}
}
/**
* @author tbb
* 奔驰汽车
*/
public class BenzCar implements Car{
@Override
public void brand()
{
System.out.println("奔驰");
}
}
/**
* @author tbb
* 奥迪汽车
*/
public class AudiCar implements Car{
@Override
public void brand()
{
System.out.println("奥迪");
}
}
public class Test
{
public static void main(String[] args)
{
//客户想要买奔驰车
BenzCarFactory benzCarFactory = new BenzCarFactory();
benzCarFactory.produceCar().brand();//奔驰
}
}
1. 7 简单工厂模式介绍
简单工厂模式的定义:
我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背“开闭原则”。
工厂模式和简单工厂模式比较:
工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
简单工厂模式代码如下:
/**
* @author tbb
* 汽车模型
*/
public interface Car
{
/**
* 品牌
*/
void brand();
}
/**
* @author tbb
* 汽车工厂
*/
public class CarFactory
{
Car produceCar(String brandName)
{
switch(brandName)
{
case "benz" : return new BenzCar();
case "audo" : return new AudiCar();
default: return null;
}
}
}
/**
* @author tbb
* 奔驰汽车
*/
public class BenzCar implements Car{
@Override
public void brand()
{
System.out.println("奔驰");
}
}
/**
* @author tbb
* 奥迪汽车
*/
public class AudiCar implements Car{
@Override
public void brand()
{
System.out.println("奥迪");
}
}
public class Test
{
public static void main(String[] args)
{
//客户想要买奔驰车
CarFactory carFactory = new CarFactory();
Car benzCar = carFactory.produceCar("benz");
benzCar.brand();//奔驰
}
}