设计模式[2]-工厂模式

news/2024/11/17 14:41:05/文章来源:https://www.cnblogs.com/Aeons/p/18375609

代码:https://gitee.com/Aes_yt/design-pattern

工厂模式

1. 简单工厂模式

简单工厂模式主要包括三种角色:
  • 简单工厂 : 创建具体产品
  • 抽象产品 : 具体产品的父类
  • 具体产品 : 简单工厂创建的对象
例子:

设计一个游戏机类(GameConsole) 作为抽象产品,然后设计具体的产品(PlanStation4,XboxOne,WiiU),最后在简单工厂中创建具体的产品。逻辑很简单。

image-20211211215848285

GameConsole:

public abstract class GameConsole {public abstract String getName();public void play() {powerOn();System.out.println("正在用 " + getName() + " 玩游戏");powerOff();}private void powerOn() {System.out.println("开机 >>> ");}private void powerOff() {System.out.println("关机 >>>");}
}

PlayStation4:

public class PlayStation4 extends GameConsole {@Overridepublic String getName() {return "playStation 4";}
}

XboxOne:

public class XboxOne extends GameConsole {@Overridepublic String getName() {return "Xbox One";}
}

WiiU:

public class WiiU extends GameConsole {@Overridepublic String getName() {return "Wii U";}
}

简单工厂类:GameConsoleSimpleFactory

public class GameConsoleSimpleFactory {public GameConsole createGameConsole(String type) {if ("Sony".equals(type)) {return new PlayStation4();} else if ("Microsoft".equals(type)) {return new XboxOne();} else if ("Nintendo".equals(type)) {return new WiiU();} else {throw new RuntimeException("不支持的游戏机");}}
}

测试类:

@Testvoid createGameConsole() {String[] arr = new String[]{"Sony", "Microsoft", "Nintendo"};GameConsoleSimpleFactory factory = new GameConsoleSimpleFactory();for (String type : arr) {GameConsole console = factory.createGameConsole(type);console.play();System.out.println();}}

输出:

开机 >>> 
正在用 playStation 4 玩游戏
关机 >>>开机 >>> 
正在用 Xbox One 玩游戏
关机 >>>开机 >>> 
正在用 Wii U 玩游戏
关机 >>>
优缺点

简单工厂类工厂和产品职责区分明确,但是工厂类过于单一,如果需要引入更多的类,则需要改动工厂类,不便拓展,类型过多时,也会造成逻辑复杂。

tips:

可以在工厂方法加static关键字,无需实例化工厂类。

public static GameConsole createGameConsole(String type)

2. 工厂方法模式

工厂方法模式主要包括四种角色:
  • 抽象工厂 : 只提供创建产品的接口
  • 具体工厂 : 实现抽象工厂的抽象方法,完成产品的创建
  • 抽象产品 : 具体产品的父类
  • 具体产品 : 具体工厂所创建的对象
例子:

将简单工厂模式的例子用工厂方法模式进行实现。

image-20211211223508840

抽象产品和具体产品类不变:GameConsole 类、PlayStation4类、XboxOne类、WiiU类不变。

抽象工厂:

GameConsoleFactory:

public interface GameConsoleFactory {GameConsole createGameConsole();
}

具体工厂类:

MicrosoftGameConsoleFactory:

public class MicrosoftGameConsoleFactory implements GameConsoleFactory {@Overridepublic GameConsole createGameConsole() {return new XboxOne();}
}

NintendoGameConsoleFactory:

public class NintendoGameConsoleFactory implements GameConsoleFactory {@Overridepublic GameConsole createGameConsole() {return new WiiU();}
}

SonyGameConsoleFactory:

public class SonyGameConsoleFactory implements GameConsoleFactory {@Overridepublic GameConsole createGameConsole() {return new PlayStation4();}
}

测试类

@Test
void createGameConsole() {play(new SonyGameConsoleFactory());play(new NintendoGameConsoleFactory());play(new MicrosoftGameConsoleFactory());
}private void play(GameConsoleFactory gameConsoleFactory) {GameConsole gameConsole = gameConsoleFactory.createGameConsole();gameConsole.play();
}

输出:

开机 >>> 
正在用 playStation 4 玩游戏
关机 >>>
开机 >>> 
正在用 Wii U 玩游戏
关机 >>>
开机 >>> 
正在用 Xbox One 玩游戏
关机 >>>
优缺点

优点创建对象灵活,若后期有添加新的产品,不需要改旧的代码,只需要建新的具体产品类和具体的工厂类即可。

