【工厂模式】工厂方法模式、抽象工厂模式-简单例子

embedded/2024/10/11 9:27:10/

简单工厂模式,请跳转到我的另一篇博客【工厂模式】简单工厂模式-简单例子-CSDN博客

四、工厂方法模式

(1)这部分还是不变,创建一个Car接口,和两个实现类。

java">public interface Car {void name();
}public class WuLing implements Car{@Overridepublic void name() {System.out.println("五菱");}
}public class Tesla implements Car{@Overridepublic void name() {System.out.println("特斯拉");}
}

(2)把车工厂提取成一个接口,

java">public interface CarFactory {Car getCar();
}public class TeslaFactory implements CarFactory{@Overridepublic Car getCar() {return new Tesla();}
}public class WuLingFactory implements CarFactory{@Overridepublic Car getCar(){return new WuLing();}
}

(3)这样的话,我再新增一种新车的时候就很方便了。

java">public class Mobai implements Car {@Overridepublic void name(){System.out.println("mobai");}
}public class MobaiFactory implements CarFactory{@Overridepublic Car getCar() {return new Mobai();}
}

(4)创建一个Customer类,

java">public class Customer {public static void main(String[] args) {Car car1 = new WuLingFactory().getCar();Car car2 = new TeslaFactory().getCar();car1.name();car2.name();Car car3 = new MobaiFactory().getCar();car3.name();}
}

这样的话,原来的类我们是没有动的,并且随时可以动态扩展,满足开闭原则。

但是实现起来反而是非常麻烦的,因为从下图的目录结构中我们也可以看出,需要创建的类变多了。

画个流程图分析一下,

总结

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它通过定义一个用于创建对象的接口,但是让子类决定实例化哪个类。这样,工厂方法模式允许一个类的实例化延迟到其子类。

工厂方法模式中,通常会有一个抽象的工厂类,该工厂类定义了一个抽象的方法,用于创建产品对象。具体的产品创建逻辑由子类实现,每个子类负责实例化特定类型的产品。这样,客户端代码可以通过调用工厂方法来创建所需的产品,而无需关心具体的实现细节。

工厂方法模式通常包括以下角色:

  1. 抽象工厂类(Abstract Factory Class):定义了一个抽象的工厂方法,用于创建产品对象。通常是一个接口或抽象类。

  2. 具体工厂类(Concrete Factory Class):实现了抽象工厂类,负责实际创建产品对象的逻辑。每个具体工厂类对应一种产品类型。

  3. 抽象产品类(Abstract Product Class):定义了产品对象的接口或抽象类,描述了产品的公共属性和方法。

  4. 具体产品类(Concrete Product Class):实现了抽象产品类定义的接口或抽象类,是真正被创建的产品对象。

工厂方法模式的优点在于可以将对象的创建逻辑移到子类中,使得主要的工厂类更加通用,而具体的产品实现则可以灵活地扩展和变化。同时,它也遵循了开闭原则,对扩展开放,对修改关闭。

总的来说,工厂方法模式提供了一种更加灵活的对象创建方式,适用于需要根据不同情况创建不同类型对象的场景。

简单工厂模式和工厂方法模式的对比

简单工厂模式(Simple Factory Pattern)和工厂方法模式(Factory Method Pattern)是两种不同的创建型设计模式,它们在对象创建的方式和角色分配上有一些不同之处。

  1. 角色定义

    • 简单工厂模式通常只涉及一个工厂类,该工厂类负责根据客户端的请求创建具体的产品对象。
    • 工厂方法模式引入了抽象工厂类和具体工厂类,使得对象的创建逻辑更加灵活。抽象工厂类定义了一个抽象的工厂方法,而具体的产品创建逻辑则由具体工厂类实现。
  2. 创建逻辑

    • 在简单工厂模式中,工厂类通常包含一个静态方法,根据不同的参数或条件返回不同类型的产品对象。
    • 而在工厂方法模式中,每个具体的产品都有对应的具体工厂类,该类负责创建特定类型的产品对象。这样,对象的创建逻辑被分散到了多个具体工厂类中。
  3. 扩展性

    • 简单工厂模式的扩展性相对较差,如果需要添加新的产品类型,则需要修改工厂类的代码,违反了开闭原则。
    • 工厂方法模式遵循了开闭原则,因为具体的产品创建逻辑在具体工厂类中,所以可以通过添加新的具体工厂类来扩展系统,而不需要修改已有的代码。
  4. 复杂度

    • 简单工厂模式相对于工厂方法模式来说,实现起来较为简单,适用于简单的场景。
    • 工厂方法模式的实现相对复杂一些,但提供了更高的灵活性和可扩展性,适用于需要根据不同情况创建不同类型对象的复杂场景。

