设计模式 – 抽象工厂模式

导读:本篇文章讲解 设计模式 – 抽象工厂模式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

抽象工厂模式 (Abstract Factory Pattern)

一. 概念相关

factory pattern tutorials

目的:提供一个接口,可实现创建一系列相关或依赖的对象,而无需指定他们具体的类

作用:抽象工厂模式提供一种封装一组具有共同性质的工厂方法,而无需指定具体的类(java多态)

适用场景

  1. 工厂一致性封装
  2. 添加新工厂,不改变现有代码
  3. 在一系列工厂,随意调用哪个工厂

使用场景

FileSystem,DataBase,Network,OS

缺陷

  1. 创建工厂给容易,但工厂一些列制造比较繁琐
  2. 工厂模式使用很多类,接口,代码会相较复杂

二.小试牛刀

2.1 背景

指环王相信大家不陌生,里面有多个维度的种族,比如精灵族,兽人族等,现在我们想实现通过传入不同种族,获得对应的国家相关一些列信息(国王,武器,城堡等),那么代码如何实现呢?

2.2 分析图

  • 国家具有的共性属性

国家

国王

城堡

武器


  • 国家分类

国家

精灵族

兽人族

…..

三. UML

KingdomFactory:王国工厂类

ElKingomFactory/OrcKingdomFactory:各王国工厂生产类

King/Army/Castle:王国里共有的属性类

El**/Orc**:各王国里属性实现类

请添加图片描述

四. 代码实现

依赖相关

  <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.7.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

4.1 工厂相关

KingdomFactory

王国工厂:规范接口

/**
 * @author zhanghp
 * @date 2022-08-05 15:08
 */
public interface KingdomFactory {

    /**
     * 国王诞生
     *
     * @return 国王
     */
    King createKing();

    /**
     * 创建城堡
     *
     * @return 城堡
     */
    Castle createCastle();

    /**
     * 制造武器
     *
     * @return 武器
     */
    Army createArmy();
}


ElKingFactory

精灵族工厂

/**
 * @author zhanghp
 * @date 2022-08-05 15:22
 */
@NoArgsConstructor
public class ElKingdomFactory implements KingdomFactory {
    @Override
    public King createKing() {
        return new ElKing();
    }

    @Override
    public Castle createCastle() {
        return new ElCastle();
    }

    @Override
    public Army createArmy() {
        return new ElArmy();
    }
}


OrcKingFactory

兽人工厂

/**
 * @author zhanghp
 * @date 2022-08-05 15:27
 */
public class OrcKingdomFactory implements KingdomFactory {
    @Override
    public King createKing() {
        return new OrcKing();
    }

    @Override
    public Castle createCastle() {
        return new OrcCastle();
    }

    @Override
    public Army createArmy() {
        return new OrcArmy();
    }
}


4.2 工厂属性相关

既然工厂都成型了,下来开始制造每个国王所需的国王,城堡,武器把!

🔱King

国王

/**
 * @author zhanghp
 * @date 2022-08-05 15:14
 */
public interface King {

    /**
     * 国王描述
     *
     * @return 国王描述
     */
    String getDesciption();
}

🏰Castle

城堡

/**
 * @author zhanghp
 * @date 2022-08-05 15:15
 */
public interface Castle {

    /**
     * 城堡描述
     *
     * @return 城堡描述
     */
    String getDesciption();
}

🔫Army

武器

/**
 * @author zhanghp
 * @date 2022-08-05 15:14
 */
public interface Army {

    /**
     * 武器描述
     *
     * @return 武器描述
     */
    String getDesciption();
}

精灵族

🔱ElKing

/**
 * @author zhanghp
 * @date 2022-08-05 15:17
 */
public class ElKing implements King {

    /**
     * 描述
     */
    private final String DESCIPTION = "精灵国王诞生...";

    @Override
    public String getDesciption() {
        return DESCIPTION;
    }
}

🏰ElCastle

/**
 * @author zhanghp
 * @date 2022-08-05 15:18
 */
public class ElCastle implements Castle {

    /**
     * 描述
     */
    private final String DESCIPTION = "精灵族城堡创建...";

    @Override
    public String getDesciption() {
        return DESCIPTION;
    }
}

🔫ElArmy

/**
 * @author zhanghp
 * @date 2022-08-05 15:17
 */
public class ElArmy implements Army {

    /**
     * 描述
     */
    private final String DESCIPTION = "精灵族武器制造...";

    @Override
    public String getDesciption() {
        return DESCIPTION;
    }
}

兽人族

🔱OrcKing

/**
 * @author zhanghp
 * @date 2022-08-05 15:19
 */
public class OrcKing implements King {

    /**
     * 描述
     */
    private final String DESCIPTION = "兽人族国王诞生...";

    @Override
    public String getDesciption() {
        return DESCIPTION;
    }
}

🏰OrcCastle

/**
 * @author zhanghp
 * @date 2022-08-05 15:20
 */
public class OrcCastle implements Castle {

    /**
     * 描述
     */
    private final String DESCIPTION = "兽人族城堡制造...";

