当前位置: 首页 > news >正文

设计模式之工厂模式

工厂方法模式

  • 工厂方法模式
    • 什么是工厂方法模式
    • 工厂方法模式的创建
      • 1、创建共同的接口
      • 2、创建不同的实现类
      • 3、创建接口工厂类
      • 4、测试
  • 抽象工厂模式
    • 什么是抽象工厂模式
    • 抽象工厂的实现
      • 1、创建普通工厂接口
      • 2、创建所有工厂的实现类
      • 3、创建抽象工厂类
      • 4、创建工厂选择器
      • 5、扩展普通工厂
      • 6、测试
  • 总结

工厂方法模式

什么是工厂方法模式

工厂方法模式(Factory Pattern)是 Java 中最常用的设计模式之一。工厂方法模式提供了一种创建对象的方式,而无需指定要创建的具体类。使得创建对象的过程与使用对象的过程分离。通过使用工厂方法模式,可以将对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象,这样可以提高代码的可维护性和可扩展性。
工厂方法模式的结构
在这里插入图片描述

工厂方法模式的创建

现在我们以运动包含跑步和游泳为例,创建一个工厂方法模式:

1、创建共同的接口

public interface Sports {void sport();
}

2、创建不同的实现类

public class Run implements Sports{@Overridepublic void sport() {System.out.println("跑步");}
}
public class Swim implements Sports{@Overridepublic void sport() {System.out.println("游泳");}
}

3、创建接口工厂类

public class SportsFactory {public Sports getSport(String sportType) {if (sportType == null) {return null;}if (sportType.equals("run")) {return new Run();} else if (sportType.equals("swim")) {return new Swim();}return null;}
}

4、测试

public class Test {public static void main(String[] args) {SportsFactory sf = new SportsFactory();//根据输入获取跑步对象Sports run = sf.getSport("run");run.sport();//获取游泳对象Sports swim = sf.getSport("swim");swim.sport();}
}

可以看出,在工厂方法模式中,用户不会显式地创建不同类别的实例,而是通过传入字符串来指定对象的类别。

抽象工厂模式

什么是抽象工厂模式

抽象工厂之于普通工厂相当于普通工厂之于具体的实现类,也就是工厂的工厂;抽象工厂和普通工厂是父子关系,每个普通工厂都是抽象工厂的子类;抽象工厂中抽象出了不同工厂的get方法,便于在工厂选择器中选择需要使用的工厂。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂方法模式提供对象。抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。通过使用抽象工厂模式,可以将客户端与具体产品的创建过程解耦,使得客户端可以通过工厂接口来创建一族产品。
抽象工厂的结构
在这里插入图片描述

抽象工厂的实现

我们以活动作为抽象工厂,普通工厂为运动和唱歌,运动工厂对应的实现类仍然为跑步和游泳,唱歌工厂对应的实现类为唱中文歌和唱英文歌。

1、创建普通工厂接口

//运动工厂接口
public interface Sport {void sport();
}
//唱歌工厂接口
public interface Sing {void sing();
}

2、创建所有工厂的实现类

//运动工厂中的跑步类
public class Run implements Sport {@Overridepublic void sport() {System.out.println("跑步");}
}
//运动工厂中的游泳类
public class Swim implements Sport {@Overridepublic void sport() {System.out.println("游泳");}
}
//唱歌工厂中的唱中文歌类
public class ChineseSongs implements Sing{@Overridepublic void sing() {System.out.println("唱中文歌");}
}
//唱歌工厂中的唱英文歌类
public class EnglishSongs implements Sing{@Overridepublic void sing() {System.out.println("唱英文歌");}
}

3、创建抽象工厂类

抽象工厂类中包含获取普通工厂对象的抽象方法。

public abstract class AbstractFactory {//抽象出两个工厂方法public abstract Sport getSport(String sport);public abstract Sing getSing(String song);
}

4、创建工厂选择器

通过传递工厂名称获取普通工厂

public class FactoryProducer {public static AbstractFactory getFactory(String factory) {if (factory.equals("运动")) {return new SportFactory();} else if(factory.equals("唱歌")) {return new SingFactory();}return null;}
}

5、扩展普通工厂

这一步是使普通工厂继承抽象工厂,并根据传入的字符串来创建具体的实现类对象。实际上这一步应该在创建工厂选择器之前,本文写在这一步只是为了使步骤三(创建抽象工厂)和步骤四(从抽象工厂中创建工厂)放在一起方便记忆。

public class SportFactory extends AbstractFactory{@Overridepublic Sing getSing(String song) {return null;}@Overridepublic Sport getSport(String sport) {if (sport == null) {return null;} else if (sport.equals("run")) {return new Run();} else if (sport.equals("swim")) {return new Swim();}return null;}
}
public class SingFactory extends AbstractFactory {@Overridepublic Sport getSport(String sport) {return null;}@Overridepublic Sing getSing(String song) {if (song == null) {return null;} else if (song.equals("中文歌")) {return new ChineseSongs();} else if (song.equals("英文歌")) {return new EnglishSongs();}return null;}
}

6、测试

public class Test {public static void main(String[] args) {//先通过工厂选择器选择运动工厂AbstractFactory sportFactory = FactoryProducer.getFactory("运动");//选择好工厂之后,选择工厂中想创建的的对象Sport sporter1 = sportFactory.getSport("run");//调用该对象的方法sporter1.sport();Sport sporter2 = sportFactory.getSport("swim");sporter2.sport();//创建唱歌工厂AbstractFactory singFactory = FactoryProducer.getFactory("唱歌");Sing singer1 = singFactory.getSing("中文歌");singer1.sing();Sing singer2 = singFactory.getSing("英文歌");singer2.sing();}
}

测试结果如下
在这里插入图片描述

总结

1、工厂方法模式优缺点:

