【软件设计】常用设计模式--工厂模式

2024-09-06 02:52

本文主要是介绍【软件设计】常用设计模式--工厂模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

软件设计模式(二)

    • 一、工厂模式(Factory Pattern)
      • 1. 概念
      • 2. 工厂模式的类型
      • 3. 实现方式
        • (1)简单工厂模式
          • C# 实现
          • Java 实现
        • (2)工厂方法模式
          • C# 实现
          • Java 实现
        • (3)抽象工厂模式
          • C# 实现
          • Java 实现
      • 4. 优点
      • 5. 缺点
      • 6. 适用场景
      • 小结
    • 二、工厂模式变体
      • 1. 简单工厂模式的变体
        • 变体1: 参数化工厂
          • C# 示例
        • 变体2: 反射工厂
          • C# 示例
      • 2. 工厂方法模式的变体
        • 变体1: 可配置工厂
          • C# 示例
        • 变体2: 延迟初始化
          • C# 示例
      • 3. 抽象工厂模式的变体
        • 变体1: 层次结构的抽象工厂
          • C#示例
        • 变体2: 工厂生产线
          • C#示例
      • 4. 实际应用场景
        • 场景1: 数据库连接管理
          • C#示例
        • 场景2: GUI 元素创建
          • C#示例
        • 场景3: 日志系统
          • C#示例
      • 小结

一、工厂模式(Factory Pattern)

1. 概念

工厂模式通过定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂模式让一个类的实例化延迟到子类进行,从而实现代码的松耦合扩展性

2. 工厂模式的类型

工厂模式有几种不同的实现方式:

  • 简单工厂模式(Simple Factory): 使用一个工厂类根据传递的参数决定创建哪个具体类的实例。
  • 工厂方法模式(Factory Method): 定义一个创建对象的接口,让子类决定具体实例化哪个类。
  • 抽象工厂模式(Abstract Factory): 提供一个接口,用于创建一系列相关或互相依赖的对象,而无需指定它们具体的类。

3. 实现方式

我们先从最基础的简单工厂模式开始,然后逐步介绍工厂方法模式和抽象工厂模式。

(1)简单工厂模式

简单工厂模式通常使用一个静态方法来根据传入的参数创建不同的对象。

C# 实现
public abstract class Product
{public abstract void DoSomething();
}public class ConcreteProductA : Product
{public override void DoSomething(){Console.WriteLine("Product A is doing something.");}
}public class ConcreteProductB : Product
{public override void DoSomething(){Console.WriteLine("Product B is doing something.");}
}public class ProductFactory
{public static Product CreateProduct(string type){switch (type){case "A":return new ConcreteProductA();case "B":return new ConcreteProductB();default:throw new ArgumentException("Invalid product type.");}}
}
  • 使用方法: Product product = ProductFactory.CreateProduct("A");
Java 实现
abstract class Product {abstract void doSomething();
}class ConcreteProductA extends Product {@Overridevoid doSomething() {System.out.println("Product A is doing something.");}
}class ConcreteProductB extends Product {@Overridevoid doSomething() {System.out.println("Product B is doing something.");}
}class ProductFactory {public static Product createProduct(String type) {switch (type) {case "A":return new ConcreteProductA();case "B":return new ConcreteProductB();default:throw new IllegalArgumentException("Invalid product type.");}}
}

使用方法: Product product = ProductFactory.createProduct("A");

(2)工厂方法模式

在工厂方法模式中,创建对象的逻辑被推迟到子类中,而不是集中在一个工厂类中。

C# 实现
public abstract class Product
{public abstract void DoSomething();
}public class ConcreteProductA : Product
{public override void DoSomething(){Console.WriteLine("Product A is doing something.");}
}public class ConcreteProductB : Product
{public override void DoSomething(){Console.WriteLine("Product B is doing something.");}
}public abstract class Creator
{public abstract Product FactoryMethod();public void AnOperation(){var product = FactoryMethod();product.DoSomething();}
}public class ConcreteCreatorA : Creator
{public override Product FactoryMethod(){return new ConcreteProductA();}
}public class ConcreteCreatorB : Creator
{public override Product FactoryMethod(){return new ConcreteProductB();}
}

使用方法:

Creator creator = new ConcreteCreatorA();
creator.AnOperation();
Java 实现
abstract class Product {abstract void doSomething();
}class ConcreteProductA extends Product {@Overridevoid doSomething() {System.out.println("Product A is doing something.");}
}class ConcreteProductB extends Product {@Overridevoid doSomething() {System.out.println("Product B is doing something.");}
}abstract class Creator {public abstract Product factoryMethod();public void anOperation() {Product product = factoryMethod();product.doSomething();}
}class ConcreteCreatorA extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductA();}
}class ConcreteCreatorB extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductB();}
}

使用方法:

Creator creator = new ConcreteCreatorA();
creator.anOperation();
(3)抽象工厂模式

抽象工厂模式通过为一系列相关或依赖的对象提供一个创建接口,使得客户端可以不必指定具体的类名,就可以创建对象族。

