设计模式之 工厂模式下–工厂方法

上一节学习了工厂模式的简单工厂(也叫静态工厂),这一节我们来学习一下工厂方法。

为什么要使用工厂方法呢?

如果工厂生产的产品种类非常多的时候,比如上一节的果汁工厂,如果不仅生产苹果汁、橙汁,还包括桃子汁、梨汁、椰汁等等二十几种果汁,那么想一下,我们的简单工厂的生产方法里面,将会有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());
    }
}

输出结果:

苹果汁
苹果味酸奶
橙汁
橙子味酸奶

类关系图:

总结:

工厂方法适用于产品非常多,并且可以划分系列的场景,根据产品系列,创建不同系列的工厂 ,各工厂再生产产品。

简单工厂适用于产品不多的情况下,将生产产品的职责,放在工厂的生产方法中,生产产品。