总的来说,简单工厂模式适用于简单的对象创建场景,而工厂方法模式更适用于复杂的场景,需要更高的灵活性和可扩展性。

五、抽象工厂模式

(1)创建一个产品接口类,和两个实现类。

java">public interface PhoneProduct {void start();void shutdown();void call();void sendMes();
}public class XiaomiPhone implements PhoneProduct{@Overridepublic void start() {System.out.println("小米手机开机");}@Overridepublic void shutdown() {System.out.println("小米手机关机");}@Overridepublic void call() {System.out.println("小米手机打电话");}@Overridepublic void sendMes() {System.out.println("小米手机发短信");}
}public class HuaWeiPhone implements PhoneProduct{@Overridepublic void start() {System.out.println("华为手机开机");}@Overridepublic void shutdown() {System.out.println("华为手机关机");}@Overridepublic void call() {System.out.println("华为手机打电话");}@Overridepublic void sendMes() {System.out.println("华为手机发短信");}
}

(2)创建一个路由器接口类,和两个实现类。

java">public interface RouteProduct {void start();void shutdown();void setting();void openWife();
}public class XiaomiRoute implements RouteProduct{@Overridepublic void start() {System.out.println("小米路由器开机");}@Overridepublic void shutdown() {System.out.println("小米路由器关机");}@Overridepublic void setting() {System.out.println("小米路由器设置");}@Overridepublic void openWife() {System.out.println("小米路由器打开wife");}
}public class HuaWeiRoute implements RouteProduct{@Overridepublic void start() {System.out.println("华为路由器开机");}@Overridepublic void shutdown() {System.out.println("华为路由器关机");}@Overridepublic void setting() {System.out.println("华为路由器设置");}@Overridepublic void openWife() {System.out.println("华为路由器打开wife");}
}

(3)创建一个抽象工厂接口,已经两个系列产品的实现类。

java">public interface ProductFactory {PhoneProduct phoneProduct();RouteProduct routeProduct();
}public class HuaWeiFactory implements ProductFactory{@Overridepublic PhoneProduct phoneProduct() {return new HuaWeiPhone();}@Overridepublic RouteProduct routeProduct() {return new HuaWeiRoute();}
}public class XiaomiFactory implements ProductFactory{@Overridepublic PhoneProduct phoneProduct() {return new XiaomiPhone();}@Overridepublic RouteProduct routeProduct() {return new XiaomiRoute();}
}

(4)创建一个Client类,

java">public class Client {public static void main(String[] args) {System.out.println("----小米产品----");XiaomiFactory xiaomiFactory = new XiaomiFactory();PhoneProduct phoneProduct = xiaomiFactory.phoneProduct();RouteProduct routeProduct = xiaomiFactory.routeProduct();phoneProduct.call();routeProduct.openWife();System.out.println("----华为产品----");HuaWeiFactory huaWeiFactory = new HuaWeiFactory();PhoneProduct phoneProduct1 = huaWeiFactory.phoneProduct();RouteProduct routeProduct1 = huaWeiFactory.routeProduct();phoneProduct1.call();routeProduct1.openWife();}
}