C# 实现
public abstract class ProductA { }
public abstract class ProductB { }public class ConcreteProductA1 : ProductA { }
public class ConcreteProductA2 : ProductA { }
public class ConcreteProductB1 : ProductB { }
public class ConcreteProductB2 : ProductB { }public abstract class AbstractFactory
{public abstract ProductA CreateProductA();public abstract ProductB CreateProductB();
}public class ConcreteFactory1 : AbstractFactory
{public override ProductA CreateProductA() => new ConcreteProductA1();public override ProductB CreateProductB() => new ConcreteProductB1();
}public class ConcreteFactory2 : AbstractFactory
{public override ProductA CreateProductA() => new ConcreteProductA2();public override ProductB CreateProductB() => new ConcreteProductB2();
}

使用方法:

AbstractFactory factory = new ConcreteFactory1();
ProductA productA = factory.CreateProductA();
ProductB productB = factory.CreateProductB();
Java 实现
abstract class ProductA { }
abstract class ProductB { }class ConcreteProductA1 extends ProductA { }
class ConcreteProductA2 extends ProductA { }
class ConcreteProductB1 extends ProductB { }
class ConcreteProductB2 extends ProductB { }abstract class AbstractFactory {abstract ProductA createProductA();abstract ProductB createProductB();
}class ConcreteFactory1 extends AbstractFactory {@OverrideProductA createProductA() {return new ConcreteProductA1();}@OverrideProductB createProductB() {return new ConcreteProductB1();}
}class ConcreteFactory2 extends AbstractFactory {@OverrideProductA createProductA() {return new ConcreteProductA2();}@OverrideProductB createProductB() {return new ConcreteProductB2();}
}

使用方法:

AbstractFactory factory = new ConcreteFactory1();
ProductA productA = factory.createProductA();
ProductB productB = factory.createProductB();

4. 优点

  • 解耦创建和使用: 客户端代码不直接依赖于具体产品类,降低了代码的耦合度。
  • 可扩展性强: 新的产品可以通过增加新的工厂类或方法实现,而不需要修改现有代码。

5. 缺点

  • 增加复杂性: 引入工厂模式可能会增加系统的复杂性,特别是在简单对象创建的场景中。
  • 抽象工厂的维护: 随着产品族的增加,抽象工厂模式可能会导致过多的类和接口。

6. 适用场景

  • 对象创建过程复杂: 适用于需要复杂对象创建过程的场景,如多个依赖对象的创建、对象的条件创建等。
  • 系统解耦: 需要将对象的创建和使用解耦的场景,如插件系统、依赖注入等。

小结

工厂模式在创建对象时提供了灵活性和可扩展性。经过上面的学习,不难发现,从简单工厂模式到工厂模式,再到抽象工厂模式,实际就是对软件架构进一步解耦的过程,提高代码的扩展性,也使得软件架构能够更加的灵活。

二、工厂模式变体

1. 简单工厂模式的变体

虽然简单工厂模式是最基础的,但在某些情况下,我们可以通过参数化或动态生成对象来增强它的功能。

变体1: 参数化工厂

在这个变体中,工厂方法接受不同的参数类型,不仅仅是一个标识符字符串,还可以是枚举、配置对象或条件判断等。

C# 示例
public enum ProductType
{ProductA,ProductB
}public class ProductFactory
{public static Product CreateProduct(ProductType type){switch (type){case ProductType.ProductA:return new ConcreteProductA();case ProductType.ProductB:return new ConcreteProductB();default:throw new ArgumentException("Invalid product type.");}}
}
变体2: 反射工厂

可以通过反射来动态创建对象,从而减少分支逻辑的硬编码。

C# 示例
public class ProductFactory
{public static Product CreateProduct(string className){Type type = Type.GetType(className);return (Product)Activator.CreateInstance(type);}
}

这种方法可以在运行时通过类的名称或其他元数据信息来创建对象,适合大型系统中的动态扩展需求。

2. 工厂方法模式的变体

工厂方法模式可以根据不同的扩展需求进行调整,通常适合创建复杂对象时使用。下面是一些变体:

变体1: 可配置工厂

工厂方法可以通过读取配置文件或外部资源来确定创建的对象类型。比如在Web开发中,可以通过读取XML或JSON文件来动态配置具体类的选择。

C# 示例
public class ConfigurableProductFactory : Creator
{public override Product FactoryMethod(){string type = ConfigurationManager.AppSettings["ProductType"];if (type == "A")return new ConcreteProductA();elsereturn new ConcreteProductB();}
}
变体2: 延迟初始化

有时候我们需要延迟创建对象,以便减少内存占用或提高启动速度。可以结合工厂模式和延迟加载模式来实现这种需求。

