chatGPT教你设计模式[3] ——创建型模式(单例模式、建造者模式和原型模式)

1. 引言

在上一篇博客中,我们已经介绍了创建者模式的最主要的部分:工厂模式及其变种。本篇博客将继续介绍创建者模式的其他三种模式:单例模式、建造者模式和原型模式。这三种模式都用于控制对象的创建过程,但是它们使用了不同的方法。单例模式确保某个类只有一个实例,建造者模式提供了一种分离复杂对象的构建过程和它的表示的方式的方法,而原型模式允许在运行时动态地创建新的对象副本。在本篇博客中,我们将深入探究这三种模式,了解它们的优缺点和使用场景,并通过示例代码加深理解。本篇博客将带你进一步探究设计模式的魅力,并让你学会在软件设计中如何使用这三种模式。请持续关注我们的博客,一起深入探索设计模式的精髓。

2. 单例模式

单例模式是一种创建型设计模式,它的主要目的是确保一个类只有一个实例,并为这个唯一的实例提供一个全局访问点。

单例模式可以用在以下几种情况:

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

2.1 示例代码

class Singleton:
    __instance = None
    def __init__(self):
        if not Singleton.__instance:
            print("__init__ method called.")
        else:
            print("Instance already created:", self.getInstance())
 
    @classmethod
    def getInstance(cls):
        if not cls.__instance:
            cls.__instance = Singleton()
        return cls.__instance
 
s = Singleton()
print("Object created", s)
s1 = Singleton()

执行结果:

__init__ method called.
Object created <__main__.Singleton object at 0x10dc6f320>
Instance already created: <__main__.Singleton object at 0x10dc6f320>

2.2 优缺点

优点

  • 只有一个实例,节省了内存空间。
  • 可以避免对资源的多重占用。
  • 可以方便地访问它。

缺点:

  • 没有抽象层,不能形成基于继承的等级结构。
  • 在实现时可能需要消耗一定的系统资源,如果实例化的对象非常多,可能会导致系统性能下降。
  • 可能会导致某些系统设计上的不合理。

2.3 应用场景

单例模式的组织架构如下:

单例类:包含一个实例变量来存储自己的唯一实例,并提供一个静态方法来获取这个实例。

应用场景有以下几种:

要求生成唯一序列号的环境,如在数据库中使用。
在整个项目中需要一个共享访问点或共享数据,例如计数器。
创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源。

3. 建造者模式

建造者模式是一种对象创建型设计模式,它可以将复杂对象的创建过程抽象出来,使得该对象的创建过程独立于它的组成部分以及它们的装配方式。这样,在实例化对象时可以更灵活地指定它们的组成部分。

3.1 优缺点

优点:

  • 隔离了具体组装过程和最终产品,使得相同的构建过程可以创建不同的产品对象。
  • 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品。

缺点:

  • 产品的组成部分必须相同,这限制了其使用范围。
  • 如果产品的内部变化复杂,该模式会增加很多的建造者类。

3.2 组织架构

建造者模式的组织架构包括:

  • Product:产品类,用于表示建造者模式中的复杂对象。
  • Builder:抽象建造者类,为创建一个Product对象的各个部件指定抽象接口。
  • ConcreteBuilder:具体建造者类,实现Builder类定义的接口,构造和装配各个部件。
  • Director:指挥者类,构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。

3.3 应用场景

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

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

例如,在建造一个房子时,可能需要使用建造者模式,因为房子由许多不同的部分组成,比如地基、墙、门窗等,而这些部分的创建算法应该独立于房子的具体组成情况,同时也可能会有不同的表示方式,例如有的房子有一层,有的房子有两层甚至更多层。

3.4 代码示例

class House:
    def __init__(self):
        self.__walls = None
        self.__floors = None
        self.__roof = None

    def set_walls(self, walls):
        self.__walls = walls
    def set_floors(self, floors):
        self.__floors = floors
    def set_roof(self, roof):
        self.__roof = roof