    @Override
    public String getDesciption() {
        return DESCIPTION;
    }
}

🔫OrcArmy

/**
 * @author zhanghp
 * @date 2022-08-05 15:19
 */
public class OrcArmy implements Army {

    /**
     * 描述
     */
    private final String DESCIPTION = "兽人族武器制造...";

    @Override
    public String getDesciption() {
        return DESCIPTION;
    }
}

4.3 测试用例

/**
 * @author zhanghp
 * @date 2022-08-05 14:42
 */
@Slf4j
public class AbstractFactoryTest {

    @Test
    void createElvenFactory() {

        // 精灵族工厂制造
        KingdomFactory elven = new ElKingdomFactory();
        // 精灵族武器制造
        Army army = elven.createArmy();
        // 精灵族国王诞生
        King king = elven.createKing();
        // 精灵族制造城堡
        Castle castle = elven.createCastle();

        log.info("{}", king.getDesciption());
        log.info("{}", castle.getDesciption());
        log.info("{}", army.getDesciption());
    }

    @Test
    void createOrcFactory() {

        // 兽人族工厂制造
        KingdomFactory elven = new OrcKingdomFactory();
        // 兽人族国王产生
        King king = elven.createKing();
        // 兽人族制造武器
        Army army = elven.createArmy();
        // 兽人族制造城堡
        Castle castle = elven.createCastle();

        log.info("{}", king.getDesciption());
        log.info("{}", castle.getDesciption());
        log.info("{}", army.getDesciption());
    }
}

五. 代码进阶

​ 在原先基础上,无论生产精灵族,还是兽人族,都需要繁琐的步骤,那可不可以一步就生成呢?

5.1 UML

Kingdom:用于生产国王工厂及相关属性

FactoryIndustry:调用国王工厂,实现统一api调用

请添加图片描述

5.2 代码

Kingdom

/**
 * @author zhanghp
 * @date 2022-08-05 16:33
 */
@Data
public class Kingdom {

    /**
     * 国王
     */
    private King king;

    /**
     * 武器
     */
    private Army army;

    /**
     * 城堡
     */
    private Castle castle;

    public static class FactoryMaker {

        /**
         * 种族
         */
        public enum KingdomType{
            /**
             * 精灵族
             */
            ELVEN,
            /**
             * 兽人族
             */
            ORCISH
        }

        /**
         * 根据王国类型,制造国家
         *
         * @param type 种族类型
         * @return 种族
         */
        public static KingdomFactory makeFartory(KingdomType type){
            KingdomFactory result;
            switch (type){
                case ELVEN:
                    result = new ElKingdomFactory();
                    break;
                case ORCISH:
                    result = new OrcKingdomFactory();
                    break;
                default:
                    throw new IllegalArgumentException("KingdomType not supported");
            }
            return result;
        }
    }
}

FactoryIndustry

/**
 * @author zhanghp
 * @date 2022-08-05 16:49
 */
@NoArgsConstructor
public class FactoryIndustry {

    /**
     * 国家
     */
    private final Kingdom kingdom = new Kingdom();

    /**
     * 获取王国
     *
     * @return 国家
     */
    public Kingdom getKingdom() {
        return this.kingdom;
    }

    /**
     * 制造国家
     *
     * @param type 种族类型
     */
    public void createKingdom(Kingdom.FactoryMaker.KingdomType type) {
        // 国家诞生
        KingdomFactory kingdomFactory = Kingdom.FactoryMaker.makeFartory(type);
        // 设置王位
        kingdom.setKing(kingdomFactory.createKing());
        // 制造城堡
        kingdom.setCastle(kingdomFactory.createCastle());
        // 制造武器
        kingdom.setArmy(kingdomFactory.createArmy());
    }
}

5.3 测试用例

/**
 * @author zhanghp
 * @date 2022-08-05 16:53
 */
@Slf4j
public class FactoryIndustryTest {
    @Test
    void createElven(){
        // 实例化王国工厂调度类
        FactoryIndustry factoryIndustry = new FactoryIndustry();
        // 创建王国
        factoryIndustry.createKingdom(Kingdom.FactoryMaker.KingdomType.ELVEN);
        // 获取王国
        Kingdom kingdom = factoryIndustry.getKingdom();

        log.info("{}", kingdom.getKing().getDesciption());
        log.info("{}", kingdom.getCastle().getDesciption());
        log.info("{}", kingdom.getArmy().getDesciption());
    }
    @Test
    void createOrcish(){
        // 实例化王国工厂调度类
        FactoryIndustry factoryIndustry = new FactoryIndustry();
        // 创建王国
        factoryIndustry.createKingdom(Kingdom.FactoryMaker.KingdomType.ORCISH);
        // 获取王国
        Kingdom kingdom = factoryIndustry.getKingdom();

        log.info("{}", kingdom.getKing().getDesciption());
        log.info("{}", kingdom.getCastle().getDesciption());
        log.info("{}", kingdom.getArmy().getDesciption());
    }
}

六. 源码地址


⭐️源码https://gitee.com/zhp1221/design_pattern/tree/master/lab_01_abstract_factory


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/63260.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!