C# 示例
public class LazyProductFactory : Creator
{private Product _product;public override Product FactoryMethod(){if (_product == null){_product = new ConcreteProductA(); // 延迟创建对象}return _product;}
}

3. 抽象工厂模式的变体

抽象工厂模式是工厂模式的进一步抽象,可以为对象族创建工厂。通常用于需要创建多个相关对象时,但在实际应用中,可以进一步优化和扩展。

变体1: 层次结构的抽象工厂

在复杂的系统中,抽象工厂可以为不同的产品层次结构创建工厂。比如,一个GUI系统可能有不同的控件类型,每种控件类型都有对应的工厂。

C#示例
// 抽象工厂为不同控件创建工厂
public abstract class GUIFactory
{public abstract Button CreateButton();public abstract Checkbox CreateCheckbox();
}// Windows 工厂
public class WindowsFactory : GUIFactory
{public override Button CreateButton() => new WindowsButton();public override Checkbox CreateCheckbox() => new WindowsCheckbox();
}// Mac 工厂
public class MacFactory : GUIFactory
{public override Button CreateButton() => new MacButton();public override Checkbox CreateCheckbox() => new MacCheckbox();
}

这种层次结构的抽象工厂使得我们可以轻松扩展支持新的操作系统或设备。

变体2: 工厂生产线

在某些复杂应用中,抽象工厂不仅仅用于创建单个对象,而是用于创建一组相关的对象。比如在游戏开发中,工厂可以创建整个生态系统的对象,如玩家角色、敌人、道具等。

C#示例
public abstract class GameFactory
{public abstract Player CreatePlayer();public abstract Enemy CreateEnemy();public abstract Item CreateItem();
}

4. 实际应用场景

场景1: 数据库连接管理

工厂模式可以用于管理数据库连接。例如,不同的数据库(如SQL Server、MySQL、Oracle)可以通过工厂模式进行选择,实现不同数据库的连接对象。

C#示例
public abstract class DatabaseConnectionFactory
{public abstract IDbConnection CreateConnection();
}public class SqlServerConnectionFactory : DatabaseConnectionFactory
{public override IDbConnection CreateConnection(){return new SqlConnection();}
}public class MySqlConnectionFactory : DatabaseConnectionFactory
{public override IDbConnection CreateConnection(){return new MySqlConnection();}
}

客户端代码可以动态决定使用哪种数据库,而不需要知道具体的实现。

场景2: GUI 元素创建

GUI系统中,控件类型众多且随平台不同。通过工厂模式,可以轻松支持不同平台的控件,如Windows和Mac的按钮、文本框等。

C#示例
GUIFactory factory = new WindowsFactory();
Button button = factory.CreateButton();
Checkbox checkbox = factory.CreateCheckbox();
场景3: 日志系统

工厂模式可以根据配置文件或运行时参数决定使用哪种日志记录系统,比如文件日志、数据库日志、远程日志等。

C#示例
public abstract class LoggerFactory
{public abstract ILogger CreateLogger();
}public class FileLoggerFactory : LoggerFactory
{public override ILogger CreateLogger(){return new FileLogger();}
}

小结

工厂模式的变体和应用场景非常广泛,无论是在对象创建、系统解耦还是灵活扩展中都能提供极大的便利。不同场景可以根据需求选择不同的工厂模式变体,如动态对象创建、延迟加载、配置驱动等。通过结合工厂模式与其他设计模式(如策略模式、装饰器模式等),可以实现更加灵活和可维护的架构。

这篇关于【软件设计】常用设计模式--工厂模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140802

相关文章

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

Python正则表达式语法及re模块中的常用函数详解

《Python正则表达式语法及re模块中的常用函数详解》这篇文章主要给大家介绍了关于Python正则表达式语法及re模块中常用函数的相关资料,正则表达式是一种强大的字符串处理工具,可以用于匹配、切分、... 目录概念、作用和步骤语法re模块中的常用函数总结 概念、作用和步骤概念: 本身也是一个字符串,其中

Nginx location匹配模式与规则详解

《Nginxlocation匹配模式与规则详解》:本文主要介绍Nginxlocation匹配模式与规则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、环境二、匹配模式1. 精准模式2. 前缀模式(不继续匹配正则)3. 前缀模式(继续匹配正则)4. 正则模式(大

usb接口驱动异常问题常用解决方案

《usb接口驱动异常问题常用解决方案》当遇到USB接口驱动异常时,可以通过多种方法来解决,其中主要就包括重装USB控制器、禁用USB选择性暂停设置、更新或安装新的主板驱动等... usb接口驱动异常怎么办,USB接口驱动异常是常见问题,通常由驱动损坏、系统更新冲突、硬件故障或电源管理设置导致。以下是常用解决

springboot项目中常用的工具类和api详解

《springboot项目中常用的工具类和api详解》在SpringBoot项目中,开发者通常会依赖一些工具类和API来简化开发、提高效率,以下是一些常用的工具类及其典型应用场景,涵盖Spring原生... 目录1. Spring Framework 自带工具类(1) StringUtils(2) Coll

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M

Linux上设置Ollama服务配置(常用环境变量)

《Linux上设置Ollama服务配置(常用环境变量)》本文主要介绍了Linux上设置Ollama服务配置(常用环境变量),Ollama提供了多种环境变量供配置,如调试模式、模型目录等,下面就来介绍一... 目录在 linux 上设置环境变量配置 OllamPOgxSRJfa手动安装安装特定版本查看日志在