class HouseBuilder:
    def build_walls(self):
        pass
    def build_floors(self):
        pass
    def build_roof(self):
        pass

class WoodenHouseBuilder(HouseBuilder):
    def build_walls(self):
        return "Building wooden walls."
    def build_floors(self):
        return "Building wooden floors."
    def build_roof(self):
        return "Building wooden roof."

class ConcreteHouseBuilder(HouseBuilder):
    def build_walls(self):
        return "Building concrete walls."
    def build_floors(self):
        return "Building concrete floors."
    def build_roof(self):
        return "Building concrete roof."

class HouseDirector:
    def __init__(self):
        self.__builder = None

    def set_builder(self, builder):
        self.__builder = builder

    def build_house(self):
        self.__builder.build_walls()
        self.__builder.build_floors()
        self.__builder.build_roof()

# Client code
director = HouseDirector()
director.set_builder(WoodenHouseBuilder())
director.build_house()

director.set_builder(ConcreteHouseBuilder())
director.build_house()

在这个示例中,我们有三个类:House、HouseBuilder和HouseDirector。House类代表要建造的房子,它有三个属性:墙、地板和屋顶。HouseBuilder类是一个抽象建造者类,它定义了建造房子的各个部分的抽象接口,具体的建造者类需要实现这些抽象接口。

4. 原型模式

原型模式是一种创建型设计模式,用于创建新的对象,而不是直接通过 new 关键字进行创建。在原型模式中,一个原型对象被复制多份,每一份都是原来的对象的一个拷贝。这样就可以避免使用 new 关键字来创建对象,避免了创建对象的复杂度。

4.1 优缺点

优点:

  • 减少了系统中对象的创建,降低了内存占用
  • 避免了创建复杂对象的复杂度
  • 通过复制已有的对象,可以快速构建新的对象

缺点:

  • 需要为每个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行较大的改造,这会带来一些使用上的麻烦
  • 在实现克隆方法时,需要考虑浅克隆和深克隆的问题

4.2 组织架构

原型模式的组织架构主要包括以下三个角色:

  • Prototype:抽象原型类,定义了克隆自身的抽象方法。
  • ConcretePrototype:具体原型类,实现了克隆自身的抽象方法。
  • Client:客户类,通过调用克隆方法来获取新的对象。

4.3 应用场景

原型模式常用于创建重复的对象,称为克隆。当直接创建对象的代价比较大时,可以使用原型模式,通过复制一个已经存在的对象来获得新的对象,如果需要修改对象的属性,可以直接修改克隆出来的对象。

4.4 代码示例

class Circle:
    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius

    def __str__(self):
        return f"Circle(x={self.x}, y={self.y}, radius={self.radius})"

    def clone(self):
        return Circle(self.x, self.y, self.radius)

# 使用原型模式
circle1 = Circle(1, 2, 3)
print(circle1)  # 输出 "Circle(x=1, y=2, radius=3)"

# 复制原型
circle2 = circle1.clone()
print(circle2)  # 输出 "Circle(x=1, y=2, radius=3)"

# 修改原型的属性,不会影响复制的原型
circle1.x = 10
circle1.y = 20
circle1.radius = 30
print(circle1)  # 输出 "Circle(x=10, y=20, radius=30)"
print(circle2)  # 输出 "Circle(x=1, y=2, radius=3)"


5. 小结

在这篇博客中,我们已经介绍了创建者模式中的三种模式——单例模式、建造者模式和原型模式。我们探讨了每种模式的优缺点、组织架构和使用场景,并且使用python的示例代码加深了对这三种模式的理解。这些模式都有助于我们在软件设计中创建对象,并且能够帮助我们更好地控制对象的创建过程。在下一篇博客中,我们将会介绍结构性模式,敬请关注。

猜你喜欢

转载自blog.csdn.net/qq_35082030/article/details/128437978
今日推荐