抽象工厂模式--AbstractFactory

  模拟场景:在上次的工厂设计模式中,女娲造了一群人。后面觉得不合适,世界上的人都好像傀儡,没有任何感情。所以她打算重新造人,让人类有性别之分:男、女。但是女娲不可能全部推倒重做吧,这个时候就要进行旧物回收利用了。

  在这里我们先进行分析一下,首先是human这个类,因为这里涉及到了sex、color、doSomething三个方法,很明显这些方法要定义到human这个接口中,具体是什么sex、什么color都是由子类去实现。那么就肯定有Yellow、White、Black三种不同肤色的human,所以要创建YellowHuman、WhiteHuman、BlackHuman三个类,但是考虑下,实现了Human接口,是否意味着要把这三个接口全部都实现呢?(下面只以YellowHuman为例进行说明,其他两个是一样的)

  其实不是,因为分析一下就知道,这里涉及到sex,那么femaleYellowHuman和maleYellowHuman只是sex不同而已,其他的像color和doSomething的操作时一样的。所以这个时候YellowHuman不能定义成普通的类,因为如果是普通的类的话就需要实现接口的全部方法。那么我们就可以使用abstract类了。不要忘记了,抽象类中是可以存在非抽象方法的,所以把共有的方法或者属性写到抽象类中,不实现getSex()方法即可。至于具体操作交给子类去实现即可。

接下来是工厂factory。工厂的操作就简单多了,在这里,虽然要创建不同肤色不同性别的human,都是会发现,其实需要创建两个factory,那就是以性别来区分(FemaleHumanFactory、MaleHumanFactory),因为我们生成的human中,最后是生成FemaleXXXHuman、MaleXXXHuman。

  如下代码:(也是以YellowHuman为例,其他操作类似)

  Human 

