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

news2024/10/7 3:29:43

目录

      • 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.coloradmin.cn/o/1885870.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

51单片机点亮第一个LED灯

欢迎入群共同学习交流 时间记录&#xff1a;2024/7/2 一、电路原理图 二、代码程序 1.项目代码结构 2.主程序代码 #include <reg51.h>sbit ledP1^0;void delay(int ms) {int i0;while(ms--){for(i0;i<110;i);} }int main() {while(1){led 1;delay(1000);led 0;d…

Retrofit源码阅读

动态代理在 Android 中的应用&#xff1a;Retrofit 源码解析 在之前的文章 《Andriod 网络框架 OkHttp 源码解析》 中我们分析了 OkHttp 的源代码。现在我们就来分析一下 OkHttp 的兄弟框架 Retrofit。关于 Retrofit 的注解的使用&#xff0c;可以参考其官方文档&#xff1a;h…

镜像私服Harbor 2.0安装-探索工厂模式:如何优化Harbor项目管理与API集成

文章目录 一、docker-compose1. 下载 Docker Compose&#xff1a;2.添加执行权限&#xff1a;3.验证安装 二、安装harbor 2.01.下载harbor离线包2. 根据需求配置 Harbor3.给harbor创建SSL证书4.预编译harbor5. 安装并启动 Harbor (必须到你安装的目录) 三、登录harbor的web页面…

Java UU跑腿同城跑腿小程序源码快递代取帮买帮送源码小程序+H5+公众号跑腿系统

&#x1f680;【同城生活小助手】&#x1f680; &#x1f3c3;‍♂️【同城跑腿&#xff0c;即刻送达的便利生活】&#x1f3c3;‍♀️ 在快节奏的都市生活中&#xff0c;时间成了最宝贵的资源。UU跑腿小程序&#xff0c;作为同城生活的得力助手&#xff0c;让你轻松解决生活…

208.贪心算法:买卖股票的最佳时机||(力扣)

