详解Java设计模式之抽象工厂模式
作者:小薯条学技术 发布时间:2022-09-29 17:00:34
简介
设计模式是软件设计中的一种常见方法,通过定义一系列通用的解决方案,来解决常见的软件设计问题。其中,抽象工厂模式是一种非常常见的设计模式,它可以帮助我们创建一组相关的对象,而不需要指定具体的实现方式。
抽象工厂模式是一种创建型设计模式,它提供了一种方式来创建一组相关的对象,而不需要暴露具体的实现方式。通过使用抽象工厂模式,我们可以把客户端与具体实现分离,从而提高代码的可维护性和可扩展性。
抽象工厂模式的主要用途是创建一组相关的对象。例如,在一个游戏中,我们需要创建一组不同种类的武器、防具和道具。这些对象可能有不同的实现方式,但是它们都属于同一组对象。通过使用抽象工厂模式,我们可以将它们的创建逻辑封装在一个工厂中,从而简化客户端代码。
在软件设计中,有很多与抽象工厂模式相似的设计模式,如工厂方法模式和建造者模式。这些模式也可以用来创建对象,但它们和抽象工厂模式之间存在一些区别。
工厂方法模式
工厂方法模式和抽象工厂模式都可以用来创建对象,但是它们之间有一个重要的区别。在工厂方法模式中,我们只需要实现一个工厂方法,它负责创建一个特定类型的对象。而在抽象工厂模式中,我们需要实现一个工厂接口,它负责创建一组相关的对象。
建造者模式
建造者模式是一种用于创建复杂对象的设计模式。它可以将一个复杂对象的构造逻辑拆分成多个简单的部分,并且允许客户端按照需要组装这些部分。与抽象工厂模式相比,建造者模式更加灵活,但是它也更加复杂。
实现
我们可以通过定义一个抽象工厂接口和多个具体工厂来实现抽象工厂模式。具体工厂实现工厂接口,并且负责创建一组相关的对象。
下面是一个使用抽象工厂模式创建按钮和文本框的示例。我们定义了一个抽象工厂接口GUIFactory
,它包含了两个方法:createButton()
和createTextBox()
。同时,我们也定义了两个具体工厂类WinFactory
和MacFactory
,它们都实现了GUIFactory
接口,并且负责创建特定平台下的按钮和文本框,代码如下:
// 抽象工厂接口
interface GUIFactory {
Button createButton();
TextBox createTextBox();
}
// 具体工厂类 - Windows工厂
class WinFactory implements GUIFactory {
public Button createButton() {
return new WinButton();
}
public TextBox createTextBox() {
return new WinTextBox();
}
}
// 具体工厂类 - Mac工厂
class MacFactory implements GUIFactory {
public Button createButton() {
return new MacButton();
}
public TextBox createTextBox() {
return new MacTextBox();
}
}
我们还定义了两个按钮类Button
和WinButton
,以及两个文本框类TextBox
和WinTextBox
。它们都是抽象类或接口,具体实现由具体工厂类来完成。
// 抽象按钮类
abstract class Button {
public abstract void paint();
}
// 抽象文本框类
abstract class TextBox {
public abstract void paint();
}
// Windows按钮类
class WinButton extends Button {
public void paint() {
System.out.println("Windows按钮");
}
}
// Windows文本框类
class WinTextBox extends TextBox {
public void paint() {
System.out.println("Windows文本框");
}
}
我们还定义了Mac按钮类MacButton
和Mac文本框类MacTextBox
,具体实现和Windows下的按钮和文本框类似,这里就不一一列举了。
// Mac按钮类
class MacButton extends Button {
public void paint() {
System.out.println("Mac按钮");
}
}
// Mac文本框类
class MacTextBox extends TextBox {
public void paint() {
System.out.println("Mac文本框");
}
}
使用抽象工厂模式,我们可以轻松地创建不同平台下的按钮和文本框,而不需要暴露具体的实现方式。例如,在Windows平台下,我们可以使用WinFactory
来创建按钮和文本框:
GUIFactory factory = new WinFactory();
Button button = factory.createButton();
TextBox textBox = factory.createTextBox();
button.paint();
textBox.paint();
输出结果为:
Windows按钮
Windows文本框
而在Mac平台下,我们可以使用MacFactory
来创建按钮和文本框:
GUIFactory factory = new MacFactory();
Button button = factory.createButton();
TextBox textBox = factory.createTextBox();
button.paint();
textBox.paint();
输出结果为:
Mac按钮
Mac文本框
优缺点
抽象工厂模式的主要优点是:
可以封装一组相关对象的创建逻辑,从而提高代码的可维护性和可扩展性。
可以帮助客户端代码与具体类的解耦,从而提高代码的灵活性和可移植性。
可以通过工厂的切换来实现对不同平台或不同产品系列的支持,同时又不会对客户端代码造成影响。
抽象工厂模式的缺点是:
在新增产品系列时,需要修改工厂接口及所有具体工厂类的实现,从而增加了代码的维护成本。
当产品系列比较复杂时,抽象工厂模式可能会变得比较臃肿。
运用场景
抽象工厂模式通常在以下场景中被使用:
系统需要支持多种产品系列,并且每个产品系列都有相应的抽象工厂、具体工厂和产品类。
系统需要动态地切换产品系列,例如根据用户的操作系统或用户的选择来决定使用哪种产品系列。
系统的产品族和产品等级结构稳定不变,但是仍然需要满足开闭原则,以便在将来新增产品时能够方便地扩展系统功能。
抽象工厂模式在GUI设计、数据库访问、游戏开发等领域得到了广泛的应用,可以说是一种非常实用的设计模式。
来源:https://juejin.cn/post/7234436929554956343
猜你喜欢
- 前言在Spring Boot的自动配置中经常看到@ConditionalOnProperty注解的使用,本篇文章带大家来了解一下该注解的功能
- 此方案适用于解决springboot项目运行时动态添加数据源,非静态切换多数据源!!!一、多数据源应用场景:1.配置文件配置多数据源,如默认
- @RequestBody出现400 Bad Request的问题今天与同事调试一个接口,发现后台使用@RequestBody老是获取不到数据
- 本文实例讲述了Hibernate批量处理海量数据的方法。分享给大家供大家参考,具体如下:Hibernate批量处理海量其实从性能上考虑,它是
- 什么是动态线程池?在线程池日常实践中我们常常会遇到以下问题:代码中创建了一个线程池却不知道核心参数设置多少比较合适。参数设置好后,上线发现需
- Unity脚本自动添加头部注释就是创建.cs文件时自动添加作者名,创建时间,文件名等看示例,我们在Unity的project面板下先创建一个
- 前言我们知道在Java中除了基础的数据类型以外,其它的都为引用类型。而Java根据其生命周期的长短将引用类型又分为强引用、软引用、弱引用、幻
- 本文实例讲述了Java设计模式之抽象工厂模式。分享给大家供大家参考,具体如下:具体工厂类:生产创建某一类具体产品对象。抽象产品类可以使用接口
- 文件上传大部分通过web前端判断后尾名或者service后端判断后尾名,这种操作具有一定的风险,比如:我可以将一个jsp页面,修改后尾名改成
- 使用GroupingSearch对搜索结果进行分组Package org.apache.lucene.search.grouping Des
- 各位亲们可以尝试以下代码:注:这里我就只有一个html标签对来说明问题了,首部之类的东西,自己添加。<html> &n
- 通过本文你可以用非常简短的代码替代业务逻辑中的判null校验,并且很容易的在出现空指针的时候进行打日志或其他操作。注:如果对Java8新特性
- 一、新建BeanUtil类import lombok.extern.slf4j.Slf4j;import org.springframewo
- 本文实例讲述了java Swing组件setBounds()简单用法。分享给大家供大家参考,具体如下:先看API:public void s
- 介绍使用mybatis时可以使用二级缓存提高查询速度,进而改善用户体验。使用redis做mybatis的二级缓存可是内存可控<如将单独
- 本篇将从以下几个方面讲述反射的知识:class 的使用方法的反射构造函数的反射成员变量的反射一、什么是class类在面向对象的世界里,万物皆
- 博主在初学注解的时候看到网上的介绍大部分都是直接介绍用法或者功能,没有实际的应用场景,篇幅又很长导致学习的时候难以理解其意图,而且学完就忘Q
- 1、定义一个接口 Animalpackage com.zh.vo;public interface Animal { void
- 尝试了各种防止中文乱码的方式,但是还是乱码;最后还是细节问题导致;解决方式:以及俩种方式是百度的,我的问题不是这俩块1.在requestMa
- 前端开发工程师和关注前端开发的开发者们在2015年中肯定被腾讯的JSSDk引爆过,搞APP的、搞前端的甚至是是搞后端的都跑过来凑热闹,一时之