1 package com.zqz.dp.abstractfactory.human;
2 /**
3  * @author Qin 定义human的接口,human都有一些相同的属性,如人都有肤色、性别等等
4  */
5 public interface Human {
6          public void getColor(); // human的肤色
7          public void getSex(); // human的性别
8          public void doSomething(); // human可以做事
9 } 

  AbstractYellowHuman 

 1 package com.zqz.dp.abstractfactory.human;
 2 /**
 3  * @author Qin
 4  * 定义一个黄种人的抽象类,所有的黄种人有着相同的肤色,可以做一样的事情,不同的只是有性别之分而已
 5  * 所以此抽象类来定义相同的属性
 6  */
 7 public abstract class AbstractYellowHuman implements Human {
 8          @Override
 9          public void getColor() {
10                    System.out.println("黄种人的肤色是黄色的。。。");
11          }
12          @Override
13          public void doSomething() {
14                    System.out.println("我是黄种人。。。");
15          }
16 } 

  FemaleYellowHuman 

 1 package com.zqz.dp.abstractfactory.human;
 2 /**
 3  * @author Qin
 4  * 定义女性黄种人,只需要覆写其中的性别即可,黄种人除了性别有着其他的共有属性
 5  */
 6 public class FemaleYellowHuman extends AbstractYellowHuman {
 7          @Override
 8          public void getSex() {
 9                    System.out.println("我是女黄种人。。。");
10          }
11 } 

  MaleYellowHuman 

 1 package com.zqz.dp.abstractfactory.human;
 2 /**
 3  * @author Qin
 4  * 定义男性黄种人,只需要覆写其中的性别即可,黄种人除了性别有着其他的共有属性
 5  */
 6 public class MaleYellowHuman extends AbstractYellowHuman {
 7          @Override
 8          public void getSex() {
 9                    System.out.println("我是男黄种人。。。");
10          }
11 } 

  HumanFactory 

 1 package com.zqz.dp.abstractfactory.factory;
 2 import com.zqz.dp.abstractfactory.human.Human;
 3 /**
 4  * @author Qin
 5  * human工厂,用来创建不同肤色的human,下面定义了三个肤色,具体生成的是female还是mela交给子类去实现
 6  */
 7 public interface HumanFactory {
 8          public Human createYellowHuman(); // 生成黄种人的实现
 9          public Human createWhiteHuman(); // 生成白种人的实现
10          public Human createBlackHuman(); // 生成黑种人的实现
11 } 

  FemaleHumanFactory 

 1 package com.zqz.dp.abstractfactory.factory;
 2 import com.zqz.dp.abstractfactory.human.AbstractBlackHuman;
 3 import com.zqz.dp.abstractfactory.human.AbstractWhiteHuman;
 4 import com.zqz.dp.abstractfactory.human.AbstractYellowHuman;
 5 import com.zqz.dp.abstractfactory.human.FemaleBlackHuman;
 6 import com.zqz.dp.abstractfactory.human.FemaleWhiteHuman;
 7 import com.zqz.dp.abstractfactory.human.FemaleYellowHuman;
 8 /**
 9  * @author Qin 创建不同肤色,但是性别为female(女)的human
10  */
11 public class FemaleHumanFactory implements HumanFactory {
12          @Override
13          public AbstractYellowHuman createYellowHuman() {// 返回黄种人对象
14                    return new FemaleYellowHuman(); // 生成女性黄种人
15          }
16          @Override
17          public AbstractWhiteHuman createWhiteHuman() {// 返回白种人对象
18                    return new FemaleWhiteHuman(); // 生成女性白种人
19          }
20          @Override
21          public AbstractBlackHuman createBlackHuman() {// 返回黑种人对象
22                    return new FemaleBlackHuman(); // 生成女性黑种人
23          }
24 } 

  MaleHumanFactory 

 1 package com.zqz.dp.abstractfactory.factory;
 2 import com.zqz.dp.abstractfactory.human.AbstractBlackHuman;
 3 import com.zqz.dp.abstractfactory.human.AbstractWhiteHuman;
 4 import com.zqz.dp.abstractfactory.human.AbstractYellowHuman;
 5 import com.zqz.dp.abstractfactory.human.MaleBlackHuman;
 6 import com.zqz.dp.abstractfactory.human.MaleWhiteHuman;
 7 import com.zqz.dp.abstractfactory.human.MaleYellowHuman;
 8 /**
 9  * @author Qin 创建不同肤色,但是性别为male(男)的human
10  */
11 public class MaleHumanFactory implements HumanFactory {
12          @Override
13          public AbstractYellowHuman createYellowHuman() {     //返回黄种人对象
14                    return new MaleYellowHuman(); // 生成男性黄种人
15          }
16          @Override
17          public AbstractWhiteHuman createWhiteHuman() {      //返回白种人对象
18                    return new MaleWhiteHuman(); // 生成男性白种人
19          }
20          @Override
21          public AbstractBlackHuman createBlackHuman() {         //返回黑种人对象
22                    return new MaleBlackHuman(); // 生成男性黑种人
23          }
24 } 

  NvWa: 

 1 package com.zqz.dp.abstractfactory.client;
 2 import com.zqz.dp.abstractfactory.factory.FemaleHumanFactory;
 3 import com.zqz.dp.abstractfactory.factory.HumanFactory;
 4 import com.zqz.dp.abstractfactory.factory.MaleHumanFactory;
 5 import com.zqz.dp.abstractfactory.human.Human;
 6 /**
 7  * @author Qin NvWa类,开始生产不同性别的人类
 8  */
 9 public class NvWa {
10          public static void main(String[] args) {
11                    create();
12          }
13          public static void create() {
14                    /**
15                     * 创建两个工厂,生成female、male的human
16                     */
17                    HumanFactory femaleFactory = new FemaleHumanFactory(); // 生成female的human工厂
18                    HumanFactory maleFactory = new MaleHumanFactory(); // 生成male的human工厂
19                    /**
20                     * 开始创建不同sex、不同肤色的human
21                     */
22                    Human femaleYellowHuman = femaleFactory.createYellowHuman();   //创建female黄种人
23                    Human maleYellowHuman = maleFactory.createYellowHuman(); //创建male黄种人
24                    femaleYellowHuman.getSex();                  //取得female黄种人的性别
25                    maleYellowHuman.getSex();            //取得male黄种人的性别
26                    /**
27                     * 生成其他肤色的human、一样的操作,略去
28                     */
29          }
30 } 

  抽象工厂的定义:未创建一组相关或者相互依赖的对象提供一个接口,而且无需指定它们的具体类。

抽象工厂的优点:

  封装性,每个产品的实现类其他模块不需要关心,关系的只是工厂类是哪个,只要知道工厂类是哪个,我就可以创建出一些需要的对象。

抽象工厂的缺点:

  横向扩展方便,即如果我们要定义一个中性的human、扩展是很方便的。只是纵向扩展很麻烦。如果要再创建一种其他肤色的human时。

抽象工厂的使用场景:

  抽象工厂定义了一系列的产品,如果想对这一系列的产品进行拓展,或者想要替换掉一系列的产品,生成新的系列操作,或者控制系列产品的生产过程,那么就用抽象工厂。

一个对象族(或者一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂。

posted @ 2014-04-21 19:30  小钦  阅读(236)  评论(0编辑  收藏  举报