上一节学习了工厂模式的简单工厂(也叫静态工厂),这一节我们来学习一下工厂方法。
为什么要使用工厂方法呢?
如果工厂生产的产品种类非常多的时候,比如上一节的果汁工厂,如果不仅生产苹果汁、橙汁,还包括桃子汁、梨汁、椰汁等等二十几种果汁,那么想一下,我们的简单工厂的生产方法里面,将会有20多个if-else,这样代码维护起来是非常困难的,而且代码本身也不简洁。
当工厂生产的产品非常多,且还可以细分为几个系列,这时就可以使用工厂方法了。
工厂方法也叫多态工厂,就是将工厂也进行抽象,首先由一个抽象工厂,定义工厂的行为职责,然后各个工厂再去生产自己系列的产品。
包括的角色由:
抽象工厂:各具体工厂需要实现抽象工厂的方法,目的是定义具体工厂职责。
具体工厂:生产各自负责的系列的产品
抽象产品:定义产品行为属性
具体产品:被生产出来的具体产品
进入代码阶段:
1、定义抽象工厂
package com.itzhimei.study.design.factory.method;
/**
* www.itzhimei.com
* 抽象工厂,定义工厂行为职责
*/
public interface IFruitsJuiceFactory {
IFruitsJuice getFruitsJuice(int type);
}
2、实现抽象工厂,这里我们写了两个具体工厂,分别是苹果工厂和橙子工厂
package com.itzhimei.study.design.factory.method;
/**
* www.itzhimei.com
* 苹果饮品工厂
*/
public class AppleJuiceFactory implements IFruitsJuiceFactory {
@Override
public IFruitsJuice getFruitsJuice(int type) {
if(type ==1) {
return new AppleJuice();
} if(type ==2) {
return new AppleYogurt();
}
return null;
}
}
package com.itzhimei.study.design.factory.method;
/**
* www.itzhimei.com
* 橙子饮品工厂
*/
public class OrangeJuiceFactory implements IFruitsJuiceFactory {
@Override
public IFruitsJuice getFruitsJuice(int type) {
if(type ==1) {
return new OrangeJuice();
} if(type ==2) {
return new OrangeYogurt();
}
return null;
}
}
3、定义抽象产品
package com.itzhimei.study.design.factory.method;
/**
* www.itzhimei.com
* 果汁接口
*/
public interface IFruitsJuice {
/**
* 定义果汁方法
* @return
*/
String getFruitsJuice();
}
4、实现抽象产品,我们这里定义了四种产品,苹果汁、苹果味酸奶、橙汁、橙味酸奶
package com.itzhimei.study.design.factory.method;
/**
* www.itzhimei.com
* 苹果汁
*/
public class AppleJuice implements IFruitsJuice {
@Override
public String getFruitsJuice() {
return "苹果汁";
}
}
package com.itzhimei.study.design.factory.method;
/**
* www.itzhimei.com
* 苹果味酸奶
*/
public class AppleYogurt implements IFruitsJuice {
@Override
public String getFruitsJuice() {
return "苹果味酸奶";
}
}
package com.itzhimei.study.design.factory.method;
/**
* www.itzhimei.com
* 橙汁
*/
public class OrangeJuice implements IFruitsJuice {
@Override
public String getFruitsJuice() {
return "橙汁";
}
}
package com.itzhimei.study.design.factory.method;
/**
* www.itzhimei.com
* 橙子味酸奶
*/
public class OrangeYogurt implements IFruitsJuice {
@Override
public String getFruitsJuice() {
return "橙子味酸奶";
}
}
类的整体结构如下图:
接下来就可以进行测试了
package com.itzhimei.study.design.factory.method;
/**
* www.itzhimei.com
* 测试
*/
public class Client {
public static void main(String[] args) {
IFruitsJuiceFactory appleFactory = new AppleJuiceFactory();
System.out.println(appleFactory.getFruitsJuice(1).getFruitsJuice());
System.out.println(appleFactory.getFruitsJuice(2).getFruitsJuice());
IFruitsJuiceFactory orangeFactory = new OrangeJuiceFactory();
System.out.println(orangeFactory.getFruitsJuice(1).getFruitsJuice());
System.out.println(orangeFactory.getFruitsJuice(2).getFruitsJuice());
}
}
输出结果:
苹果汁
苹果味酸奶
橙汁
橙子味酸奶
类关系图:
总结:
工厂方法适用于产品非常多,并且可以划分系列的场景,根据产品系列,创建不同系列的工厂 ,各工厂再生产产品。
简单工厂适用于产品不多的情况下,将生产产品的职责,放在工厂的生产方法中,生产产品。