快速入门C#设计模式【1】创建型模式

2024-08-13 19:28:49 浏览数 (3)

创建型模式

创建型模式主要关注对象的创建机制,使得系统在创建对象时更加灵活和可复用。

  1. 单例(Singleton)
  2. 工厂方法(Factory Method)
  3. 抽象工厂(Abstract Factory)
  4. 建造者(Builder)
  5. 原型(Prototype)

单例模式

单例模式(Singleton Pattern)是一种常用的设计模式,用于确保一个类只有一个实例,并提供一个全局访问点。单例模式通常用于管理共享资源,例如配置文件、线程池等。

单例模式的基本概念

单例模式的核心是确保一个类仅有一个实例,并提供一个全局的访问点来获取这个实例。其主要特点包括:

  • 私有的构造函数:防止外部通过new关键字创建类的实例。
  • 类中有一个私有静态变量存储类的唯一实例。
  • 一个公共的静态方法用于获取这个实例,这个方法通常是线程安全的。

实现单例模式的方法

1. 懒汉式(线程安全)

懒汉式单例模式指的是实例在第一次使用时才被创建。这种方式通常会通过lock关键字来保证线程安全,但这可能会影响性能。

2. 饿汉式(线程安全)

饿汉式单例模式指的是实例在类加载时立即创建。由于CLR(公共语言运行时)控制着静态初始化,因此这种方式本身就是线程安全的。

3. 双重检查锁定

双重检查锁定(Double-Check Locking)是一种结合了懒汉式和线程安全的优点的方法。它首先检查实例是否已创建,如果未创建,才进行同步。这样,只有第一次访问时会同步,提高了效率。

使用场景

单例模式适用于以下情况:

  • 当类只需要一个实例且客户可以从一个众所周知的访问点访问它时。
  • 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

单例模式是一种有用的模式,但也要注意不要滥用,因为它可能会引入全局状态的问题,在多线程环境中尤其需要注意实现的线程安全。

工厂方法模式

工厂方法模式(Factory Method Pattern)是面向对象设计模式中的一种常用模式。工厂方法模式是创建型模式之一,用于在不直接调用构造函数的情况下创建对象,提供了一种封装对象创建的机制。

工厂方法模式的基本概念

工厂方法模式的目的是定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。主要特点包括:

  • 产品接口:定义了产品对象的公共接口。
  • 具体产品:实现产品接口的具体类。
  • 创建者类:声明工厂方法,该方法返回一个产品类型的对象。创建者的子类通常提供此方法的实现。
  • 具体创建者:重写工厂方法以返回一个具体产品实例。

工厂方法模式的实现

下面通过一个简单的例子展示如何在 C# 中实现工厂方法模式。假设我们有一个日志系统,它可以输出不同类型的日志(如文件日志、数据库日志等)。

1. 产品接口

这是定义所有具体产品必须实现的接口。

2. 具体产品

这些类实现了产品接口。

3. 创建者类

这是一个抽象类,包含一个声明返回产品接口对象的工厂方法。

4. 具体创建者

这些类实现了在基类中声明的工厂方法,以决定实例化哪个具体产品类。

使用示例

在客户端代码中,可以通过创建者的引用使用工厂方法,而不需要知道具体产品的类名。

执行效果:

使用场景

工厂方法模式非常适用于以下情况:

  • 当一个类不知道它所必须创建的对象的类的时候。
  • 当一个类希望由其子类来指定创建的对象时。
  • 当类将创建对象的责任委托给多个帮助子类中的一个,并且你想将哪个帮助子类是代理者这一信息局部化时。

抽象工厂

抽象工厂模式(Abstract Factory Pattern)是另一种常用的创建型设计模式。这个模式提供了一个接口,用于创建相关或依赖对象的家族,而无需指定具体类。抽象工厂模式是工厂方法模式的一种扩展,它使用多个工厂方法。

抽象工厂模式的基本概念

抽象工厂模式的目的是允许一个系统独立于其产品的创建、组合和表示方式。该模式提供了一系列用于创建一系列相关或相互依赖对象的接口,而不需要指定它们具体的类。主要特点包括:

  • 抽象工厂:提供一个创建一系列相关或相互依赖对象的接口。
  • 具体工厂:实现抽象工厂的操作以创建具体的产品对象。
  • 抽象产品:为一类产品对象声明一个接口。
  • 具体产品:抽象产品的实现对象,定义一个将被相应的具体工厂创建的产品对象。

实现抽象工厂模式

下面通过一个实例,比如假设有一个跨平台的UI组件库,来展示如何在 C# 中实现抽象工厂模式。这个库可以创建按钮和窗口,并且根据不同的操作系统(如 Windows 和 macOS)有不同的表现。

1. 抽象

