设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)

news/2024/5/10 12:52:51/文章来源:https://blog.csdn.net/m0_63622279/article/details/128951902

工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)

工厂模式-创建型模式-提供了创建对象的最佳方式。

在工厂模式中,创建对象时不会对客户端暴露创建逻辑,并且是通过一个共同的接口来创建新的对象。

简单工厂

简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式由一个工厂对象决定创建出哪一种产品类的实例。(工厂类拥有一个工厂方法(create),接受了一个参数,通过不同的参数实例化不同的产品类。)

定义了一个创建对象的类,由这个类来封装实例化对象的行为。

例子:一个汽车生产工厂,生产不同品牌的汽车,每台汽车具有说广告标语的行为。将汽车生产工厂封装成一个简单工厂类。说汽车广告标语的行为封装为一个接口。

在这里插入图片描述

接口:

package com.robin.factoryPattern.simpleFactory;public interface Moveable {void RunRoad();
}

品牌汽车类:

比亚迪:

package com.robin.factoryPattern.simpleFactory;// 比亚迪
public class BydCar implements Moveable {@Overridepublic void RunRoad() {System.out.println("[比亚迪]:一路同驰骋");}
}

法拉利:

package com.robin.factoryPattern.simpleFactory;// 法拉利汽车
public class FerrariCar implements Moveable {@Overridepublic void RunRoad() {System.out.println("[法拉利]:对车手来说,是速度\n" +"对小孩来说,是红色\n" +"对父亲来说,是血液\n" +"对车迷来说,是情人\n" +"对个人来说,是挑战\n" +"对一群人来说,是传奇\n" +"对我们来说,是一切");}
}

五菱宏光:

package com.robin.factoryPattern.simpleFactory;// 五菱汽车
public class WuLingCar implements Moveable {@Overridepublic void RunRoad() {System.out.println("[五菱宏光]:人民需要什么,五菱就造什么");}
}

简单工厂类:

package com.robin.factoryPattern.simpleFactory;public class SimpleFactory {// 根据传入参数进行不同汽车的生产public Moveable getVehicle(String vehicleName){if (vehicleName.equalsIgnoreCase("BYD")){return new BydCar();}else if(vehicleName.equalsIgnoreCase("FERRARI")){return new FerrariCar();}else if(vehicleName.equalsIgnoreCase("WULING")){return new WuLingCar();}return null;}
}

客户端类:

