秒懂设计模式--学习笔记(5)【创建篇-抽象工厂】

目录

      • 4、抽象工厂
          • 4.1 介绍
          • 4.2 品牌与系列(针对工厂泛滥)(**分类**)
          • 4.3 产品规划(**数据模型**)
          • 4.4 生产线规划(**工厂类**)
          • 4.5 分而治之
          • 4.6 抽象工厂模式的各角色定义如下
          • 4.7 基于此抽象工厂模式以品牌与系列进行全局规划

4、抽象工厂

4.1 介绍
  • 抽象工厂模式(Abstract Factory)是对工厂的抽象化,而不只是制造方法
  • 系统如果按工厂方法那样为每种产品都增加一个新工厂又会造成工厂泛滥
  • 抽象工厂模式提供了另一种思路,将各种产品分门别类
  • 基于此来规划各种工厂的制造接口,最终确立产品制造的顶级规范,使其与具体产品彻底脱钩
  • 抽象工厂是建立在制造复杂产品体系需求基础之上的一种设计模式
  • 在某种意义上,我们可以将抽象工厂模式理解为工厂方法模式的高度集群化升级版
  • 测试类文件
    测试类文件结构
4.2 品牌与系列(针对工厂泛滥)(分类)
  • 产品多元化 --> 工厂泛滥 --> 产业规划与整合
    • A品牌3系列 + B品牌3系列 + …
    • 这便是抽象工厂模式的基础数据模型
    • 分为品牌工厂,系列工厂