  • 优点:调用者不需要知道产品的具体实现,只需要关注接口的名称;符合开闭原则,增加产品时创建工厂以及实现类即可,扩展性好。
  • 缺点:增加产品步骤繁琐,需要创建工厂和实现类,导致系统中类的数量增加,对于这些类的编译和运行会增加系统开销。

2、抽象工厂模式的优缺点

  • 优点:与工厂方法模式相同,调用者不需要知道产品的具体实现;除此之外还能使同一族的对象聚集起来。
  • 缺点:比工厂方法模式更加复杂,并且扩展性不好,需要新加产品时需要修改抽象工厂以及工厂选择器。

3、工厂方法模式和抽象工厂模式的区别

  • 1、工厂模式主要关注一个对象的创建,而抽象工厂关注的是一系列相似对象的创建;
  • 2、当需要根据不同情况创建不同类型的对象时,需要使用工厂模式;当需要将多个系列对象按分类存放时可以使用抽象工厂模式;
  • 3、工厂模式的扩展性好,抽象工厂模式的扩展性差。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • ElasticSearch(七)— 相关性检索和组合查询
  • git 推送时出现错误 Locking support detected on remote “origin“
  • 右键没有压缩选项
  • 音视频入门基础:H.264专题(17)——FFmpeg源码获取H.264裸流文件信息(视频压缩编码格式、色彩格式、视频分辨率、帧率)的总流程
  • docker部署本地词向量模型
  • Django学习(二)
  • Linux_实现UDP网络通信
  • 详解 @RequestHeader 注解在 Spring Boot 中的使用
  • 学生党如何挑选高性价比蓝牙耳机?四款天花板级蓝牙耳机推荐
  • 在C++里如何释放内存的时候不调用对象的析构函数?
  • Final Draft for Mac v13.1.0激活版:专业剧本写作软件
  • 【Python】基础学习技能提升代码样例2:小功能块
  • UE5C++中,NewObject<>()和CreateDefaultSubobject<>()的区别
  • 网络通信---UDP
  • C语言 写一个函数days,实现某日在本年中是第几天计算。
  • Android框架之Volley
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • hadoop集群管理系统搭建规划说明
  • JSDuck 与 AngularJS 融合技巧
  • Laravel核心解读--Facades
  • use Google search engine
  • Web设计流程优化:网页效果图设计新思路
  • - 概述 - 《设计模式(极简c++版)》
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • # 职场生活之道:善于团结
  • #ubuntu# #git# repository git config --global --add safe.directory
  • #微信小程序(布局、渲染层基础知识)
  • (1)(1.13) SiK无线电高级配置(六)
  • (Matlab)使用竞争神经网络实现数据聚类
  • (超详细)语音信号处理之特征提取
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (分享)自己整理的一些简单awk实用语句
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (十)Flink Table API 和 SQL 基本概念
  • (文章复现)基于主从博弈的售电商多元零售套餐设计与多级市场购电策略
  • (原)本想说脏话,奈何已放下
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (原創) 未来三学期想要修的课 (日記)
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .NET/C#⾯试题汇总系列:集合、异常、泛型、LINQ、委托、EF!(完整版)
  • .net6 webapi log4net完整配置使用流程
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .Net的C#语言取月份数值对应的MonthName值
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • @基于大模型的旅游路线推荐方案
  • [2021ICPC济南 L] Strange Series (Bell 数 多项式exp)
  • [Angular 基础] - 表单:响应式表单
  • [BZOJ 3680]吊打XXX(模拟退火)
  • [Bzoj4722]由乃(线段树好题)(倍增处理模数小快速幂)
  • [EFI]Dell Inspiron 15 5567 电脑 Hackintosh 黑苹果efi引导文件
  • [FSCTF 2023]细狗2.0
  • [GN] DP学习笔记板子
  • [jobdu]不用加减乘除做加法