设计模式之(四)------抽象工厂模式

好了,我们继续上一节课,上一节讲到女娲造人,人是造出来了,世界时热闹了,可是低头一看,都

是清一色的类型,缺少关爱、仇恨、喜怒哀乐等情绪,人类的生命太平淡了,女娲一想,猛然一拍脑袋,

Shit!忘记给人类定义性别了,那怎么办?抹掉重来,然后就把人类重新洗牌,准备重新开始制造人类。

由于先前的工作已经花费了很大的精力做为铺垫,也不想从头开始了,那先说人类(Product 产品类)

怎么改吧,好,有了,给每个人类都加一个性别,然后再重新制造,这个问题解决了,那八卦炉怎么办?

只有一个呀,要么生产出全都是男性,要不都是女性,那不行呀,有了,把已经有了一条生产线——八卦

炉(工厂模式中的 Concrete Factory)拆开,于是女娲就使用了“八卦拷贝术”,把原先的八卦炉一个变两

个,并且略加修改,就成了女性八卦炉(只生产女性,一个具体工厂的实现类)和男性八卦炉(只生产男

性,又一个具体工厂的实现类)先看一下 我们的类的结构图:

3个抽象类 YellowHuman BlackHuman WhiteHuman 在抽象工厂模式中叫做产品等级,6个实现类(FemaleYellowHuman MaleYellowHuman FemaleBlackHuman MaleBlackHuman FemaleWhiteHuman MaleWhiteHuamn )叫做产品族。

其中抽象工厂AbstractHumanFactory 只有一个createHuman 的方法。下面我们来看程序实现:

package com.fc.AbstractFactory;

public interface IHumann {
 public void  laugh();
 public  void talk();
 public  void sex();
}

人类的接口定义好,然后根据接口创建三个抽象类,也就是三个产品等级, 实现 laugh()、talk()

三个方法,以 AbstractYellowHuman 为例:

package com.fc.AbstractFactory.dengji;

import com.fc.AbstractFactory.IHumann;

public abstract class AbstractYellowHuman implements IHumann{

    public void laugh() {
        System.out.println("黄色人类会笑");

    }

    public void talk() {
        System.out.println("黄色人类说话");

    }

}

其他两个与这个类似,这样三个抽象类就实现完了,然后就是那6个实现类了。

我们先来看女性黄色人种的实现类:

package com.fc.AbstractFactory.pinzu;

import com.fc.AbstractFactory.dengji.AbstractYellowHuman;

public class YellowFemaleHuman extends AbstractYellowHuman {
    public void sex() {
        System. out.println(" 该黄种人的性别为女...");
        }
}

男性黄色人种:

package com.fc.AbstractFactory.pinzu;

import com.fc.AbstractFactory.dengji.AbstractYellowHuman;

public class YellowMaleHuman extends AbstractYellowHuman{

    public void sex() {
        System.out.println("该黄种人的性别是男。。。");

    }

}

女性黑色人种:

package com.fc.AbstractFactory.pinzu;

import com.fc.AbstractFactory.dengji.AbstractBlackHuman;

public class BlackFemaleHuman extends AbstractBlackHuman{
    public void sex() {
        System. out.println(" 该黑人的性别为女...");
        }
}

男性黑色人种:

package com.fc.AbstractFactory.pinzu;

import com.fc.AbstractFactory.dengji.AbstractBlackHuman;

public class BlackMaleHuman extends AbstractBlackHuman{

    public void sex() {
        System.out.println("该黑人的性别是男。。。");

    }

}

女性白色人种:

package com.fc.AbstractFactory.pinzu;

import com.fc.AbstractFactory.dengji.AbstractWhiteHuman;

public class WhiteFemaleHuman extends AbstractWhiteHuman {
    public void sex() {
        System. out.println(" 该白人的性别为女...");
        }
}

男性白色人种:

package com.fc.AbstractFactory.pinzu;

import com.fc.AbstractFactory.dengji.AbstractWhiteHuman;

public class WhiteMaleHuman extends AbstractWhiteHuman{

    public void sex() {
        System.out.println("该白人的性别是男。。。");

    }

}

抽象工厂模式下的产品等级和产品族都已经完成,也就是人类以及产生出的人类是什么样子的都已经

定义好了,下一步就等着工厂开工创建了,那我们来看工厂类。

在看工厂类之前我们先看那个枚举类型,这个是很有意思的:

package com.fc.AbstractFactory;

public enum HumanEnum {

  YelloMaleHuman("com.fc.AbstractFactory.pinzu.YellowMaleHuman"),
  YelloFemalHuman("com.fc.AbstractFactory.pinzu.YellowFemaleHuman"),
  WhiteFemalHuman("com.fc.AbstractFactory.pinzu.WhiteFemaleHuman"),
  WhiteMaleHuman("com.fc.AbstractFactory.pinzu.WhiteMaleHuman"),
  BlackFemalHuman("com.fc.AbstractFactory.pinzu.BlackFemaleHuman"),
  BlackMaleHuman("com.fc.AbstractFactory.pinzu.BlackMaleHuman");
private String value = "";
    //定义构造函数,目的是Data(value) 类型的相匹配
    private HumanEnum(String value){
     this. value = value;
     }
    public String getValue(){
     return this. value;
     }
}

