工厂模式
简单工厂模式
介绍
简单工厂其实并不是一种设计模式,更多的是作为一种编程习惯出现,在简单工厂模式中,返回生产对象的方法通常是static的,被称为静态工厂。
示例代码
- 汽车抽象接口 2种具体汽车(作为具体的生产产品)
interface Car{
void create();
}
class Benz implements Car{
@Override
public void create() {
System.out.println("生产了一辆宝马");
}
}
class BMW implements Car{
@Override
public void create() {
System.out.println("生产了一辆奔驰");
}
}
- 工厂类
class CarFactory{
public static Car createCar(String name)throws Exception{
if (name.equals("Benz")) {
return new Benz();
}else if(name.equals("BMW")){
return new BMW();
}else {
throw new Exception("无法确认需要生产的汽车");
}
}
}
- 运行实例
public class SimpleFactory {
public static void main(String[] args) throws Exception {
Car benz = CarFactory.createCar("Benz");
benz.create();
Car bmw = CarFactory.createCar("BMW");
bmw.create();
}
}
//运行结果
生产了一辆奔驰
生产了一辆宝马
假如,宝马和奔驰公司还有各自的别的型号的产品呢?把这些产品都放在Factory吗
工厂方法模式
介绍
与简单工厂不同的地方在于,不集中一个工厂生产,而是实现一个工厂接口,对象的实例化在抽象工厂的子类中。
示例代码
- 汽车抽象接口 2种具体汽车(作为具体的生产产品)
interface Car{
void create();
}
class BenzA implements Car{
@Override
public void create() {
System.out.println("生产了一辆奔驰A");
}
}
class BenzB implements Car{
@Override
public void create() {
System.out.println("生产了一辆奔驰B");
}
}
class BMWA implements Car{
@Override
public void create() {
System.out.println("生产了一辆宝马A");
}
}
class BMWB implements Car{
@Override
public void create() {
System.out.println("生产了一辆宝马B");
}
}
- 工厂类
abstract class Factory{
abstract Car createCar(int type);
}
class BenzFactory extends Factory{
@Override
Car createCar(int type) {
switch (type){
case 1:
return new BenzA();
case 2:
return new BenzB();
default:
return null;
}
}
}
class BMWFactory extends Factory{
@Override
Car createCar(int type) {
switch (type){
case 1:
return new BMWA();
case 2:
return new BMWB();
default:
return null;
}
}
}
- 运行实例
public class TestFactory {
public static void main(String[] args){
Factory factory1=new BenzFactory();
Car car1=factory1.createCar(1);
car1.create();
Factory factory2=new BMWFactory();
Car car2=factory2.createCar(2);
car2.create();
}
}
//运行结果
生产了一辆奔驰A
生产了一辆宝马B
类图
抽象工厂模式
三种模式的区别和联系
在介绍抽象工厂模式之前,先看一下区别,重点在于抽象工厂模式和工厂方法模式的对比。
一、简单工厂模式特点:
1、它是一个具体的类,非接口、抽象类。有一个重要的create()方法,利用if或者 switch创建产品并返回。
2、create()方法通常是静态的,所以也称之为静态工厂。
缺点:1、扩展性差(我想增加一种面条,除了新增一个面条产品类,还需要修改工厂类方法)。
2、不同的产品需要不同额外参数的时候 不支持。
二、工厂方法模式
模式描述:提供一个用于创建对象的接口(工厂接口),让其实现类(工厂实现类)决定实例化哪一个类(产品类),并且由该实现类创建对应类的实例。
模式要素:提供一个产品类的接口。产品类均要实现这个接口(也可以是abstract类,即抽象产品)。提供一个工厂类的接口。工厂类均要实现这个接口(即抽象工厂)。由工厂实现类创建产品类的实例。工厂实现类应有一个方法,用来实例化产品类。
三、抽象工厂模式
模式描述:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
四、区别
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。它与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。
示例代码
- 汽车配件 其中EngineB TireB PaintingB是BMW的组装配件,后面没写Benz工厂,但看个原理就差不多了
interface Engine{
Engine produce();
}
class EngineA implements Engine{
@Override
public Engine produce(){
System.out.println("奔驰配件-引擎A被生产");
return this;
}
}
class EngineB implements Engine{
@Override
public Engine produce(){
System.out.println("引擎B被生产");
return this;
}
}
interface Tire{
Tire produce();
}
class TireA implements Tire{
@Override
public Tire produce(){
System.out.println("奔驰配件-轮胎A被生产");
return this;
}
}class TireB implements Tire{
@Override
public Tire produce(){
System.out.println("轮胎B被生产");
return this;
}
}
interface Painting{
Painting produce();
}
class PaintingA implements Painting{
@Override
public Painting produce(){
System.out.println("奔驰配件-喷漆A被生产");
return this;
}
}class PaintingB implements Painting{
@Override
public Painting produce(){
System.out.println("喷漆B被生产");
return this;
}
}
- 汽车抽象类 及 具体的汽车
abstract class Car{
Engine e ;
Tire t;
Painting p;
void create(){};
}
class BenzA extends Car{
AccessoryFactory accessoryFactory;
public BenzA(AccessoryFactory a){
this.accessoryFactory=a;
}
@Override
public void create() {
this.e = accessoryFactory.createEngine();
this.t = accessoryFactory.createTire();
this.p = accessoryFactory.createPainting();
System.out.println("组装了配件,生产了一辆奔驰A");
}
}
class BenzB extends Car{
AccessoryFactory accessoryFactory;
public BenzB(AccessoryFactory a){
this.accessoryFactory=a;
}
@Override
public void create() {
this.e = accessoryFactory.createEngine();
this.t = accessoryFactory.createTire();
this.p = accessoryFactory.createPainting();
System.out.println("组装了配件,生产了一辆奔驰B");
}
}
- 汽车配件工厂类 生产引擎,轮胎,喷漆
interface AccessoryFactory{
Engine createEngine();
Tire createTire();
Painting createPainting();
}
class BenzAccessoryFactory implements AccessoryFactory{
@Override
public Engine createEngine() {
return new EngineA().produce();
}
@Override
public Tire createTire() {
return new TireA().produce();
}
@Override
public Painting createPainting() {
return new PaintingA().produce();
}
}
以上是抽象工厂模式的代码
这里和工厂方法模式结合起来,对比一下
5. 这是生产汽车的工厂类
abstract class Factory{
abstract Car createCar(int type);
}
class BenzFactory extends Factory{
@Override
Car createCar(int type) {
AccessoryFactory accessoryFactory=new BenzAccessoryFactory();
switch (type){
case 1:
return new BenzA(accessoryFactory);
case 2:
return new BenzB(accessoryFactory);
default:
return null;
}
}
}
- 运行示例
public class SimpleFactory {
public static void main(String[] args){
Factory factory1=new BenzFactory();
Car car1=factory1.createCar(1);
car1.create();
Car car2=factory1.createCar(2);
car2.create();
}
}
//运行结果
奔驰配件-引擎A被生产
奔驰配件-轮胎A被生产
奔驰配件-喷漆A被生产
组装了配件,生产了一辆奔驰A
奔驰配件-引擎A被生产
奔驰配件-轮胎A被生产
奔驰配件-喷漆A被生产
组装了配件,生产了一辆奔驰B
总结一下。工厂方法模式的对象实例化集中在一个方法中,且返回的是实现同一个接口的对象。通过继承完成对象的创建。
而抽象工厂模式,实例化的是多个相关,具有联系的对象。例如示例中的引擎,轮胎,喷漆。是通过对象组装完成创建对象的。