在简单工厂模式中,当出现产品类的增删改时,均需要修改静态产品工厂类内的选择分支,破坏了开闭原则。针对这个不足,可以将生产不同产品的工厂也单独成类,他们继承同一个抽象工厂类。这样在出现新产品时只增加相应的产品类和生产他的工厂类,对其他代码均无需改动其他。等到要使用这个新工厂时,再在客户端中声明这个工厂的实例,由它来生产产品即可。这就是符合开闭原则的工厂方法模式。
package com.yukiyama.pattern.creation;
/**
* 工厂方法模式
*/
public class FactoryMethodDemo {
public static void main(String[] args) {
// 声明一个具体运算工厂
OperFactory fa = new AddFactory();
// 由该工厂提供运算产品
Oper oper = fa.createOper();
// 执行产品的运算方法得到结果,输出“7”
System.out.println(oper.result(3, 4));
}
}
/**
* 抽象工厂类
* 定义一个创建产品的抽象方法。
*/
abstract class OperFactory{
public abstract Oper createOper();
}
/**
* 具体工厂类
* 继承抽象工厂类,实现创建产品的抽象方法。
* 下例是加法工厂。
*/
class AddFactory extends OperFactory{
@Override
public Oper createOper() {
return new OperAdd();
}
}
/**
* 具体工厂类
* 下例是减法工厂。
*/
class SubFactory extends OperFactory{
@Override
public Oper createOper() {
return new OperSub();
}
}
/**
* 下例是乘法工厂
*/
class MulFactory extends OperFactory{
@Override
public Oper createOper() {
return new OperMul();
}
}
/**
* 下例是除法工厂
*/
class DivFactory extends OperFactory{
@Override
public Oper createOper() {
return new OperDiv();
}
}
/**
* 抽象产品类
* 定义抽象产品方法。
* 本示例的产品为四则运算,产品方法为运算过程。
*/
abstract class Oper{
public abstract int result(int a, int b);
}
/**
* 具体产品类
* 继承抽象产品类,实现抽象产品方法。
* 下例是加法产品。
*/
class OperAdd extends Oper{
@Override
public int result(int a, int b) {
return a + b;
}
}
/**
* 具体产品类
* 下例是减法产品。
*/
class OperSub extends Oper{
@Override
public int result(int a, int b) {
return a - b;
}
}
/**
* 具体产品类
* 下例是乘法产品。
*/
class OperMul extends Oper{
@Override
public int result(int a, int b) {
return a * b;
}
}
/**
* 具体产品类
* 下例是除法产品。
*/
class OperDiv extends Oper{
@Override
public int result(int a, int b) {
if(b == 0) {
System.err.println("除数不能为0.");
throw new IllegalArgumentException();
}
return a / b;
}
}