Enum 以前我也很少用,最近在一个项目中偶然使用上了,然后才发觉它的好处,Enum 类型作为一个参

数传递到一个方法中时,在 Junit 进行单元测试的时候,不用判断输入参数是否为空、长度为 0 的边界异

常条件,如果方法传入的参数不是 Enum 类型的话,根本就传递不进来,你说定义一个类,定义一堆的静态

变量,这也可以呀,这个不和你抬杠,上面的代码我解释一下,构造函数没啥好说的,然后是 getValue()

方法,就是获得枚举类型中一个元素的值,枚举类型中的元素也是有名称和值的,这个和 HashMap 有点类

似。

然后,我们看我们的工厂类,先看接口:

package com.fc.AbstractFactory;

public interface IHumanFatory {
    //制造黄色人类
    public IHumann createYellowHuman();
    //制造一个白色人类
    public IHumann createWhiteHuman();
    //制造一个黑色人类
    public IHumann createBlackHuman();
}

然后看抽象类:

package com.fc.AbstractFactory;

import com.fc.factory.Human;

public abstract class AbstractHumanFactory implements IHumanFatory {
    /*
     * 给定一个性别人类,创建一个人类出来 专业术语是产生产品等级
     */
    protected IHumann createHuman(HumanEnum humanEnum) {
        IHumann human = null;
        // 如果传递进来不是一个Enum中具体的一个Element的话,则不处理
        if (!humanEnum.getValue().equals("")) {
            try {
                // 直接产生一个实例
                human = (IHumann) Class.forName(humanEnum.getValue())
                        .newInstance();
            } catch (Exception e) {
                // 因为使用了enum,这个种异常情况不会产生了,除非你的enum有问题;
                e.printStackTrace();
            }
        }
        return human;
    }
}

看到没,这就是引入 enum 的好处,createHuman(HumanEnum humanEnum)这个方法定义了输入参数必须

是 HumanEnum 类型,然后直接使用 humanEnum.getValue()方法就能获得具体传递进来的值,这个不多说了,

大家自己看程序领会,没多大难度,这个抽象类的目的就是减少下边实现类的代码量,我们看实现类:

男性工厂,只创建男性:

package com.fc.AbstractFactory;

 public class MaleHumanFactory extends AbstractHumanFactory{

public IHumann createYellowHuman() {

    return super.createHuman(HumanEnum.YelloMaleHuman);
}

public IHumann createWhiteHuman() {

    return super.createHuman(HumanEnum.WhiteMaleHuman);
}

public IHumann createBlackHuman() {

    return super.createHuman(HumanEnum.BlackMaleHuman);
}
}

女性工厂,只创建女性:

package com.fc.AbstractFactory;

public class FemaleHumanFactory extends AbstractHumanFactory{

    public IHumann createYellowHuman() {
        // TODO Auto-generated method stub
        return super.createHuman(HumanEnum.YelloFemalHuman);
    }

    public IHumann createWhiteHuman() {
        // TODO Auto-generated method stub
        return super.createHuman(HumanEnum.WhiteFemalHuman);
    }

    public IHumann createBlackHuman() {
        // TODO Auto-generated method stub
        return super.createHuman(HumanEnum.BlackFemalHuman);
    }

}

产品定义好了,工厂也定义好了,万事俱备只欠东风,那咱就开始造吧,哦,不对,女娲开始造人了:

package com.fc.AbstractFactory;

public class NvWa {

    /**
     * @param args
     */
    public static void main(String[] args) {

         //第一条生产线,男性生产线
         IHumanFatory maleHumanFactory = new MaleHumanFactory();
         //第二条生产线,女性生产线
         IHumanFatory femaleHumanFactory = new FemaleHumanFactory();
         //生产线建立完毕,开始生产人了:
         IHumann maleYellowHuman = maleHumanFactory.createYellowHuman();
         IHumann femaleYellowHuman = femaleHumanFactory.createYellowHuman();
         maleYellowHuman.talk();
         maleYellowHuman.laugh();
         femaleYellowHuman.sex();
         /*
         * .....
         * 后面你可以续了
         */

    }

}

输出结果:

*黄色人类说话

黄色人类会笑

该黄种人的性别为女…*

时间: 2024-08-06 14:56:13

设计模式之(四)------抽象工厂模式的相关文章

设计模式学习03—抽象工厂模式