4.3 产品规划(数据模型
  • 无论哪种工厂模式,都一定是基于特定的产品特性发展而来的: 从产品建模切入(提取相同点,找出不同点)
  • 例子(星际战争游戏)
  • 分析规划(提取相同点,找出不同点)
    • 兵种:人族、怪兽族…
    • 等级:1及、2级、3级…
  • 建立数据模型
  • 兵种顶层父类
package abstractFactory.entity.abstractt;

/**
 * 兵种抽象类
 **/
public abstract class Unit {
    /**
     * 攻击力
     */
    protected int attack;
    /**
     * 防御力
     */
    protected int defence;
    /**
     * 生命力
     */
    protected int health;
    /**
     * 横坐标
     */
    protected int x;
    /**
     * 纵坐标
     */
    protected int y;

    public Unit(int attack, int defence, int health, int x, int y) {
        this.attack = attack;
        this.defence = defence;
        this.health = health;
        this.x = x;
        this.y = y;
    }

    /**
     * 展示:绘制到图上 (抽象方法交由子类实现)
     */
    public abstract void show();

    /**
     * 攻击(抽象方法交由子类实现)
     */
    public abstract void attack();
}
  • 兵种等级: 各等级兵种类都继承自兵种抽象类Unit,它们对应的攻击力、防御力及生命力也各不相同
    • 初级兵种类LowClassUnit
    • 中级兵种类MidClassUnit
    • 高级兵种类HighClassUnit
package abstractFactory.entity.abstractt;
/**
 * 初级兵种类
 **/
public abstract class LowClassUnit extends Unit{
    public LowClassUnit( int x, int y) {
        super(5, 2, 35, x, y);
    }
}

package abstractFactory.entity.abstractt;
/**
 * 中级兵种类
 **/
public abstract class MidClassUnit extends Unit {
    public MidClassUnit( int x, int y) {
        super(10, 8, 80, x, y);
    }
}
package abstractFactory.entity.abstractt;
/**
 * 高级兵种类
 **/
public abstract class HighClassUnit extends Unit {
    public HighClassUnit( int x, int y) {
        super(25, 30, 300, x, y);
    }
}
  • 定义具体的兵种类
    • 海军陆战队员类Marine
    • 变形坦克类Tank
    • 巨型战舰类Battleship
    • 蟑螂类Roach
    • 毒液类Poison
    • 猛犸类Mammoth
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.LowClassUnit;
/**
 * 海军陆战队员类Marine
 **/
public class Marine extends LowClassUnit {
    public Marine(int x, int y) {
        super(x, y);
    }
    @Override
    public void show() {
        System.out.println("士兵出现在坐标:[" + x + "," + y + "]");
    }
    @Override
    public void attack() {
        System.out.println("士兵用机关枪射击,攻击力:" + attack);
    }
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.MidClassUnit;
/**
 * 变形坦克类Tank
 **/
public class Tank extends MidClassUnit {
    public Tank(int x, int y) {
        super(x, y);
    }
    @Override
    public void show() {
        System.out.println("坦克出现在坐标:[" + x + "," + y + "]");
    }
    @Override
    public void attack() {
        System.out.println("坦克用炮轰击,攻击力:" + attack);
    }
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.HighClassUnit;
/**
 * 巨型战舰类Battleship
 **/
public class Battleship extends HighClassUnit {
    public Battleship(int x, int y) {
        super(x, y);
    }
    @Override
    public void show() {
        System.out.println("战舰出现在坐标:[" + x + "," + y + "]");
    }
    @Override
    public void attack() {
        System.out.println("战舰用激光炮打击,攻击力:" + attack);
    }
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.LowClassUnit;
/**
 * 蟑螂类Roach
 **/
public class Roach extends LowClassUnit {
    public Roach(int x, int y) {
        super(x, y);
    }
    @Override
    public void show() {
        System.out.println("蟑螂兵出现在坐标:[" + x + "," + y + "]");
    }
    @Override
    public void attack() {
        System.out.println("蟑螂兵用爪子挠,攻击力:" + attack);
    }
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.MidClassUnit;
/**
 * 毒液类Poison
 **/
public class Poison extends MidClassUnit {
    public Poison(int x, int y) {
        super(x, y);
    }
    @Override
    public void show() {
        System.out.println("毒液兵出现在坐标:[" + x + "," + y + "]");
    }
    @Override
    public void attack() {
        System.out.println("毒液兵用毒液喷射,攻击力:" + attack);
    }
}

package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.HighClassUnit;
/**
 * 猛犸类Mammoth
 **/
public class Mammoth extends HighClassUnit {
    public Mammoth(int x, int y) {
        super(x, y);
    }
    @Override
    public void show() {
        System.out.println("猛犸巨兽出现在坐标:[" + x + "," + y + "]");
    }
    @Override
    public void attack() {
        System.out.println("猛犸巨兽用獠牙顶,攻击力:" + attack);
    }
}
  • 所有兵种类已定义完毕,代码不是难点,重点集中在对兵种的划分上
  • 横向划分族,纵向划分等级(系列),利用类的抽象与继承描绘出所有的游戏角色以及它们之间的关系,同时避免了不少重复代码
4.4 生产线规划(工厂类
  • 数据模型构建完成,定义工厂,建立生产线
    • 定义了6个兵种产品(数据模型):实体
    • 可分为2个工厂:人族、怪兽族
    • 3个制造标准:3个等级
  • 定义抽象工厂接口:
    • 3个制造标准方法
package abstractFactory.factory;

import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;

/**
 * 定义抽象工厂接口 : 抽象兵工厂接口
 *      抽象兵工厂接口定义了3个等级兵种的制造标准, 这意味着子类工厂必须具备初级、中级、高级兵种的生产能力
 **/
public interface AbstractFactory {
    /**
     * 初级兵种制造标准
     * @return
     */
    LowClassUnit createLowClassUnit();
    /**
     * 中级兵种制造标准
     * @return
     */
    MidClassUnit createMidClassUnit();
    /**
     * 高级兵种制造标准
     * @return
     */
    HighClassUnit createHighClassUnit();
}
  • 工厂类实现
package abstractFactory.factory.impl;

import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;
import abstractFactory.entity.product.Battleship;
import abstractFactory.entity.product.Marine;
import abstractFactory.entity.product.Tank;
import abstractFactory.factory.AbstractFactory;
/**
 * 人类兵工厂
 **/
public class HumanFactory implements AbstractFactory {
    /**
     * 横坐标
     */
    private int x;
    /**
     * 纵坐标
     */
    private int y;
    public HumanFactory(int x, int y) {
        this.x = x;
        this.y = y;
    }
    @Override
    public LowClassUnit createLowClassUnit() {
        LowClassUnit unit = new Marine(x, y);
        System.out.println("制造海军陆战队员成功。");
        return unit;
    }
    @Override
    public MidClassUnit createMidClassUnit() {
        MidClassUnit unit = new Tank(x, y);
        System.out.println("制造变形坦克成功。");
        return unit;
    }
    @Override
    public HighClassUnit createHighClassUnit() {
        HighClassUnit unit = new Battleship(x, y);
        System.out.println("制造巨型战舰成功。");
        return unit;
    }
}
package abstractFactory.factory.impl;

import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;
import abstractFactory.entity.product.Mammoth;
import abstractFactory.entity.product.Poison;
import abstractFactory.entity.product.Roach;
import abstractFactory.factory.AbstractFactory;

/**
 * 外星母巢(工厂)
 **/
public class AlienFactory implements AbstractFactory {
    private int x;
    private int y;
    public AlienFactory(int x, int y) {
        this.x = x;
        this.y = y;
    }
    @Override
    public LowClassUnit createLowClassUnit() {
        LowClassUnit roach = new Roach(x, y);
        System.out.println("制造蟑螂兵成功。");
        return roach;
    }
    @Override
    public MidClassUnit createMidClassUnit() {
        MidClassUnit poison = new Poison(x, y);
        System.out.println("制造毒液兵成功。");
        return poison;
    }
    @Override
    public HighClassUnit createHighClassUnit() {
        HighClassUnit mammoth = new Mammoth(x, y);
        System.out.println("制造猛犸巨兽成功。");
        return mammoth;
    }
}

  • 生产线规划非常清晰
    • 人类兵工厂与外星母巢分别实现了3个等级兵种的制造方法
    • 其中前者由低到高分别返回海军陆战队员、变形坦克以及巨型战舰对象,
    • 后者则分别返回蟑螂兵、毒液兵以及猛犸巨兽对象
  • 测试使用
    • 抽象兵工厂接口引用了人类兵工厂实现
    • 调用3个等级的制造方法分别得到人类族的对应兵种
    • 将抽象兵工厂接口引用替换为外星母巢实现
    • 制造出的兵种变为3个等级的外星怪兽族兵种
    • 如果玩家需要一个新族加入,我们可以在此模式之上去实现一个新的族工厂并实现3个等级的制造方法
    • 工厂一经替换即可产出各系列产品兵种,且无须改动现有代码,良好的可扩展性
    • 这就是一套拥有完备生产模式的标准化工业系统所带来的好处
package abstractFactory;

import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;
import abstractFactory.entity.abstractt.Unit;
import abstractFactory.factory.AbstractFactory;
import abstractFactory.factory.impl.AlienFactory;
import abstractFactory.factory.impl.HumanFactory;
/**
 * 测试客户端类
 **/
public class Client {
    /**
     *  打印结果
     *      游戏开始......
     *      双方挖掘攒钱......
     *      建造人类族工厂.......
     *      制造海军陆战队员成功。
     *      士兵出现在坐标:[10,10]
     *      制造变形坦克成功。
     *      坦克出现在坐标:[10,10]
     *      制造巨型战舰成功。
     *      战舰出现在坐标:[10,10]
     *      建造外星怪兽族工厂
     *      制造蟑螂兵成功。
     *      蟑螂兵出现在坐标:[200,200]
     *      制造毒液兵成功。
     *      毒液兵出现在坐标:[200,200]
     *      制造猛犸巨兽成功。
     *      猛犸巨兽出现在坐标:[200,200]
     *      两族开始混战......
     *      士兵用机关枪射击,攻击力:5
     *      蟑螂兵用爪子挠,攻击力:5
     *      毒液兵用毒液喷射,攻击力:10
     *      坦克用炮轰击,攻击力:10
     *      猛犸巨兽用獠牙顶,攻击力:25
     *      战舰用激光炮打击,攻击力:25
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("游戏开始......");
        System.out.println("双方挖掘攒钱......");

        // 第一位玩家选择了人类族
        System.out.println("建造人类族工厂.......");
        // 抽象兵工厂接口引用了人类兵工厂实现
        AbstractFactory factory = new HumanFactory(10, 10);

        Unit marine = factory.createLowClassUnit();
        marine.show();

        Unit tank = factory.createMidClassUnit();
        tank.show();

        Unit ship = factory.createHighClassUnit();
        ship.show();

        // 第二位万家选择了外星怪兽族
        System.out.println("建造外星怪兽族工厂");
        /**
         * 抽象兵工厂接口引用替换为外星母巢实现
         * 工厂一经替换即可产出各系列产品兵种,且无须改动现有代码,良好的可扩展性
          */
        factory = new AlienFactory(200, 200);

        Unit roach = factory.createLowClassUnit();
        roach.show();

        Unit poison = factory.createMidClassUnit();
        poison.show();

        Unit mammoth = factory.createHighClassUnit();
        mammoth.show();

        System.out.println("两族开始混战......");
        marine.attack();
        roach.attack();
        poison.attack();
        tank.attack();
        mammoth.attack();
        ship.attack();
    }
}
4.5 分而治之
  • 抽象工厂制造模式已经布局完成,各工厂可以随时大规模投入生产活动了
  • 我们还可以进一步,再加一个“制造工厂的工厂”来决定具体让哪个工厂投入生产活动
  • 此时客户端就无须关心工厂的实例化过程了,直接使用产品就可以了
  • 这也是抽象工厂可以被视为“工厂的工厂”的原因
  • 与工厂方法模式不同,抽象工厂模式能够应对更加复杂的产品族系,它更类似于一种对“工业制造标准”的制定与推行
    • 各工厂实现都遵循此标准来进行生产活动
    • 工厂类划分产品族(工厂类)
    • 制造方法划分产品系列(数据模型)
    • 达到无限扩展产品的目的
4.6 抽象工厂模式的各角色定义如下
  • 产品系列的抽象类:
    • AbstractProduct1、AbstractProduct2(抽象产品1、抽象产品2)
    • 一系产品与二系产品分别代表同一产品族多个产品系列,对应本章例程中的初级、中级、高级兵种抽象类
  • 继承自抽象产品的产品实体类(数据模型)
    • ProductA1、ProductB1、ProductA2、ProductB2(产品A1、产品B1、产品A2、产品B2)
    • 其中ProductA1与ProductB1代表A族产品与B族产品的同一产品系列,类似于例中人类族与外星怪兽族的初级兵种
  • 抽象工厂接口(AbstractFactory)
    • 各族工厂的高层抽象,可以是接口或者抽象类
    • 抽象工厂对各产品系列的制造标准进行规范化定义,但具体返回哪个族的产品由具体族工厂决定,它并不关心。
  • 工厂实现类:
    • ConcreteFactoryA、ConcreteFactoryB(工厂A实现、工厂B实现)
    • 继承自抽象工厂的各族工厂,需实现抽象工厂所定义的产品系列制方法,可以扩展多个工厂实现。
    • 对应本章例程中的人类兵工厂与外星母巢
  • Client(客户端):
    • 产品的使用者,只关心制造出的产品系列,具体是哪个产品族由工厂决定
4.7 基于此抽象工厂模式以品牌与系列进行全局规划
  • 抽象工厂模式一定是基于产品的族系划分来布局的
  • 产品系列一定是相对固定的
  • 故以抽象工厂来确立工业制造标准(各产品系列生产接口)
  • 而产品族则可以相对灵活多变

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/766025.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

本地文本向量模型的部署提供兼容openai的接口

前言 之前部署了fastgpt官方文档的一个,提供的一个m3e-large的向量模型打包的docker镜像,虽然使用起来整体效果还可以,但是有些文本向量相似度匹配的结果还是不太满意的,目前,网络上层出不穷的带推理文本向量,想体验一下,于是我基于modelscope库封装了一个兼容open ai的…

有哪些Python书籍是程序员强烈推荐?

有一本升级版的经典Python项目编程书一定要推荐一下。 Python极客项目编程(第2版) 第一版累计销售19万册,豆瓣评分8.4。每个项目都按照【讲解原理-分析需求-代码精讲-知识小结-扩展练习-完整代码】的方式进行讲解,并提供可下载运…

【文档+源码+调试讲解】科研经费管理系统

目 录 目 录 摘 要 ABSTRACT 1 绪论 1.1 课题背景 1.2 研究现状 1.3 研究内容 2 系统开发环境 2.1 vue技术 2.2 JAVA技术 2.3 MYSQL数据库 2.4 B/S结构 2.5 SSM框架技术 3 系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 操作可行性 3.1.3 经济可行性 3.1…

实习总结 --- 内部平台使用

常用术语 CR CR–标准问题分类管理平台:由业务类型-角色-国家-品类-Page定义。 FAQSOP FAQ是端上用户自助的第一道关口,在引导用户进行自助解决上起关键作用 SOP是指标准作业程序,客服SOP是针对用户遇到的具体问题场景,给客服…

论文阅读【时间序列】DSformer

论文阅读【时间序列】DSformer arxive: DSformer: A Double Sampling Transformer for Multivariate Time Series Long-term Prediction github: MTST 分类:多变量时间序列(Multivariate time series) 核心观点 多变量时间序列3个维度信息 …

从零开始实现大语言模型(一):概述

1. 前言 大家好,我是何睿智。我现在在做大语言模型相关工作,我用业余时间写一个专栏,给大家讲讲如何从零开始实现大语言模型。 从零开始实现大语言模型是了解其原理及领域大语言模型实现路径的最好方法,没有之一。已有研究证明&…

ArcGIS中将测绘数据投影坐标(平面坐标)转地理坐标(球面经纬度坐标)

目录 前言1.测绘数据预览1.1 确定带号1.2 为什么是对Y轴分带,而不是对X轴分带? 2 测绘数据转shp2.1 添加数据2.2 显示XY数据2.3 添加经纬度字段2.4 计算经纬度 3.shp数据重投影4.总结 前言 最近在刚好在做一个小功能,将测绘数据转为经纬度坐标…

一些硬件知识(十二)

X电容是接在火线和零线之间,Y电容是接在火零线和地之间。X电容滤除差模干扰,Y电容滤除共模干扰: 高频干扰信号经过X电容后幅度没有变化,相位相差180度: DW01电池管理芯片: M1、M2:这两个为N沟道…

BMA530 运动传感器

型号简介 BMA530是博世(bosch-sensortec)的一款运动传感器。时尚简约的可穿戴设备为功能强大的组件提供了很小的空间。具有先进功能集的下一代加速度计是世界上最小的加速度传感器(1.2 x 0.8 x 0.55 mm)。它专为紧凑型设备而设计&…

本地项目推送到gitlab仓库的保姆级教程

目录 1、安装git (1)Windows系统 (2)Linux系统 2、gitlab创建空白项目 3、创建密钥 4、将密钥添加到gitlab中 5、远程配置 (1)配置全局的用户和邮箱 (2)本地文件夹初始化 …

【代码随想录】【算法训练营】【第52天】 [647]回文子串 [516]最长回文子序列

前言 思路及算法思维,指路 代码随想录。 题目来自 LeetCode。 day 52,周五,开始补作业了~ 题目详情 [647] 回文子串 题目描述 647 回文子串 解题思路 前提:寻找回文子串,子串意味着元素连续 思路:…

Python-Tkinter+Logging+Sqlserver项目结合

参考文章: https://www.jb51.net/article/283745.htm 目录: common(文件夹) – base.py – config_reader.py – dosqlserver.py – log.py txt(空文件夹,后面会自动生成txt文件在该文件夹下面) 1.txt 2.txt env.…

非平稳信号的时频表示-基于本征模态函数(MATLAB)

时频分析思想萌芽于匈牙利物理学家 Gabor 在 1946 年所提出的 Gabor 展开理论,随后以此为基础发展出著名的线性时频变换方法—短时傅里叶变换。短时傅里叶变换假设分析信号在有限时长内具有平稳特性,它首先将时间与频率均为有限支撑的窗函数与分析信号进…

973. 最接近原点的 K 个点-k数组维护+二分查找

973. 最接近原点的 K 个点-k数组维护二分查找 给定一个数组 points ,其中 points[i] [xi, yi] 表示 X-Y 平面上的一个点,并且是一个整数 k ,返回离原点 (0,0) 最近的 k 个点。 这里,平面上两点之间的距离是 欧几里德距离&#…

Linux修炼之路之进程概念,fork函数,进程状态

目录 一:进程概念 二:Linux中的进程概念 三:用getpid(),getppid()获取该进程的PID,PPID 四:用fork()来创建子进程 五:操作系统学科的进程状态 六:Linux中的进程状态 接下来的日子会顺顺利利&#xf…

【MySQL备份】Percona XtraBackup加密备份实战篇

目录 1.前言 2.准备工作 2.1.环境信息 2.2.配置/etc/my.cnf文件 2.3.授予root用户BACKUP_ADMIN权限 2.4.生成加密密钥 2.5.配置加密密钥文件 3.加密备份 4.优化加密过程 5.解密加密备份 6.准备加密备份 7.恢复加密备份 7.1.使用rsync进行恢复 7.2.使用xtrabackup命令恢…

crewAI实践过程中,memory规避openai的使用方法以及(windows下xinferece框架使用踩过的坑)

问题: 在使用crewAI开发项目的过程中,memory开启后报错:openai key is fake 经代码核查,其默认使用了openai的embedding模型。 解决方法 经查阅资料,可以参考其本地部署llm的方法。 本地部署模型可以使用xinference…

人工智能导论速成笔记

文章目录 前言考试题型第一章、人工智能导引 (10分 )课后习题第二章、Python基础 (10分 )*文件读写NumPy的使用Python绘图基础第三章、机器学习初步(15分 )逻辑回归分类(Logistic Regression)*,3.5线性回归预测(Linear Regression)*,3.6 、3.7、 3.8聚类 3.9第四章、自然语言…

【信息系统项目管理师】常见图表

作文里面的画图题用语言描述画图过程 合同 采购综合评分标准 责任分配矩阵 成本预算表 成本估算 成本管理计划 活动清单 活动属性 变更日志 问题日志 项目章程 自己再添加更多内容 甘特图 甘特图包含以下三个含义: 1、以图形或表格的形式显示活动; 2、…

uniapp封装虚拟列表滚动组件

uniapp封装虚拟列表滚动组件 这里用到一个列表&#xff0c;然后数据可能有很多很多…&#xff0c;一次性全部渲染到dom上会卡顿&#xff0c;很废性能&#xff0c;于是用了这个虚拟列表就变丝滑很多很多。 组件mosoweInventedList 代码&#xff1a; <!-- 虚拟滚动列表组件&a…