缺点也很明显,创建的类变多了,增加了系统的复杂性。

3. 抽象工厂模式

抽象工厂模式主要包括四种角色:
  • 抽象工厂 : 提供创建产品的接口,但有多个创建产品的方法,可以创建多个不同等级的产品
  • 具体工厂 : 实现抽象工厂的多个抽象方法,完成产品的创建
  • 抽象产品 : 具体产品的父类
  • 具体产品 : 具体工厂所创建的对象

抽象工厂模式是工厂方法模式的升级版。它的角色和工厂方法模式一样都是这四种。

为什么需要用到抽象工厂方法模式呢,我们可以看看上面游戏机的例子。现在如果我们还需要创建游戏机相关的游戏手柄,那么我们利用工厂方法模式来创建的话,除了建游戏手柄抽象类和具体类以外,就还需要再建游戏手柄抽象工厂还有各个品牌的游戏手柄的具体工厂。这样类创建就会过多。

所以,在使用同一个产品族的情况下,利用抽象工厂模式能够对同一产品族的不同等级的产品进行很好的创建管理。

注:同一产品族:索尼游戏机,索尼游戏手柄,这是同一产品族下的不同等级产品。

例子:

image-20211212000557018

新增游戏手柄Gamepad抽象类,和具体的实现类

public abstract class Gamepad {public abstract void getName();
}
public class MicrosoftGamepad extends Gamepad{@Overridepublic void getName() {System.out.println("微软游戏手柄");}
}
public class SonyGamepad extends Gamepad {@Overridepublic void getName() {System.out.println("索尼游戏手柄");}
}
public class NintendoGamepad extends Gamepad {@Overridepublic void getName() {System.out.println("任天堂游戏手柄");}
}

原本的抽象工厂改名为游戏设备工厂GameDeviceFactory,新增创建一个游戏手柄的抽象方法

GameDeviceFactory:

public interface GameDeviceFactory {/*** @param* @return "com.yt.design.abstractfactory.GameConsole"* @description 创建游戏机对象* @author lzf* @date 2021/12/11 22:14*/GameConsole createGameConsole();/*** @param* @return "com.yt.design.abstractfactory.Gamepad"* @description 创建手柄对象* @author lzf* @date 2021/12/11 23:57*/Gamepad createGamepad();
}

具体工厂:

MicrosoftGameDeviceFactory:

public class MicrosoftGameDeviceFactory implements GameDeviceFactory {@Overridepublic GameConsole createGameConsole() {return new XboxOne();}@Overridepublic Gamepad createGamepad() {return new MicrosoftGamepad();}
}

MicrosoftGameDeviceFactory:

public class NintendoGameDeviceFactory implements GameDeviceFactory {@Overridepublic GameConsole createGameConsole() {return new WiiU();}@Overridepublic Gamepad createGamepad() {return new NintendoGamepad();}
}

SonyGameDeviceFactory:

public class SonyGameDeviceFactory implements GameDeviceFactory {@Overridepublic GameConsole createGameConsole() {return new PlayStation4();}@Overridepublic Gamepad createGamepad() {return new SonyGamepad();}
}

测试类:

class GameDeviceFactoryTest {@Testvoid createGameConsole() {show(new MicrosoftGameDeviceFactory());show(new SonyGameDeviceFactory());show(new NintendoGameDeviceFactory());}private void show(GameDeviceFactory gameDeviceFactory) {GameConsole gameConsole = gameDeviceFactory.createGameConsole();Gamepad gamepad = gameDeviceFactory.createGamepad();gameConsole.play();gamepad.getName();System.out.println();}
}

输出:

开机 >>> 
正在用 Xbox One 玩游戏
关机 >>>
微软游戏手柄开机 >>> 
正在用 playStation 4 玩游戏
关机 >>>
索尼游戏手柄开机 >>> 
正在用 Wii U 玩游戏
关机 >>>
任天堂游戏手柄
优缺点

抽象工厂模式可以在同一个抽象工厂类创建不同产品等级的对象,当增加新的产品族时也不需要修改代码,只需要创建新的具体工厂类即可。

但是,当产品族需要再加新的产品等级时,比如在增加一个游戏遥控器类,那么还是需要修改所有的抽象工厂类和具体产品类的代码的。

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

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

相关文章

2021-12-29-md1

代码:https://gitee.com/Aes_yt/design-pattern代理模式 代理模式需要给某对象提供一个代理来访问该对象。是客户端和目标对象之间的一个媒介。 代理模式主要包括三种角色抽象主题:接口或抽象类,有着业务方法,可以让真实主题和代理对象来实现。 真实主题:实现了抽象主题的…

