设计模式系列之「抽象工厂模式」

掘金地址:https://juejin.im/post/5a4052d76fb9a0450a6791ad

「工厂方法模式」制造出了牛逼哄哄的鸣人,700多集的《火影》让小Y嗖的一声跳到了大结局,直接让鸣人变成了忍界大佬。回想这样子的鸣人太过乏味了,小Y决定让鸣人回炉重造,Let’s go!

一、制造前的Ready

1.前提

在工厂方法模式准备的条件之下重新制造鸣人,尽可能利用现有的。

2.增加的模块

把鸣人成长阶段分为鸣人baby鸣人欧巴两个阶段。

3.制造工厂的改造

现只有一个AbstractMingRenFactory,只能要够生产出不同模式的鸣人,不能设置不同时期下的鸣人,怎么办?把现有的工厂拆分为两个,鸣人baby工厂鸣人欧巴工厂

4.重新制造鸣人UML

重新造鸣人UML

二、制造鸣人

①MingRen接口是对鸣人的总称

public interface MingRen {
    //鸣人使用不同能力的咒语
    void getSpell();
    //能力的介绍
    void getAbility();
}

②仙人模式的鸣人

public abstract MingRenOfFairy implements MingRen {
    @Override
    public void getSpell() {
        System.out.println("哦哈哟锅炸一马屎~~~");
    }

    @Override
    public void getAbility() {
        System.out.println("可以利用自身周围的自然能量,使攻击范围更广。");
    }
}

③仙人模式的鸣人baby

public class MingRenBabyOfFairy extens MingRenOfFairy {

    public void attcak() {
        System.out.println("仙人模式处于baby期。");
    }

}

④仙人模式的鸣人欧巴

public class MingRenOBaOfFairy extens MingRenOfFairy {

    public void attcak() {
        System.out.println("仙人模式处于欧巴期。");
    }

}

⑤螺旋丸的鸣人

public class MingRenOfSpiral implements MingRen {
    @Override
    public void getSpell() {
        System.out.println("玛尼玛尼哄~~~");
    }

    @Override
    public void getAbility() {
        System.out.println("形成手掌般大小的查克拉球。");
    }
}

⑥螺旋丸的鸣人baby

public class MingRenBabyOfSpiral extens MingRenOfSpiral {
    public void Attcak() {
        System.out.println("螺旋丸处于baby期。");
    }
}

⑦螺旋丸的鸣人欧巴

public class MingRenOBaOfSpiral iextens MingRenOfSpiral {
    public void attcak() {
        System.out.println("螺旋丸处于欧巴期。");
    }
}

⑧多重影分身术的鸣人

public class MingRenOfSeparate implements MingRen {
    @Override
    public void getSpell() {
        System.out.println("卡通,阿里噶哆~~~");
    }

    @Override
    public void getAbility() {
        System.out.println("一次分出多个影分身。");
    }
}

⑨多重影分身术的鸣人baby

public class MingRenBabyOfSeparate extends MingRenOfSeparate {
    public void Attcak() {
        System.out.println("多重影分身术处于baby期。");
    }
}

⑩多重影分身术的鸣人欧巴

public class MingRenOBaOfSeparate extends MingRenOfSeparate {
    public void attcak() {
        System.out.println("多重影分身术处于欧巴期。");
    }
}

⑪定义鸣人工厂

public implements class AbstractMingRenFactory {
    //制造一个仙人模式的鸣人
    public MingRen createMingRenOfFairy();
    //制造一个螺旋丸的鸣人
    public MingRen createMingRenOfSpiral();
    //制造一个多重影分身术的鸣人
    public MingRen createMingRenOfSeparate();
}

⑫生产baby期鸣人的工厂

public class MingRenBabyFactory implements AbstractMingRenFactory {
    public MingRen createMingRenOfFairy(){
        return new MingRenOBaOfFairy();
    }

    public MingRen createMingRenOfSpiral(){
        return new MingRenBabyOfSpiral();
    }

    public MingRen createMingRenOfSeparate(){
        return new MingRenBabyOfSeparate();
    }
}

⑬生产欧巴期鸣人的工厂

public class MingRenOBaFactory implements AbstractMingRenFactory {
    public MingRen createMingRenOfFairy(){
        return new MingRenBabyOfFairy();
    }

