抽象工厂模式

初学编程模式,请读者指出不正确指出,多谢!

    抽象工厂模式的作用是为了灵活地生产产品。如果产品能够从一维的角度进行分类的话,可以直接使用普通的工厂模式即可。但是,在真实环境下,产品的属性可能是二维或者更高维的,所以这个时候就要用到抽象工厂了。本文完全参考CBF4LIFE缩写的《Java设计模式》,网上可下,文中的抽象工厂使用了女娲补天,不是,是女娲造人的例子来阐明抽象工厂模式,诙谐生动。在这里,我就借助这个例子来描述本人对抽象工厂的理解。

     首先,把人看作产品,那么人首先有肤色之分:白,黑,黄;同时也有性别之分:男,女;这两种属性是交叉存在的,也就是说既有黄色的男人,也有白色的女人等等。如果使用普通工厂的思路来考虑的话,直接在单一的工厂里设计六个方法,分别生产需要的人种即可。但是,这样太麻烦了。而且灵活度很低,对于我们这里的需求,先定义抽象工厂的基本功能就是生产三个颜色的人种,不分男女,即,工厂的基本方法就有:生产黄人,黑人,白人。然后,在定义两种具体的工厂,男人工厂,女人工厂。这样,通过调用男人工厂的三个函数可以生产黑男人,白男人和黄男人;调用女人工厂可以生产黑女人,白女人和黄女人。这样,能够灵活地生产这几个人种了。

      有人可能疑问,为什么不设计三个工厂:黑人工厂,白人工厂,黄人工厂?这样当然也是可以的,只是从另一个角度来决定工厂的作用,这种情况下,工厂的基本功能就是生产男人和女人了。

      整理的程序结构如下(摘抄至《java设计模式》):

      1、定义接口(interface)Human,包含了所有人的全部特征

package com.cbf4life;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 定义一个人类的统称,问题出来了,刚刚定义的时候忘记定义性别了 这个重要的问题非修改不可,否则这个世界上太多太多的东西不存在了
 */
public interface Human {
    // 首先定义什么是人类
    // 人是愉快的,会笑的,本来是想用smile表示,想了一下laugh更合适,好长时间没有大笑了;
    public void laugh();

    // 人类还会哭,代表痛苦
    public void cry();

    // 人类会说话
    public void talk();

    // 定义性别
    public void sex();
}
View Code

      2、定义了人所有种类的枚举变量HumanEnum,共六种变量,在通过工厂创建产品的时候,工厂通常需要将创建的产品的类名传入,生成类的实例。用枚举变量可以很好地保存六种产品类(就是这里的人种)的名称,这个技巧非常值得学习

package com.cbf4life;

public enum HumanEnum {
    // 把世界上所有人类型都定义出来
    YelloMaleHuman("com.cbf4life.yellowHuman.YellowMaleHuman"), YelloFemaleHuman(
            "com.cbf4life.yellowHuman.YellowFemaleHuman"), WhiteFemaleHuman(
            "com.cbf4life.whiteHuman.WhiteFemaleHuman"), WhiteMaleHuman(
            "com.cbf4life.whiteHuman.WhiteMaleHuman"), BlackFemaleHuman(
            "com.cbf4life.blackHuman.BlackFemaleHuman"), BlackMaleHuman(
            "com.cbf4life.blackHuman.BlackMaleHuman");

    private String value = "";

    // 定义构造函数,目的是Data(value)类型的相匹配
    private HumanEnum(String value) {
        this.value = value;
    }

    public String getValue() {
        return this.value;
    }

}
View Code

      3、接下来,需要定义一个工厂的接口,这个接口中包含了所有基本的工厂操作,也就是上文提到的生产黄人,黑人,白人的三个方法

package com.cbf4life;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 这次定一个接口,应该要造不同性别的人,需要不同的生产线 那这个八卦炉必须可以制造男人和女人
 */
public interface HumanFactory {
    // 制造黄色人种
    public Human createYellowHuman();

    // 制造一个白色人种
    public Human createWhiteHuman();

    // 制造一个黑色人种
    public Human createBlackHuman();
}
View Code

      4、然后定义造人工厂的抽象类,该抽象类的作用自然就是造人了,它只负责根据传入的类的名称造人,管你造男人女人黑人白人

package com.cbf4life.humanFactory;

import com.cbf4life.Human;
import com.cbf4life.HumanEnum;
import com.cbf4life.HumanFactory;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 编写一个抽象类,根据enum创建一个人类出来
 */
public abstract  class AbstractHumanFactory implements HumanFactory {
    /*
     * 给定一个性别人种,创建一个人类出来专业术语是产生产品等级
     */
    protected Human createHuman(HumanEnum humanEnum) {
        Human human = null;
        // 如果传递进来不是一个Enum中具体的一个Element的话,则不处理
        if (!humanEnum.getValue().equals("")) {
            try {
                // 直接产生一个实例
                human = (Human) Class.forName(humanEnum.getValue())
                        .newInstance();
            } catch (Exception e) {
                // 因为使用了enum,这个种异常情况不会产生了,除非你的enum有问题;
                e.printStackTrace();
            }

        }
        return human;
    }
}
View Code

      5、在抽象类工厂类额基础上,就是具体的工厂类了,分为男人类MaleHumanFactory和女人类FemaleHumanFactory,每个类中的具体方法也要对应体现

package com.cbf4life.humanFactory;