代码解决 class Solution { public:int maxProfit(vector<int>& prices) {int result 0; // 初始化结果为0&#xff0c;表示初始利润为0// 从第二天开始遍历价格数组for (int i 1; i < prices.size(); i) {// 如果当天价格比前一天价格高&#xff0c;则将差价加…

学习伦敦金技术分析的具体步骤是什么?

技术分析是我们分析伦敦金市场的重要工具&#xff0c;刚入市就面对时涨时跌的市场应该如何交易呢&#xff1f;投资者如果不掌握技术分析的方法&#xff0c;恐怕对这个问题会没有头绪。入场都没有&#xff0c;盈利就更加无从谈起了。而学习技术分析&#xff0c;是有不同的阶段、…

算法-位图与底层运算逻辑

文章目录 1. 位图的理论基础2. 完整版位图实现3. 底层的运算逻辑-位运算 1. 位图的理论基础 首先我们要理解什么是位图, 位图的一些作用是什么 位图法就是bitmap的缩写。所谓bitmap&#xff0c;就是用每一位来存放某种状态&#xff0c;适用于大规模数据&#xff0c;但数据状态又…

让你500平的大别墅网络信号无死角!一文读懂什么是Mesh

最新的路由器往往拥有超快的速度、多天线和对最新Wi-Fi标准的支持。然而&#xff0c;如果你的设备信号微弱或有死角&#xff0c;再强大的路由器也无济于事。虽然Wi-Fi扩展器是增加网络覆盖范围的廉价替代品&#xff0c;但它们效率低下且带宽较低。 相比之下&#xff0c;Mesh网络…

野外/工地车流计数摄像头,单人即可安装,简单低成本

在野外或工地这样的特殊环境中&#xff0c;对车流进行准确计数对于交通管理、资源调配以及安全保障都具有重要意义。而野外/工地车流计数摄像头的出现&#xff0c;以其单人即可安装、简单低成本的特点&#xff0c;为解决这些场景中的车流统计问题提供了理想的解决方案。 一、野…

【Elasticsearch】一、概述,安装

文章目录 概述全文搜索引擎概述ES&#xff08;7.x&#xff09; 安装ES&#xff08;Docker&#xff09;测试&#xff0c;是否启动成功 可视化工具配置中文 客户端Postman下载 概述 ES是开源的高扩展的分布式全文搜索引擎&#xff0c;实时的存储、检索数据&#xff1b;本身扩展性…

做了个记录心情并结合AI给出建议的小程序

名称&#xff1a;心情记录员 微信小程序名称叫程序记录员&#xff0c;主要功能是记录情绪&#xff0c;然后根据情绪和产生情绪的原因通过AI给出有助于心理健康的建议。同时支持统计功能&#xff0c;可以以查看日历的方式浏览不同日期下情绪的变化轨迹。 主要功能 记录情绪和…

“私域流量:解锁电商新机遇,共创数字化未来“

一、私域流量的战略意义再探 步入数字化浪潮的深处&#xff0c;流量已成为企业成长不可或缺的血液。与广泛但难以掌控的公域流量相比&#xff0c;私域流量以其独特的专属性和复用潜力&#xff0c;为企业铺设了通往深度用户关系的桥梁。它不仅赋能企业实现精准营销&#xff0c;…

应用监控SkyWalking调研

参考&#xff1a; 链路追踪( Skyworking )_skywalking-CSDN博客 企业级监控项目Skywalking详细介绍&#xff0c;来看看呀-CSDN博客 SkyWalking 极简入门 | Apache SkyWalking 使用 SkyWalking 监控 ClickHouse Server | Apache SkyWalking https://zhuanlan.zhihu.com/p/3…

主播一般用什么麦克风?一文看懂哪种麦克风降噪效果好

如今是一个短视频飞速发展的时代&#xff0c;越来越多自媒体人通过短视频的方式来进行直播带货、生活Vlog、线上K歌等&#xff0c;记录下生活里那美丽的瞬间。不过想要拍摄出来的视频作品拥有清晰的音质以及不受环境噪音所影响&#xff0c;那么一款好的麦克风是必不可少的。很多…

Linux驱动开发实战宝典:设备模型、模块编程、I2C/SPI/USB外设精讲

摘要: 本文将带你走进 Linux 驱动开发的世界,从设备驱动模型、内核模块开发基础开始,逐步深入 I2C、SPI、USB 等常用外设的驱动编写,结合实际案例,助你掌握 Linux 驱动开发技能。 关键词: Linux 驱动,设备驱动模型,内核模块,I2C,SPI,USB 一、Linux 设备驱动模型 Li…

如何选择最适合您的短剧系统源码

短剧系统源码是一个帮助用户搭建短剧平台的软件程序。在选择短剧系统源码时&#xff0c;确保选择一个适合您需求的系统是非常重要的。以下是一些关键因素&#xff0c;可以帮助您选择最好的短剧系统源码。 1. 功能丰富性&#xff1a;在选择短剧系统源码之前&#xff0c;您需要明…

ListBox自动滚动并限制显示条数

1、实现功能 限制ListBox显示的最大条数&#xff1b; ListBox自动滚动&#xff0c;显示最新行&#xff1b; 2、C#代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using Syst…

LED显示屏的尺寸及安装比例设计

在现代商业展示和舞美应用中&#xff0c;LED显示屏已成为不可或缺的视觉设备。为了确保LED显示屏的最佳视觉效果和与环境的完美融合&#xff0c;正确的尺寸及安装比例设计尤为重要。本文将从LED显示屏的安装方法、音响系统、控制系统及配电、质量保证备件等方面&#xff0c;探讨…

Snipaste截图工具的下载

Snipaste是一款简单而强大的桌面截图工具&#xff0c;它不仅支持快速截图&#xff0c;还提供了丰富的编辑和贴图功能&#xff0c;极大地提升了用户的工作效率。 网址&#xff1a;Snipaste 下载 1.进入文件夹解压缩 2.解压缩后打开双击运行 3.快捷键F1截图 F3截图固定桌面 …

日志以及日志封装

日志 输出日志信息 import logging# 调用 指定级别 输入日志信息 logging.debug("this is a debug") logging.info("this is a info") logging.warning("this is a warning") logging.error("this is a error") logging.critical(&qu…