定义按钮和窗口的接口。

2. 具体产品

根据不同的操作系统实现具体的按钮和窗口。

3. 抽象工厂

定义一个接口来创建一组相关的对象。

4. 具体工厂

实现具体的创建方法,每个工厂负责创建特定操作系统的组件。

使用示例

客户端代码可以通过抽象工厂的引用来创建不同的产品组,而不需要知道具体产品的类名。

运行结果:

使用场景

抽象工厂模式适用于以下情况:

  • 当系统需要独立于如何创建、组成和表示产品时。
  • 当系统应该被配置为一系列相互依赖的多个产品族之一时。
  • 当一组产品对象被设计为一起使用时,这使得需要强制此约束成为必要。
  • 当你想提供一组产品的库,并只想显示它们的接口而不是实现时。

抽象工厂模式能够提高系统的灵活性和可扩展性,但可能增加了系统的复杂性,并且难以支持新种类的产品,因为它需要扩展抽象工厂的接口。

建造者模式

建造者模式(Builder Pattern)是一种常用的创建型设计模式,主要用于构建一个复杂的对象,同时允许步骤化地创建其内部结构。与工厂模式不同,建造者模式更加关注对象构建的过程,而不仅仅是最终产品。这使得建造者模式非常适用于那些需要创建具有复杂内部结构的对象的情况。

建造者模式的基本概念

建造者模式的主要目标是分离一个复杂对象的构建和其表示,使得同样的构建过程可以创建不同的表示。其主要特点包括:

建造者(Builder):为创建一个产品对象的各个部件指定抽象接口。

具体建造者(Concrete Builder):实现 Builder 的接口以构造和装配该产品的各个部件。定义并明确它所创建的表示,并提供一个检索产品的接口。

指挥者(Director):构造一个使用 Builder 接口的对象。

产品(Product):表示被构造的复杂对象。ConcreteBuilder 创建该产品的内部表示并定义它的装配过程。

实现建造者模式

以下是一个关于如何在 C# 中实现建造者模式的简单示例。假设我们需要构建一个复杂的汽车对象,它包含发动机、轮胎和门等部件。

1. 产品类

定义产品,即最终要构建的对象。

2. 建造者接口

定义所有类型建造者将会遵循的接口。

3. 具体建造者

实现具体的建造步骤来创建产品。

4. 指挥者

负责按顺序构建最终产品。

使用示例

下面的代码展示了如何使用建造者模式构建对象。

运行效果:

使用场景

建造者模式适用于以下场景:

  • 当创建复杂对象的算法应独立于该对象的组成部分以及它们的装配方式时。
  • 当构造过程必须允许被构造的对象有不同的表示时。

通过使用建造者模式,可以更灵活地控制对象的创建过程,同时将对象的构造代码与其表示代码分离,增加代码的可维护性和可扩展性。

原型模式

原型模式(Prototype Pattern)是一种创建型设计模式,用于创建对象的复制(克隆)操作,从而允许从一个原型实例创建新的对象,而无需了解任何具体的类信息。原型模式是基于对象的克隆来创建扩展对象,这通常适用于创建成本较高的实例时。

原型模式的基本概念

原型模式的核心思想是通过复制一个现有对象来创建新的对象。在 C# 中,这通常通过实现 ICloneable 接口来实现。这个模式主要用于:

  • 当直接创建对象的成本比较高时,可以通过复制已有对象获得更高效的性能。
  • 当对象之间的差异较小,通过克隆后进行少量的修改比全新创建更为高效时。

原型模式的关键组件

  • 原型(Prototype):定义用于复制现有对象以产生新对象的接口。
  • 具体原型(Concrete Prototype):实现原型接口的类。

C# 中的实现

在 C# 中,ICloneable 接口提供了一个 Clone() 方法,用于创建一个当前对象的浅表副本。实现深拷贝时,需要自定义复制逻辑来确保所有的对象成员也被适当地复制。

示例:克隆图书对象

假设我们有一个 Book 类,每本书有标题和作者。我们将实现原型模式来克隆书籍对象。

使用示例

以下代码演示了如何使用 Clone() 方法来创建图书对象的副本。以及运行结果。

使用场景

原型模式特别适用于以下情况:

  • 当创建新的对象实例成本较高或复杂时,可以通过复制和修改现有实例来获取新实例。
  • 当需要独立于具体类的方式来生成实例时。这种模式允许动态增加或减少产品类。

原型模式在实际应用中可以极大地提高代码的灵活性和可扩展性,但也需要注意管理好原始对象与克隆对象之间的依赖关系,尤其是在处理深拷贝时。

创建型设计模式就到这儿,感兴趣可以上gitee获取以上测试的源码:

https://gitee.com/dreamer_j/design-patterns.git

0 人点赞