设计模式(二)-创建者模式(3)-抽象工厂模式

一、为什么需要抽象工厂模式?

在工厂模式中,我们需要定义多个继承于共同工厂抽象基类的工厂子类,这些子类负责创建一个对应的对象。工厂模式存在一个缺点就是:每次扩展新的工厂子类,就会增加系统的复杂度。

如果我们知道把所有产品(比如车)分为几个产品族(比如自行车族、汽车族),那么工厂子类就对应指定的产品族进行“批量”创建对象。若有新的产品,则工厂子类创建该新产品对象。(工厂子类内部逻辑,类似于简单工厂模式)

抽象工厂模式 ,类似于简单工厂模式和工厂模式混合运用而成的模式。(参考上篇文章“工厂模式”的最后一个代码例子)

优点: 不需要每次定义一个新的产品类时,就要扩展新的工厂子类。工厂子类提供一个产品族中多个对象的创建工作,客户端可以方便使用某个产品族中的对象。

缺点: 产品族扩展难。要增加一个新系列的某一产品,要定义产品抽象类、产品实现类,工厂抽象基类,工厂子类。

【角色】
某系列抽象基类: 用以定义某产品族的特征和行为的抽象接口。
某系列的某产品实现类: 继承某系列抽象基类,用以实现某系列里某产品的特征和行为的具体类。
工厂抽象基类: 用以定义创建对象的特征的抽象接口。特征行为包括提供某系列产品的抽象方法。
工厂子类: 对对应的实现类进行实例化。实现提供某系列某产品的方法。

请添加图片描述

二、例子

需求: 假定某些地方的主要交通工具有自行车和汽车。为了满足人们交通便利的需求,现有XX公司和YY公司这两家公司,对市场推行了两种运营模式:租车和共享车。也就是说,租车和共享车是这两家公司所推广的两个产品系列业务,即两个产品族。

1)定义产品族和具体产品


//共享车系列(产品族)
    public abstract class Share
    {
        public abstract void Move();
    }
    
//租借车系列
    public abstract class Rent
    {
        public abstract void Move();
    }

//XX公司-共享-自行车
    public class XXBikeShare : Share
    {
        public override void Move(){
            Console.WriteLine("Share XXBike move.");
        }
    }
    
//XX公司-共享-汽车
    public class XXCarShare : Share
    {
        public override void Move(){
            Console.WriteLine("share XXCar move.");
        }
    }
    
//XX公司-租借-自行车
    public class XXBikeRent : Rent
    {
        public override void Move(){
            Console.WriteLine("Rent XXBike move.");
        }
    }

//XX公司-租借-汽车
    public class XXCarRent : Rent
    {
        public override void Move(){
            Console.WriteLine("Rent XXCar move.");
        }
    }

//YY公司-共享-自行车
    public class YYBikeShare : Share
    {
        public override void Move() {
            Console.WriteLine("share YYBike move.");
        }
    }

//YY公司-共享-汽车
    public class YYCarShare : Share
    {
        public override void Move() {
            Console.WriteLine("share YYCar move.");
        }
    }

//YY公司-租借-自行车
    public class YYBikeRent : Rent
    {
        public override void Move(){
            Console.WriteLine("Rent YYBike move.");
        }
    }

//YY公司-租借-汽车
    public class YYCarRent : Rent
    {
        public override void Move(){
            Console.WriteLine("Rent YYCar move.");
        }
    }

2)定义工厂基类和工厂子类


//定义提供两个产品族的抽象方法
    public abstract class Factory
    {
        public abstract Share ProvideS(string args);
        public abstract Rent ProvideR(string args);
    }

//XX公司落实产品业务:租借和共享
    public class XXFactory : Factory
    {
        public override Share ProvideS(string args)
    {
            Share share = null;
            switch (args)
            {
                case "XXBike":
                    share = new XXBikeShare(); break;
                case "XXCar":
                    share = new XXCarShare(); break;
                default:
                    throw new ArgumentException("args is Invalid. new obj failed.");
            }

            return share;
        }

        public override Rent ProvideR(string args)
        {
            Rent rent = null;
            switch (args)
            {
                case "XXBike":
                    rent = new XXCarRent(); break;
                case "XXCar":
                    rent = new XXBikeRent(); break;
                default:
                    throw new ArgumentException("args is Invalid. new obj failed.");
            }

            return rent;
        }
    }
    
