工厂方法模式与简单工厂模式

时间:2022-06-08 07:14:55
一、定义

        定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延伸到其子类。

        简单的说,就是定义一个工厂,由工厂的生产方法来生产具体的产品类,用户只需要调用工厂的生产方法来获取具体的产品,而不需要关心生产的过程。

二、优点

    1.拥有良好的封装性。调用者需要一个具体产品,只需要向工厂获取,而不用知道创建对象的艰辛过程,降低模块间的耦合。

    2.易于扩展。增加产品时,只需要适当修改具体的工厂类或者扩展一个工厂,甚至不用修改。

    3.屏蔽产品类,解除耦合。产品类的实现如何变化,调用者都不需要关心,只需要关心产品的接口即可。

三、女娲造人实例分析

    大家都听过女娲捏土造人的神话故事,这软件开发中,这个过程设计到三个对象:女娲、八卦炉、不同肤色的人。女娲可以使用场景类 Client 表示,八卦炉类似于一个工厂 Factory,负责制造具体的产品 Product(即人类 Human)。相应的类图如下:

工厂方法模式与简单工厂模式

AbstractHumanFactory 的代码可以如下定义:

public abstract class AbstractHumanFactory {
    public abstract <T extends Human> T createHuman(Class<T> c);
}

    泛型限定了创建方法返回的对象类型必须是人类 Human。

HumanFactory 的代码可以如下定义:

public class HumanFactory extends AbstractHumanFactory {
    public <T extends Human> T createHuman(Class<T> c){
        //定义一个生产的人种
        Human human = null;
        try {
            //产生一个人种
            human = (T)Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            System.out.println("人种生成错误! ");
        }
        return (T)human;
    }
}

    使用反射可以避免新增产品时,还需要修改工厂的生产方法。

NvWa 类可以如下:

public class NvWa {
    public static void main(String[] args) {
        //声明阴阳八卦炉
        AbstractHumanFactory YinYangLu = new HumanFactory();//女娲第一次造人, 火候不足, 于是白人产生了
        System.out.println("--造出的第一批人是白色人种--");
        Human whiteHuman = YinYangLu.createHuman(WhiteHuman.class);
        whiteHuman.getColor();
        whiteHuman.talk();
        //女娲第二次造人, 火候过足, 于是黑人产生了
        System.out.println("--造出的第二批人是黑色人种--");
        Human blackHuman = YinYangLu.createHuman(BlackHuman.class);
        blackHuman.getColor();
        blackHuman.talk();
        //第三次造人, 火候刚刚好, 于是黄色人种产生了
        System.out.println("--造出的第三批人是黄色人种--");
        Human yellowHuman = YinYangLu.createHuman(YellowHuman.class);
        yellowHuman.getColor();
        yellowHuman.talk();
    }
}
四、简单工厂模式

    当我们仅需要使用到一个工厂,我们没必要把它产生出来,同时使用静态方法就可以了。

    例如上面女娲那个例子,我们可以去掉 AbstractHumanFactory 类,同时把 createHuman 方法设置为静态类型,简化了类的创建过程。类图如下:

工厂方法模式与简单工厂模式

    类图变简单了,少了 AbstractHumanFactory 类,调用也比较简单,该模式是工厂方法模式的弱化,因为简单,所以称之为简单工厂模式,也叫静态工厂模式。

新的 HumanFactory 的代码可以如下定义:

public class HumanFactory {
    public static <T extends Human> T createHuman(Class<T> c){//定义一个生产出的人种
        Human human = null;
        try {
            //产生一个人种
            human = (Human)Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            System.out.println("人种生成错误! ");
        }
        return (T)human;
    }
}
    其优点是简单,缺点是工厂类的扩展比较困难,不符合开闭原则。