dubbo[3]_注解配置

本文介绍注解方式配置dubbo的例子。 服务提供Provider 1. 定义接口Animal和实现类CatAnimal: public interface Animal {/*** 描述: 返回动物的叫声*/String sound(); }Cat: package com.yt.provider;import com.alibaba.dubbo.config.annotation.Service;@Service(timeout = 5…

dubbo[2]_XML配置

本文介绍了zookeeper的下载安装以及用xml配置服务消费者和提供者的例子。 1. zookeeper下载安装 本文的例子使用zookeeper作为注册中心。 首先,从官网下载zookeeper,我选择的是Apache ZooKeeper 3.6.3版本。下载完成后,解压到自己的目录。https://zookeeper.apache.org/rele…

2021-05-13-md1

本文介绍注解方式配置dubbo的例子。 服务提供Provider 1. 定义接口Animal和实现类CatAnimal: public interface Animal {/*** 描述: 返回动物的叫声*/String sound(); }Cat: package com.yt.provider;import com.alibaba.dubbo.config.annotation.Service;@Service(timeout = 5…

2021-05-12-md1

本文介绍了zookeeper的下载安装以及用xml配置服务消费者和提供者的例子。 1. zookeeper下载安装 本文的例子使用zookeeper作为注册中心。 首先,从官网下载zookeeper,我选择的是Apache ZooKeeper 3.6.3版本。下载完成后,解压到自己的目录。https://zookeeper.apache.org/rele…

Myslq千万级数据量查询

两千四百万数据量SQL查询没有索引时 如果字段无索引,耗时十分钟无索引查询过程 MySQL 需要对 2400 万条数据一一进行比较,假设每条记录的处理时间为 0.025 ms,那么总查询时间大约为 10 分钟(即 2400 万 0.025 ms)。 •全表扫描: 当查询 kh = 03356129487 时,如果表上没有…

001.MinIO简介

MinIO 简介 MinIO 是天然的云原生存储,可以作为轻量级容器运行,由相关编排服务(如 Kubernetes )管理。 整个服务器是一个不到100MB的静态二进制文件,并且在使用CPU和内存资源方面即使在高负载场景也非常高效,因此可以在共享硬件上共同托管大量租户。 MinIO 可以在任何地方和…

转载:国产麒麟v10、UOS系统在线比较两个Word文件的内容差异

调用PageOffice的WordCompare方法,同时在线打开两个Word文档,可以切换显示其中的一个文档,或者显示两个文档的对比结果,即可实现在线的文档内容比较功能。此功能可以应用在以下方面: 文档管理中,比较两个版本Word文档的差别。 在处理文档管理的Web项目中,比较两个版本的…

并发编程[5]_wait和notify

1. wait 和 notify wait() 方法是Object类中的方法,他的作用是让当前线程进入等待状态,而使用notify() 方法可以唤醒。wait(long): void ,参数是毫秒,表示等待毫秒数,直到时间结束或被唤醒; wait(long, int): void ,第一个参数是毫秒,第二个参数是纳秒,如果纳秒在0-99…

【2024-08-23】邬贺铨院士:大模型赋能企业数字化转型

一、AI的演进之路:从生成式AI到通用A1二、大模型的构建与应用:自建与协作开发的行业大模型2.1 自建基础大模型2.2 合作开发行业大模型三、对MaaS及其工具链的探索四、大模型推动云服务创新4.1 大模型时代对算力网络的要求4.2 大模型推动IaaS创新发展4.3 大模型催生AI PaaS创新…

.NET 8 + Vue 3 极简 RABC 权限管理系统

前言 在日常工作中,几乎每家公司都需要一个后台管理系统来处理各种任务。为了帮助大家快速搭建这样一个系统,给大家介绍一个基于最新技术 .NET 8 和前端框架 Vue 3 实现的极简 RABC(基于角色的访问控制)权限管理系统。 该系统后端采用经过精心精简的 ABP框架,前端则使用了…

ToDesk支持多系统互控,使用教程来了!

能多系统跨设备进行远控的软件被我找到了! 就是ToDesk远程控制👍官网就能免费下载使用 遇到公司电脑window系统,但家里笔记本手机是苹果再也不会束手无策了! 电脑手机平板都能互相远程控制,一个账号可登录多个设备 传输文件速度高达12m/s,画质高清还能匹配网速流畅度进行…