import com.cbf4life.Human;
import com.cbf4life.HumanEnum;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 女性创建工厂
 */
public class FemaleHumanFactory extends AbstractHumanFactory {
    // 创建一个女性黑种人
    public Human createBlackHuman() {
        return super.createHuman(HumanEnum.BlackFemaleHuman);
    }

    // 创建一个女性白种人
    public Human createWhiteHuman() {
        return super.createHuman(HumanEnum.WhiteFemaleHuman);
    }

    // 创建一个女性黄种人
    public Human createYellowHuman() {
        return super.createHuman(HumanEnum.YelloFemaleHuman);
    }
}
View Code
package com.cbf4life.humanFactory;

import com.cbf4life.Human;
import com.cbf4life.HumanEnum;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 男性创建工厂
 */
public class MaleHumanFactory extends AbstractHumanFactory {
    // 创建一个男性黑种人
    public Human createBlackHuman() {
        return super.createHuman(HumanEnum.BlackMaleHuman);
    }

    // 创建一个男性白种人
    public Human createWhiteHuman() {
        return super.createHuman(HumanEnum.WhiteMaleHuman);
    }

    // 创建一个男性黄种人
    public Human createYellowHuman() {
        return super.createHuman(HumanEnum.YelloMaleHuman);
    }
}
View Code

      不好意思把女人类放在前面了,谁让现在男人没地位呢。

      6、接下来,就是各个产品(人)的具体情况了

      首先定义黑人的抽象类AbstractBlackHuman,以及具体类,黑男人BlackMaleHuman(应该说男黑人,意思都差不多),黑女人(听起来很别扭)BlackFemaleHuman

package com.cbf4life.blackHuman;

import com.cbf4life.Human;

public abstract class AbstractBlackHuman implements Human {
    public void cry() {
        System.out.println("黑人会哭");
    }

    public void laugh() {
        System.out.println("黑人会笑");
    }

    public void talk() {
        System.out.println("黑人可以说话,一般人听不懂");
    }
}
View Code
package com.cbf4life.blackHuman;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 女性黑种人
 */
public class BlackFemaleHuman extends AbstractBlackHuman {
    public void sex() {
        System.out.println("该黑种人的性别为女...");
    }
}
View Code
package com.cbf4life.blackHuman;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 男性黑种人
 */
public class BlackMaleHuman extends AbstractBlackHuman {
    public void sex() {
        System.out.println("该黑种人的性别为男...");
    }
}
View Code

     然后是黄人

package com.cbf4life.yellowHuman;

import com.cbf4life.Human;

public abstract class AbstractYellowHuman implements Human {
    public void cry() {
        System.out.println("黄色人种会哭");
    }

    public void laugh() {
        System.out.println("黄色人种会大笑,幸福呀!");
    }

    public void talk() {
        System.out.println("黄色人种会说话,一般说的都是双字节");
    }
}
View Code
package com.cbf4life.yellowHuman;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 女性黄种人
 */
public class YellowFemaleHuman extends AbstractYellowHuman {
    public void sex() {
        System.out.println("该黄种人的性别为女...");
    }
}
View Code
package com.cbf4life.yellowHuman;

/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 男性黄种人
*/
public class YellowMaleHuman extends AbstractYellowHuman {
public void sex() {
System.out.println("该黄种人的性别为男....");
}
}
View Code

      最后是白人

package com.cbf4life.whiteHuman;

import com.cbf4life.Human;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 白色人人种 为了代码整洁,新建一个包,这里是白种人的天下了
 */
public abstract class AbstractWhiteHuman implements Human {
    public void cry() {
        System.out.println("白色人种会哭");
    }

    public void laugh() {
        System.out.println("白色人种会大笑,侵略的笑声");
    }

    public void talk() {
        System.out.println("白色人种会说话,一般都是但是单字节!");
    }
}
View Code
package com.cbf4life.whiteHuman;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 女性白种人
 */
public class WhiteFemaleHuman extends AbstractWhiteHuman {
    public void sex() {

        System.out.println("该白种人的性别为女....");
    }
}
View Code
package com.cbf4life.whiteHuman;

/**
 * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
 *         all. 男性白种人
 */
public class WhiteMaleHuman extends AbstractWhiteHuman {
    public void sex() {
        System.out.println("该白种人的性别为男....");
    }
}
View Code

      7,任何工厂都定义好了,女娲娘娘,可以开始了!(!要叫我女王大人!)

package com.cbf4life;

import com.cbf4life.humanFactory.FemaleHumanFactory;
import com.cbf4life.humanFactory.MaleHumanFactory;

public class NvWa {
    public static void main(String[] args) {
        // 第一条生产线,男性生产线
        HumanFactory maleHumanFactory = new MaleHumanFactory();
        // 第二条生产线,女性生产线
        HumanFactory femaleHumanFactory = new FemaleHumanFactory();
        // 生产线建立完毕,开始生产人了:
        Human maleYellowHuman = maleHumanFactory.createYellowHuman();
        Human femaleYellowHuman = femaleHumanFactory.createYellowHuman();
        maleYellowHuman.cry();
        maleYellowHuman.laugh();
        femaleYellowHuman.sex();
        /*
         * ..... 后面你可以续了
         */
    }
}
View Code

      以上便是本人对抽象工厂的理解,所有代码全部盗版CBF4LIFE的《Java设计模式》。如有错误或者不妥,欢迎留言。

原文地址:https://www.cnblogs.com/Joy06/p/3669373.html