设计模式-抽象工厂模式

抽象工厂模式

    • 1、抽象工厂模式简介
    • 2、具体实现

1、抽象工厂模式简介

  抽象工厂模式(Abstract Factory Pattern)在工厂模式尚添加了一个创建不同工厂的抽象接口(抽象类或接口实现),该接口可叫做超级工厂。在使用过程中,我们首先通过抽象接口创建不同的工厂对象,然后根据不同的工厂对象创建不同的对象。

  我们可以将工厂模式理解为针对一个产品维度进行分类,比如上述工厂模式下的苹果手机和华为手机;而抽象工厂模式针对的是多个产品维度的分类,比如苹果公司既制造苹果手机又制造苹果笔记本电脑,同样,华为公司既制造华为手机也制造华为笔记本电脑。

  在同一个厂商有多个维度的产品时,如果使用工厂模式,则势必会存在多个独立的工厂,这样的话,设计和物理世界是不对应的,正确的做法是通过抽象工厂模式来实现。我们可以将抽象工厂类比成厂商(苹果、华为),将通过抽象工厂创建出来的工厂类比成不同产品的生产线(手机生产线、笔记本电脑生产线),在需要生产产品时根据抽象工厂生产。

  工厂模式定义了工厂方法来实现不同厂商手机的制造。可是问题来了,我们知道苹果公司和华为公司不仅制造手机,还制造电脑。如果使用工厂模式,就需要实现两个工厂类,并且这两个工厂类没有多大关系,这样的设计显然不够优雅,那么如何实现呢?使用抽象工厂就能很好地解决上述问题。我们定义一个抽象工厂,在抽象工厂中定义好要生产的产品(手机或者电脑),然后在抽象工厂的实现类中根据不同类型的产品和产品规格生产不同的产品返回给用户。
在这里插入图片描述

2、具体实现

  第1类产品的手机接口及其实现类的定义如下:

public interface Phone {String call();
}
public class PhoneApple implements Phone {@Overridepublic String call() {return "call somebody by apple phone";}
}
public class PhoneHuaWei implements Phone {@Overridepublic String call() {return "call somebody by huawei phone";}
}

  以上代码定义了Phone的接口及其实现类PhoneApplePhoneHuaWei。在该接口中定义了一个打电话的方法call(),实现类根据其品牌打印相关信息。

  第1类产品的手机工厂类的定义如下:

public class PhoneFactory extends AbstractFactory{@Overridepublic Phone createPhone(String brand) {if("HuaWei".equals(brand)){return new PhoneHuaWei();}else if("Apple".equals(brand)){return new PhoneApple();}else{return null;}}@Overridepublic Computer createComputer(String brand) {return null;}
}

  以上代码定义了PhoneFactory的手机工厂类,该类继承了AbstractFactory并实现了方法createPhone(),createPhone()根据不同的此参数实例化不同品牌的手机类并返回。在createPhone()的参数为“HuaWei”时,工厂类为我们实例化一个PhoneHuaWei类的实例并返回;在createPhone()的参数为"Apple"时,工厂类为我们实例化一个PhoneApple类的实例并返回,这样便满足了工厂根据不同参数生产不同产品的需求。

  第2类产品的电脑接口及实现类的定义如下:

public interface Computer {String internet();
}
public class ComputerApple implements Computer {@Overridepublic String internet() {return "surf the internet by apple computer";}
}
public class ComputerHuaWei implements Computer {@Overridepublic String internet() {return "surf the internet by huawei computer";}
}

  以上代码定义了Computer的电脑接口及其实现类ComputerAppleComputerHuaWei。在该接口中定义了一个上网的方法internet(),实现类根据其品牌打印相关信息。

  第2类产品的电脑工厂类定义如下:

public class ComputerFactory extends AbstractFactory {@Overridepublic Phone createPhone(String brand) {return null;}@Overridepublic Computer createComputer(String brand) {if("HuaWei".equals(brand)){return new ComputerHuaWei();}else if("Apple".equals(brand)){return new ComputerApple();}else{return null;}}
}

  以上代码定义了ComputerFactory的手机工厂类,该类继承了AbstractFactory并实现了方法createComputer(),createComputer()根据不同的此参数实例化不同品牌的电脑类并返回。在createComputer()的参数为“HuaWei”时,工厂类为我们实例化一个ComputerHuaWei类的实例并返回;在createComputer()的参数为"Apple"时,工厂类为我们实例化一个ComputerApple类的实例并返回,这样便满足了工厂根据不同参数生产不同产品的需求。

  抽象工厂的定义如下:

public abstract class AbstractFactory {public abstract Phone createPhone(String brand);public abstract Computer createComputer(String brand);
}

  以上代码定义了抽象类AbstractFactory,这个类是抽象工厂的核心类,它定义了两个方法createPhone()createComputer(),用户在需要手机时调用其createPhone()构造一个手机(华为或者苹果品牌)即可,用户在需要电脑时调用其createComputer()构造一个电脑(华为或者苹果品牌)即可。

  使用抽象工厂:

//使用抽象工厂
public static void main(String[] args) {PhoneFactory phoneFactory = new PhoneFactory();Phone huaWei = phoneFactory.createPhone("HuaWei");Phone apple = phoneFactory.createPhone("Apple");System.out.println(huaWei.call());System.out.println(apple.call());ComputerFactory computerFactory = new ComputerFactory();Computer computerHuaWei = computerFactory.createComputer("HuaWei");Computer computerApple = computerFactory.createComputer("Apple");System.out.println(computerHuaWei.internet());System.out.println(computerApple.internet());
}

  以上代码使用了我们定义好的抽象工厂,在需要生产商品时,首先需要定义一个抽象的工厂类AbstractFactory,然后使用抽象的工厂类生产不同的工厂类,最终根据不同的工厂生产不同的产品。运行结果如下:

image-20230612000119182

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NoSQL之 Redis配置与优化

文章目录 一、关系数据库与非关系型数据库关系型数据库:非关系型数据库关系型数据库和非关系型数据库区别:非关系型数据库产生背景 二、Redis简介Redis 具有以下几个优点:使用场景:哪些数据适合放入缓存中Redis为什么这么快 三、R…

4、数据库操作语句:聚合函数

目录 1、定义 2、常用的聚合函数 1)Avg/sum:只适用于数值类型的字段(或变量)。 2)Max/min:适用于数值类型、字符串类型、日期时间类型的字段(或变量) 3)Count: ①作…

SpringBoot自定义starter之接口日志输出

文章目录 前言文章主体1 项目全部源码2 项目结构介绍3 starter 的使用3.1 配置文件 application,yml的内容3.2 启动类3.3 控制器类 4 测试结果 结语 前言 本文灵感来源是一道面试题。 要求做一个可以复用的接口日志输出工具,在使用时引入依赖,即可使用。…

OpenCV学习笔记 | ROI区域选择提取 | Python

摘要 ROI区域是指图像中我们感兴趣的特定区域,OpenCV提供了一些函数来选择和提取ROI区域,我们可以使用OpenCV的鼠标事件绑定函数,然后通过鼠标操作在图像上绘制一个矩形框,该矩形框即为ROI区域。本文将介绍代码的实现以及四个主要…

Vue中如何进行游戏开发与游戏引擎集成?

Vue中如何进行游戏开发与游戏引擎集成? Vue.js是一款流行的JavaScript框架,它的MVVM模式和组件化开发思想非常适合构建Web应用程序。但是,如果我们想要开发Web游戏,Vue.js并不是最合适的选择。在本文中,我们将介绍如何…

edge自带断网游戏

在没有网络时你会不会很无聊?博主告诉你一个edge浏览器自带的断网小游戏,让你在断网时也能玩游戏! 网址: 打开edge://surf这个断网游戏网站即可游玩: 作弊码既隐藏模式: 输入microsoft(意思就…

Axure教程——图片轮播(纵向滚动)

本文介绍的时用Axure中的动态面板制作图片轮播之纵向滚动 一、预览效果 预览地址:https://c1s4i1.axshare.com 二、功能描述 图片纵向自动滚动播放 三、元件制作 拖入一个动态面板,命名为1,设置大小为375*155,并设置四个状态&…

Python对csv文件一键多值保存为json本地文件再读取加速效率(3)

最近发现做办公自动化表格匹配的时候还是csv格式的文件最快、效率是最高的 今天接到一个需求就是大致内容之这样的 1、给我一张表格直邮一列A列,内容是运单号 2、需要用相同的单号去另外一张表格匹配数据 3、其实就是Excel中的常见的vlookup 但是想要匹配的表格有几…

基于Python所写的Word助手设计

点击以下链接获取源码资源: https://download.csdn.net/download/qq_64505944/87959100?spm1001.2014.3001.5503 《Word助手》程序使用说明 在PyCharm中运行《Word助手》即可进入如图1所示的系统主界面。在该界面中,通过顶部的工具栏可以选择所要进行的…

Pytorch实现多GPU并行训练(DDP)

Pytorch实现并行训练通常有两个接口:DP(DataParallel)和DDP(DistributedDataParallel)。目前DP(DataParallel)已经被Pytorch官方deprecate掉了,原因有二:1,DP…

VisualStudio离线包制作

因为需要,需要制作VisualStudio离线包,之前尝试了很多的方案,均没有下载成功。今天偶然看到一个可行的方案,这里在这里分享下。 从微软官网下载VisualStudio离线包 1 下载安装文件 visualstudio官网 首先进入到官网中&#xff0…

最小二乘法的原理及实现

1.最小二乘法的原理及实现 笔记来源于《白话机器学习的数学》 1.1 最小二乘法的原理 预测一个变量 x x x与一个变量 y y y的关系 例如:广告费 x x x与点击量 y y y 用直线拟合数据 1.2 最小二乘法的实现 广告费x和点击量y,找到一条直线表达式&#x…