1.动机与定义 工厂模式中,一个工厂仅仅能提供一个或一类产品,当产品种类较多,形成产品系列(比方我们要创建跨平台的button,菜单,文本框等等一系列GUI控件: 单纯使用工厂模式会产生大量工厂,并且后期维护也不方便,我们能够从产品中找到规律,假设产品等级相对固定,以后仅仅会新增产品族,那么我们就能够把整个产品族放到一个工厂创建,以后新增其它系统产品族也很方便,例如以下图: 这样的模式就是抽象工厂,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则须要面对多个产品等级结构,一个工厂等级结构能

设计模式C++实现——抽象工厂模式

模式定义: 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类. 抽象工厂允许客户使用抽象的接口来创建一组相关产品,而不需要知道实际产出的具体产品时什么.这样一来,客户就从具体的产品中被解耦了. 模式结构: 举例: 数据库访问程序设计,不同的数据库访问方式可能不一样,为了抽象对对不同数据库的访问,可以将数据库隐藏起来,提供统一的访问方式,用多态进行实现. UML设计: 编程实现及执行结果: #include <iostream> using namespace st

23种设计模式[3]:抽象工厂模式

一.简单工厂模式(静态工厂方法,不属于23种GOF设计模式之一) 定义:定义一个用于创建产品对象的方法,由该工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例. 类型:创建类模式 public interface SmsService { void sendSms(); } public class MontnetsService implements SmsService { @Override public void sendSms() { Syste

设计模式第四篇-工厂模式

一.引言 园子里有关设计模式的文章可以说数不胜数,之前也看过很多,但是其实理解都不深入,时间一长就忘了.最好是记录下来,总结中加深印象,这里也给刚开始进行开发的同学提个建议,不要因为自己写的不好而不去写,谁都是从菜鸟开始的,不断的总结才能将知识消化成自己的. 现在开始今天的学习. 工厂模式是设计模式中很重要的一个模式,其中有简单工厂模式(并不能算一个模式),工厂模式,抽象工厂模式. 工厂模式,从名字可以看出,这是一个创建型的模式,是用来创建对象.我们从简单工厂模式开始 二.简单工厂模式 简单工厂

一天一个设计模式——Abstract Factory抽象工厂模式

一.模式说明 前面学习了工厂方法(Factory Method)模式.在工厂方法模式中,在工厂方法模式中,父类决定如何生成实例,但并不决定所要生成的具体类,具体的处理交由子类来处理.这里学习的抽象工厂方法模式中,抽象工厂使用抽象的零件组装成抽象的产品.即使用包含特定的方法接口零件,将零件组装成抽象产品. 二.模式类图: 上面的类图中包含两个包:包含抽象工厂,抽象零件,抽象产品的类所在的包以及具体工厂实现类的包. 三.代码示例 1.Item类: package com.designpattern.

设计模式学习-抽象工厂模式

1.定义 提供接口,创建一系列相关或独立的对象,而不指定这些对象的具体类. 2.类图 3.代码示例 1 package com.zhaoyangwoo.abstractfactory; 2 3 /** 4 * Created by john on 16/5/2. 5 * @author wuzhaoyang 6 * <p> 7 * 抽象工厂:多个抽象产品类,派生出多个具体产品类:一个抽象工厂类,派生出多个具体工厂类:每个具体工厂类可创建多个具体产品类的实例. 8 * 即提供一个创建一系列相关或

大话设计模式C++版——抽象工厂模式

前面说过,简单工厂模式是最基础的一种设计模式,那以工厂命名的设计模式就是23种设计模式中最多的一种,他们一脉相承,一步一步进化而来,这里就是其中的最后一种--抽象工厂模式(Abstract Factory),其是在工厂方法模式的基础上改进而来,如果没有弄明白工厂方法模式的同学请先观看<大话设计模式C++版--工厂方法模式>. 为什么会有抽象工厂模式?抽象工厂模式是简单工厂模式缺陷的终极解决方式么?NO,抽象工厂模式并不是为了解决简单工厂模式的缺陷而活着,它是因为有新的使命而诞生. 一个简单的例

[Python编程实战] 第一章 python的创建型设计模式1.1抽象工厂模式

注:关乎对象的创建方式的设计模式就是"创建型设计模式"(creational design pattern) 1.1 抽象工厂模式 "抽象工厂模式"(Abstract Factory Pattern)用来创建复杂的对象,这种对象由许多小对象组成,而这些小对象都属于某个特定的"系列"(family). 比如说,在GUI 系统里可以设计"抽象控件工厂"(abstract widget factory),并设计三个"具体子

JAVA常用设计模式(一、抽象工厂模式)

抽象工厂模式 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂.该超级工厂又称为其他工厂的工厂.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类.每个生成的工厂都能按照工厂模式提供对象. 意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 主要解决:主要解决接口选择的问题. 何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一

Java描述设计模式(04):抽象工厂模式

本文源码:GitHub·点这里 || GitEE·点这里 一.抽象工厂模式 1.生活场景 汽车生产根据用户选择的汽车类型,指定不同的工厂进行生产,选择红旗轿车,就要使用中国工厂,选择奥迪轿车,就要使用德国工厂. 2.抽象工厂模式 1) 抽象工厂模式:定义了一个interface用于创建相关对象或相互依赖的对象,而无需指明具体的类:2) 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合:3) 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象).4) 将工厂抽象成两层,A