    public MingRen createMingRenOfSpiral(){
        return new MingRenOBaOfSpiral();
    }

    public MingRen createMingRenOfSeparate(){
        return new MingRenOBaOfSeparate();
    }
}

⑭Client实现生产鸣人

public class Client {

    public static void main(String []args){

        //生产baby期的鸣人
        MingRenBabyFactory mingRenBabyFactory=new MingRenBabyFactory();
        //生产欧巴期的鸣人
        MingRenOBaFactory mingRenOBaFactory=new MingRenOBaFactory();

        //生产一个baby期的、会多重影分身术的鸣人
        MingRen babyMingRenOfSeparate=mingRenBabyFactory.createMingRenOfSeparate();
        babyMingRenOfSeparate.getAbility();
        babyMingRenOfSeparate.getAbility();
        babyMingRenOfSeparate.attcak();

        //生产一个欧巴期的、会多重影分身术的鸣人
        MingRen oBaMingRenOfSeparate=mingRenOBaFactory.createMingRenOfSeparate();
        oBaMingRenOfSeparate.getAbility();
        oBaMingRenOfSeparate.getAbility();
        oBaMingRenOfSeparate.attcak();

    }
}

⑮输出结果

//baby期的、会多重影分身术的鸣人
卡通,阿里噶哆~~~   
一次分出多个影分身。
多重影分身术处于baby期。

//欧巴期的、会多重影分身术的鸣人
卡通,阿里噶哆~~~   
一次分出多个影分身。
多重影分身术处于欧巴期。

经过一番改造,终于能够自如的制造出分别在不同期间的不同模式的鸣人。对抽象工厂模式也有一定程度的了解了,下面小Y带大家更加深入的去理解抽象工厂模式

二、基本概念

1.什么是抽象工厂模式

为创建一组相关或相互依赖的对象提供一个接口,无须指定它们的具体类。

2.抽象工厂模式通用UML

通用抽象工厂UML

3.理解

  • 抽象工厂模式是工厂方法模式的升级版本。

  • 两个抽象的产品类可以有关系,比如共同继承或实现一个抽象类或者接口。

  • 抽象工厂类AbstractMingRenFactory的职责是定义baby期鸣人工厂和欧巴期鸣人工厂要实现的职能。鸣人分为仙人模式的鸣人、会多重分身术的鸣人、会旋螺丸的鸣人,因此在抽象工厂中有对应的创建方法。总结起来就是在有N个产品族,在抽象工厂类中就要有N个创建方法。

  • 把鸣人的成长阶段分为baby期和欧巴期,那个就相对应有了baby期鸣人工厂和欧巴期鸣人工厂。即有N个产品等级就应该有N个实现工厂类,在每个实现工厂中,实现不同产品族的生产任务。

  • 在场景类中,没有任何一个方法和实现类有关系,对于一个产品来说,只需要知道它的工厂方法就可以了直接产生一个产品对象,无须关心它的实现类。

4.应用场景

一个对象族有相同的约束,则可以使用抽象工厂模式。就是一个继承体系中,如果存在着多个等级结构,并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。

三、抽象工厂模式优缺点

1.优点

  • 良好的封装性,每个产品的实现类不是高层模块要关心的,主要关心的是接口,只要知道工厂类是什么就可以创建出一个需要的对象。

  • 产品族内的约束为非公开状态,具体的产品族内的约束是在工厂内实现的。

2.缺点

  • 产品扩展困难。比如要增加一个仙人模式+九喇嘛模式,就是说产品族由原来的3个增加到4个,上面例子需要改动的地方就有很多,AbstractMingRenFactory要增加一个创建方法,两个制造不同期间鸣人的工厂也需要修改,违反了开闭原则。

四、总结

抽象工厂模式一个非常常用的模式,但是上面也说到抽象工厂模式的缺点就是扩展比较困难,违反了开闭原则,这里说的难扩展是针对产品族,即是上面的螺旋丸鸣人、仙人模式鸣人、多重分身术鸣人,而不是针对产品等级,即baby期的鸣人、欧巴期的鸣人,增加一个产品等级是非常简单的,只需要继承抽象工厂类即可。

Android技术交流吧

猜你喜欢

转载自blog.csdn.net/kaoshibiguo_1/article/details/78933990