//YY公司落实产品业务:租借和共享
    public class YYFactory : Factory
    {
        public override Share ProvideS(string args)
        {
            Share share = null;
            switch (args)
            {
                case "YYBike":
                    share = new YYBikeShare(); break;
                case "YYCar":
                    share = new YYCarShare(); break;
                default:
                    throw new ArgumentException("args is Invalid. new obj failed.");
            }

            return share;
        }

        public override Rent ProvideR(string args)
        {
            Rent rent = null;
            switch (args)
            {
                case "YYBike":
                    rent = new YYBikeRent(); break;
                case "YYCar":
                    rent = new YYCarRent(); break;
                default:
                    throw new ArgumentException("args is Invalid. new obj failed.");
            }

            return rent;
        }
    }

3)在客户端使用


class Program
    {
        static void Main(string[] args)
        {
            Factory xx = new XXFactory();
            Factory yy = new YYFactory();

            var sharexxCar = xx.ProvideS("XXCar");
            sharexxCar.Move();

            var rentyyBike = yy.ProvideR("YYBike");
            rentyyBike.Move();

            Console.ReadLine();
        }
    }

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

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

相关文章

【shell】 1、bash语法超详细介绍

文章目录 修改前缀路径dirname set常用函数参数变量local 返回值正则打印第 n 行获取行号核对数据库各表数量jq查询检查日志 sshpassexpect数组xargs bash manual 修改前缀 参考 export PS1"bash> "路径 dirname strip last component from file name dir$(…

AWS云服务器EC2实例实现ByConity快速部署

1. 前言 亚马逊是全球最大的在线零售商和云计算服务提供商。AWS云服务器在全球范围内都备受推崇,被众多业内人士誉为“云计算服务的行业标准”。在国内,亚马逊AWS也以其卓越的性能和服务满足了众多用户的需求,拥有着较高的市场份额和竞争力。…

小小发票拦住出海“巨头”,合合信息智能文档处理技术助力企业重塑财务管理流程

作为连接企业采购、生产、运营、销售等经营行为的枢纽,财务系统的数字化、智能化升级近年来变得愈发重要。发票的录入、存储关乎企业应收账款管理和税务规范,通过技术手段提升发票管理的精准度与效率,也成为了财务数字化的关键环节。 近日&a…

MTK Pump Express 快速充电原理分析

1 MTK PE 1.1 原理 在讲正文之前,我们先看一个例子。 对于一块电池,我们假设它的容量是6000mAh,并且标称电压是3.7V,换算成Wh(瓦时)为单位的值是22.3Wh(6000mAh*3.7V);普通的充电器输出电压电流是5V2A(10W)&#xff0c…

ModStartCMS v7.6.0 CMS备份恢复优化,主题开发文档更新

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用,支持后台一键快速安装,让开发者能快的实现业务功能开发。 系统完全开源,基于 Apache 2.0 开源协议,免费且不限制商业使用。 功能特性 丰富的模块市…

『亚马逊云科技产品测评』活动征文|构建生态农场家禽系统

『亚马逊云科技产品测评』活动征文|构建生态农场家禽系统 授权声明:本篇文章授权活动官方亚马逊云科技文章转发、改写权,包括不限于在 Developer Centre, 知乎,自媒体平台,第三方开发者媒体等亚马逊云科技官方渠道 前…

.NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不仅仅是技术还有人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔 !背景介绍 突然闯到路径搜索算法里…

智能货柜:无人零售行业的新宠

智能货柜:无人零售行业的新宠 与早期的传统自动售货机相比,智能货柜的投放场景正呈现多样化的趋势。除了人流密集的公共场所,一些办公室、健身房等室内场景也成为商家争相争夺的热门位置。 其次,在无人零售行业中,许多…

2023-简单点-树莓派picamera2介绍和要点

picamera2 requirements简介preview windows预览窗口GtGL preview【有 x windwows情况下 硬件加速】Qt preview【软件加速】DRM/KMS preview【没有 x windwows情况下】NULL previewpreview的一些其他特征 配置camera配置的细节 捕捉图像capture images切换模式 requirements简…

【MySQL】细谈SQL高级查询

文章目录 一、前言 & 准备工作二、简易高级查询⚙ 准备工作1、查询每一门课程及其先修课程2、查询和“刘涛”在一个班级的学生的信息3、查询选修了‘计算机基础’课的学生的学号、姓名③ 连接方式④ 子查询嵌套方式 4、查询没有选修课程的学生的信息① 子查询in方式② 子查…

typora整理markdown笔记

效果 符号 快捷键 斜体 * * ctrlB(代表同时按) 加粗 ** ** ctrlI 竖线 > 超链接 清除样式 ctrl\ 图片 ![图片描述][图片绝对路径/相对路径] 如何在Typora中插入图像? ➊ 使用Markdown语法 (不推荐,太慢) ➋ 直接拷贝图…

nvm 安装后出现的各种问题解决方法

1、nvm安装后无法安装node版本 首先需要确定删除了电脑上所有的node版本,如果不会卸载那么请移步到 查看 ,我们是要通过nvm来下载node环境,所以之前下载的node有冲突,所以都要清除。 2、下载后的nvm环境,无法使用node、…

Linux入门攻坚——6、磁盘管理——分区及文件系统管理

磁盘管理主要涉及分区的管理,以及分区后的文件系统管理。 磁盘的使用大体要分两步: 文件系统也是一个软件,根是自引用的。 文件系统的全局结构:物理格式: 一个磁盘刚被生产出来的时候,它里边没有划分扇区…

[OpenAirInterface-01]什么是OAI?OAI在github中源代码的存放结构

文章目录 前言:什么是软件无线电SDR第1章 什么是OAI(OpenAirInterface)1.1 来自官网的概述1.2 来自github的概述1.3 来自我的解读 第2章 什么是OSA2.1 OSA概述:2.2 OSA联盟职责2.3 OpenAirInterface github成员的角色 第3章 常见的…

服务号转为订阅号可以吗

服务号和订阅号有什么区别?服务号转为订阅号有哪些作用?很多小伙伴想把服务号改为订阅号,但是不知道改了之后具体有什么作用,今天跟大家具体讲解一下。首先我们知道服务号一个月只能发四次文章,但是订阅号每天都可以发…

赴日开发工程师是做什么的?

日本的软件开发岗位对技术要求和沟通能力都有较高的要求,赴日开发工程师主要负责软件设计、开发和测试,包括编写代码、测试代码和修复漏洞等工作。开发人员必须对软件架构、设计模式和业务逻辑有深入的理解,并能做出合适的技术决策。 当然&a…

探索SPI:深入理解原理、源码与应用场景

文章目录 一、初步认识1、概念2、工作原理3、作用场景 二、源码分析1、ServiceLoader结构2、相关字段3、核心方法 三、案例connector连接器小案例1、新建SPI项目2、创建扩展实现项目1-MongoDB3、创建扩展实现项目2-Oracle4、测试 Spring应用1、创建study工程2、创建forlan-test…

系列六、多线程集合不安全

一、多线程List集合不安全 1.1、List集合不安全案例代码 /*** Author : 一叶浮萍归大海* Date: 2023/11/20 12:38* Description: 多线层环境下List集合不安全案例代码*/ public class NotSafeListMainApp {public static void main(String[] args) {List<String> list …

使用JDK自带java.util.logging.Logger引起的冲突问题

现象&#xff1a; 应用代码如下&#xff1a; import javax.script.ScriptEngineManager;ScriptEngineManager manager new ScriptEngineManager(); manager.getEngineByName("JavaScript"); 在TongWeb8上运行出错&#xff0c;日志如下&#xff1a; Servlet.servi…

反渗透水处理成套设备有哪些

反渗透水处理成套设备主要包括反渗透装置、预处理系统、控制系统等部分。 反渗透装置&#xff1a;反渗透水处理设备的核心部分&#xff0c;由反渗透膜、压力容器、膜组件等组成。反渗透膜是一种高分子材料制成的半透膜&#xff0c;能够截留水中的溶解盐、有机物、细菌等杂质&a…