总结

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一个接口用于创建相关或依赖对象的家族,而不需要指定具体类。抽象工厂模式属于工厂模式的一种扩展,它通过引入抽象工厂和具体工厂来解决工厂方法模式中只能创建单一产品的局限性。

在抽象工厂模式中,有两个关键的角色:

  1. 抽象工厂(Abstract Factory):定义了创建一系列产品的方法,每个方法对应一种产品。
  2. 具体工厂(Concrete Factory):实现了抽象工厂接口,负责创建具体的产品。

工厂方法模式不同的是,抽象工厂模式中一个具体工厂可以创建多个不同类型的产品,这些产品之间通常有关联性,属于同一个产品族。

适用场景:

  1. 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
  2. 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现

抽象工厂模式的优点包括:

  • 客户端与具体产品的实现相分离,客户端通过抽象工厂接口操作产品,可以方便地更换产品系列。
  • 符合开闭原则,增加新的产品族很方便,只需要增加对应的具体工厂类即可。

但是,抽象工厂模式也有一些缺点:

  • 难以支持新种类产品的变化,因为需要修改抽象工厂接口及其所有的实现。
  • 增加了系统的复杂度,引入了更多的抽象概念和类。

总的来说,抽象工厂模式适用于需要创建一系列相关或依赖对象的场景,其中产品的组合可能会变化,但产品之间的关联性固定的情况。


http://www.ppmy.cn/embedded/5521.html

相关文章

第63天:服务攻防-框架安全CVE 复现DjangoFlaskNode.JSJQuery

目录 思维导图 案例一:JavaScript-开发框架安全-Jquery&Node node.js目录穿越 CVE-2021-21315命令执行 Jquery CVE-2018-9207 案例二:Python-开发框架安全-Django&Flask django cve_2019_14234 CVE-2021-35042 flask ssti 思维导图 案…

项目实践:贪吃蛇

引言 贪吃蛇作为一项经典的游戏,想必大家应该玩过。贪吃蛇所涉及的知识也不是很难,涉及到一些C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等。这里我会介绍贪吃蛇的一些思路。以及源代码也会给大家放到文章末尾。 我们最终的…

C++11 列表初始化、initializer_list、auto、decltype、array

🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C 🔥座右铭:“不要等到什么都没有了,才下…

Rust---#[derive(Debug)]

在 Rust 中,#[derive(Debug)] 宏用于自动为结构体或枚举实现 Debug trait。Debug trait 允许一个类型的实例被格式化为字符串,通常用于调试输出。以下是 #[derive(Debug)] 通常的使用方式: 目录 定义结构体或枚举使用 println! 宏打印调试信息在自定义 Debug 实现中使用定义…

嵌入式平台code Size优化

背景 在嵌入式平台中,为了节约存储空间、内存资源,通常需要降低目标bin文件的size。下面总结下code size的优化经验。本文所说的优化主要是指的C/C++代码binary/elf size。 统计工具 工欲善其事必先利其器,首先介绍一下统计工具。在优化可执行文件size之前,要先统计一下目…

【Flutter】多语言方案二:GetX 版

介绍 多语言方案:GetX版,需要手动自定义字符串引用常量,优点不需要自己管理状态。 目录 介绍运行效果一、安装 GetX二、使用1.语言配置 在lib/core下创建一个language文件夹,文件夹下创建一个local.dart文件2.language文件夹下创…

51.基于SpringBoot + Vue实现的前后端分离-校园志愿者管理系统(项目 + 论文)

项目介绍 本站是一个B/S模式系统,采用SpringBoot Vue框架,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得基于SpringBoot Vue技术的校园志愿者管理系统设计与实现管理工…

蓝桥杯第十五界软件测试线下省赛题目分析及解决

PS 需要第十五界蓝桥杯被测系统或者功能测试模板、单元测试被测代码、自动化测试被测代码请加🐧:1940787338 备注:15界蓝桥杯省赛软件测试 题目1:功能测试 题目描述 ​ 某物流公司的货运收费标准根据重量、距离和节假日三个因素来确定。如…