package com.robin.factoryPattern.simpleFactory;import java.util.Scanner;public class Main {public static void main(String[] args) {// 充当客户端 利用一个While循环测试while (true){Scanner scanner = new Scanner(System.in);System.out.println("请输入汽车名称:");String carName = scanner.next();Moveable m = new SimpleFactory().getVehicle(carName);if (m==null){break;}else {m.RunRoad();}}System.out.println("=====over=====");}
}

在这里插入图片描述

小结:当我们需要新的品牌汽车时,在简单工厂类中进行代码修改即可。

  • 优点:很明显,简单工厂的特点就是“简单粗暴”,通过一个含参的工厂方法,可以实例化任何产品类。
  • 缺点:
    • 任何”东西“的子类都可以被生产,负担太重。当所要生产产品种类非常多时,工厂方法的代码量可能会很庞大
    • 没有遵循开闭原则(对拓展开放,对修改关闭),简单工厂对于增加新的产品,无能为力。因为增加新产品只能通过修改工厂方法来实现。

工厂方法

结合上面的简单工厂,工厂方法进一步解耦合,把工厂类进行抽象,不再负责所有实例的创建,而是把具体的创建工作交给其子类去完成,实例化延迟到子类加载,由子类来决定要实例化的类。

一句话概括就是,工厂方法定义了一个对象的接口,但由子类去决定实例化的类是哪一个。

一个电脑配件工厂,创建对应的品牌配件。

在这里插入图片描述

鼠标接口(打印名称):

package com.robin.factoryPattern.factoryMethod;public interface CpParts {void printName();
}

鼠标工厂方法类:

package com.robin.factoryPattern.factoryMethod;public abstract class CpPartsFactory {public abstract CpParts create();
}

鼠标实现类工厂:

package com.robin.factoryPattern.factoryMethod;public class HpMouseFactory extends CpPartsFactory implements CpParts{@Overridepublic void printName() {System.out.println("惠普鼠标 created!");}@Overridepublic CpParts create() {return new HpMouseFactory();}
}
package com.robin.factoryPattern.factoryMethod;public class LenovoMouseFactory extends CpPartsFactory implements CpParts{@Overridepublic void printName() {System.out.println("联想鼠标 created!");}@Overridepublic CpParts create() {return new LenovoMouseFactory();}
}
package com.robin.factoryPattern.factoryMethod;public class LogitechMouseFactory extends CpPartsFactory implements CpParts{@Overridepublic void printName() {System.out.println("罗技鼠标 created!");}@Overridepublic CpParts create() {return new LogitechMouseFactory();}
}

客户端测试类:

package com.robin.factoryPattern.factoryMethod;public class Main {public static void main(String[] args) {//  工厂模式-工厂方法CpPartsFactory cpPartsFactory = new HpMouseFactory();cpPartsFactory.create().printName();// 惠普鼠标 created!}
}

优缺点

  • 优点

    • 工厂方法模式就很好的减轻了工厂类的负担,把某一类/某一种东西交由一个工厂生产;(对应简单工厂的缺点)。
    • 同时增加某一类 ”东西“ 并不需要修改工厂类,只需要添加生产这类 ”东西“ 的工厂即可,使得工厂类符合开闭原则
  • 缺点

    • 对于某些可以形成产品族(一组产品)的情况处理比较复杂。

抽象工厂

抽象工厂:提供一个接口,用于创建相关或依赖的家族,而不需要明确指定具体类。

例子:假设你做了一个大型游戏,里面人物角色的种族属性及世界观都是不同的。比如,普通人类,魔法师,外星物种…

在这里插入图片描述

载具抽象类:

package com.robin.factoryPattern.abstractFactory;// 交通工具的抽象类
public abstract class Vehicle {abstract void go();
}

食物抽象类:

package com.robin.factoryPattern.abstractFactory;// 食物抽象类  抽象类,一个具体的名词真实世界存在且是一个抽象的概念统称
public abstract class Food {abstract void printName();
}

武器抽象类:

package com.robin.factoryPattern.abstractFactory;// 武器抽象类
public abstract class Weapon {abstract void wave();
}

抽象工厂类:

package com.robin.factoryPattern.abstractFactory;// 抽象工厂类  一个【人】的拥有的...
public abstract class AbstractFactory {// 抽象方法abstract Food getFood();abstract Weapon getWeapon();abstract Vehicle getVehicle();
}

载具实现类:

package com.robin.factoryPattern.abstractFactory;public class Car extends Vehicle{public void go(){System.out.println("[人类]-载具-汽车...");}
}
package com.robin.factoryPattern.abstractFactory;public class Broom extends Vehicle{public void go(){System.out.println("[魔法师]-载具-魔法扫帚...");}
}

食物实现类:

package com.robin.factoryPattern.abstractFactory;public class Bread extends Food{public void printName(){System.out.println("[人类]-食物-面包...");}
}
package com.robin.factoryPattern.abstractFactory;public class MushRoom extends Food {public void printName(){System.out.println("[魔法师]食物-蘑菇");}
}

武器实现类:

package com.robin.factoryPattern.abstractFactory;public class BroadSword extends Weapon{public void wave(){System.out.println("[人类]挥动大刀...");}
}
package com.robin.factoryPattern.abstractFactory;public class MagicWand extends Weapon{public void wave(){System.out.println("[魔法师]挥舞着魔法棒....");}
}

不同人物种族的区分:

普通地球人:

package com.robin.factoryPattern.abstractFactory;public class EarthManFactory extends AbstractFactory{@OverrideFood getFood() {return new Bread();}@OverrideWeapon getWeapon() {return new BroadSword();}@OverrideVehicle getVehicle() {return new Car();}
}

魔法师:

package com.robin.factoryPattern.abstractFactory;public class MagicManFactory extends AbstractFactory{@OverrideFood getFood() {return new MushRoom();}@OverrideWeapon getWeapon() {return new MagicWand();}@OverrideVehicle getVehicle() {return new Broom();}
}

Main客户端测试类:

package com.robin.factoryPattern.abstractFactory;// 充当客户端
public class Main {// 一个人类public static void main(String[] args) {// 通过AbstractFactory 抽象工厂类对不同世界|星球|种族 的人的描述AbstractFactory abstractFactory = new MagicManFactory();// 这样当我们有不同的设定的种族来时,从抽象工厂继承实现即可,// 然后客户端只需要修改 AbstractFactory abstractFactory = new xxxFactory();即可Vehicle vehicle = abstractFactory.getVehicle();vehicle.go();// [魔法师]-载具-魔法扫帚...Weapon weapon = abstractFactory.getWeapon();weapon.wave();// [魔法师]挥舞着魔法棒....Food food = abstractFactory.getFood();food.printName();// [魔法师]食物-蘑菇}
}

工厂模式区别

  • 简单工厂 : 使用一个工厂对象用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
  • 工厂方法 : 使用多个工厂对象用来生产同一等级结构中对应的固定产品。(支持拓展增加产品)
  • 抽象工厂 : 使用多个工厂对象用来生产不同产品族的全部产品。(不支持拓展增加产品;支持增加产品族)

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

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

相关文章

小兔子MQ高级

一.保证消息被执行处理传递逻辑:生产者消息确认RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。这种机制必须给每个消息指定一个唯一ID(一般是业务id)。消息发送到MQ以后,会返回一个结果给发送者,表示消息是否处理成功。…

从FPGA说起的深度学习(二)

这是新的系列教程,在本教程中,我们将介绍使用 FPGA 实现深度学习的技术,深度学习是近年来人工智能领域的热门话题。在本教程中,旨在加深对深度学习和 FPGA 的理解。用 C/C 编写深度学习推理代码高级综合 (HLS) 将 C/C 代码转换为硬…

真的麻了,别再为难软件测试员了......

前言 有不少技术友在测试群里讨论,近期的面试越来越难了,要背的八股文越来越多了,考察得越来越细,越来越底层,明摆着就是想让我们徒手造航母嘛!实在是太为难我们这些测试工程师了。 这不,为了帮大家节约时…

无需注册即可免费使用ChatGPT

无需注册即可免费使用ChatGPT 最近OpenAI的ChatGPT异常火爆,有很多人都想尝试尝试,但是因为一些原因折戟,这里提供一个免注册的体验方法,仅供学习交流。 一,首先下载vscode 官网下载地址 Visual Studio Code - Code…

【python】多线程的基本使用 _thread包

Python中使用线程有两种方式:函数或者用类来包装线程对象。 函数式: 调用 _thread 模块中的start_new_thread()函数来产生新线程。语法如下: _thread.start_new_thread ( function, args[, kwargs] ) 参数说明: function - 线程函数。 args - 传递给线…

后勤管理系统—服务台管理功能

数图互通是一家IT类技术型软件科技公司,专业的不动产、工作场所、空间、固定资产、设备家具、设施运维及可持续性管理解决方案软件供应商。 一、后勤管理系统服务台管理功能包含: 1、专业自动化、集中管理的自助服务助理,随时响应服务请求。…

《数字经济全景白皮书》出海篇:选对路径下好棋,热点出海行业如何实现增长?

易观分析:《数字经济全景白皮书》浓缩了易观分析对于数字经济各行业经验和数据的积累,并结合数字时代企业的实际业务和未来面临的挑战,以及数字技术的创新突破等因素,最终从数字经济发展大势以及各领域案例入手,帮助企…

mongo DB数据库bindIP的配置和我的理解(bindIP不是应用服务器的IP)

先批评这个文章!典型的错误,bindIP根本不是绑定哪一个ip的 背景:最近在阿里云上搭建overleaf的web服务集群,数据库和应用服务器分离,一口气买了三台服务器准备开始干活。overleaf用的是mongodb,我本来准备…

锦正茂EM3电磁铁的技术参数

产品特点: ※U形结构、视野开阔、磁场强度高、磁场强度大小调节方便 ※体积小、重量轻、占空比小、结构紧凑、磁场性能更佳 ※电磁铁的工作气隙调节轻便灵活,极头处设有螺纹,更换极头装卸方便 ※可选配工作间隙刻度指示 ※小气隙时用于铁…

智能优化算法——粒子群优化算法(PSO)(小白也能看懂)

前言: 暑假期间,因科研需要,经常在论文中看到各种优化算法,所以自己学习了一些智能优化的算法,做了一些相关的纸质性笔记,寒假一看感觉又有点遗忘了,并且笔记不方便随时查看,所以希…

20、CSS中单位:【px和%】【em和rem】【vw|vh|vmin|vmax】的区别

CSS中的px 和 % px (pixels) 是固定单位,也可以叫基本单位,代表像素,可以确保元素的大小不受屏幕分辨率的影响。 % (percentage) 是相对单位,代表元素大小相对于其父元素或视口(viewport)的大小的百分比。使用百分比可…

iOS 导航条isTranslucent几个注意点(iOS11及iOS13的变化)

文章主要针对11及13之后的导航变化进行总结,主要是设置透明度时对转场,包括标题,背景透明,图片,颜色等设置的影响。 每一个iOS版本的发布苹果最不稳写的可能就数这个导航条了吧,改了又改。 因此isTranslu…

为什么微博签到数据如此受欢迎?

随着互联网的发展,人们在新浪微博、Twitter、Facebook、等社交媒体的网络社交活动也越来越活跃。就新浪微博而言,2023年春晚期间活跃用户3亿左右。 由于我国网民群体庞大、网络社交活动不受地域限制、话题自由开放等特点,使得微博签到数据能…

拦截器interceptor总结

拦截器一. 概念拦截器和AOP的区别:拦截器和过滤器的区别:二. 入门案例2.1 定义拦截器bean2.2 定义配置类2.3 执行流程2.4 简化配置类到SpringMvcConfig中一. 概念 引入: 消息从浏览器发送到后端,请求会先到达Tocmat服务器&#x…

56 门控循环单元(GRU)【动手学深度学习v2】

56 门控循环单元(GRU)【动手学深度学习v2】 深度学习学习笔记 学习视频:https://www.bilibili.com/video/BV1mf4y157N2/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 门控循环单元GRU GRU和LSTM 实际上效果差不多。…

国家政策鼓励使用电子保函和银行函证,君子签助推函证数字化建设

近日,国家发改委发文,推动电子保函应用,降低电子保函费用;财政部会同银保监会发文,开展数字化函证,有效提升函证效率和效果。政策的出台有助于加快推进普及电子函证应用。 发改委:鼓励使用电子…

Java基础-多线程juc

1.实现多线程 1.1简单了解多线程【理解】 是指从软件或者硬件上实现多个线程并发执行的技术。 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能。 1.2并发和并行【理解】 并行:在同一时刻,有多个指令在多个CPU上…

DataFrame与Spark SQL的由来

文章目录DataFrame与Spark SQL的由来RDD 之殇:优化空间受限DataFrame 横空出世幕后英雄:Spark SQL基于 DataFrame,Spark SQL 是如何进行优化的Catalyst 优化器TungstenDataFrame与Spark SQL的由来 Spark 已经有了 RDD 这个开发入口&#xff…

SSJ-21A AC220V静态【时间继电器】

系列型号: SSJ-11B静态时间继电器;SSJ-21B静态时间继电器 SSJ-21A静态时间继电器;SSJ-22A静态时间继电器 SSJ-22B静态时间继电器SSJ-42B静态时间继电器 SSJ-42A静态时间继电器SSJ-41A静态时间继电器 SSJ-41B静态时间继电器SSJ-32B静态时间继电…

MySQL架构图

MySQL架构图 Mysql逻辑架构图主要分三层: 1) 第一层负责连接处理,授权认证,安全等等 每个客户端连接都会在服务器进程中拥有一个线程,服务器维护了一个线程池,因此不需要为每一个新建的连接创建或者销毁线程。 当客户…