📜  享元法Python设计模式

📅  最后修改于: 2022-05-13 01:54:44.870000             🧑  作者: Mango

享元法Python设计模式

Flyweight方法是一种结构设计模式,专注于最小化程序在运行时所需的对象数量。基本上,它创建了一个由多个上下文共享的享元对象。它以您无法区分对象和享元对象的方式创建。享元对象的一个重要特征是它们是不可变的。这意味着它们一旦构建就无法修改。
为了在Python中实现享元方法,我们使用Dictionary存储对已创建对象的引用,每个对象都与一个键相关联。

为什么我们要关心程序中的对象数量?

  • 更少的对象减少了内存使用,它设法让我们远离与内存相关的错误
  • 虽然在Python中创建对象确实很快,但我们仍然可以通过共享对象来减少程序的执行时间。

不使用享元法的问题

想象一下,您是一位非常喜欢赛车游戏的游戏开发者,也想为您和您的朋友开发一款赛车游戏。作为一个完美的游戏开发者,您创建了一个并开始享受游戏。然后你把游戏也发给了你的朋友,但他不太喜欢游戏,因为游戏每隔几分钟就会崩溃。
但为什么? (如果您认为自己是专业游戏开发者,请猜猜原因) 。经过几个小时的调试,您发现问题是您朋友的系统内存不足。与您朋友的系统相比,您的系统功能强大得多,这就是为什么游戏在您的系统上运行顺畅,但在您朋友的系统上却运行不畅的原因。

享元问题图

享元问题图

使用享元法的解决方案

那么,作为开发人员,您将如何提高性能呢? (当然!不打算升级 RAM) 。实际问题与汽车对象有关,因为每辆汽车都由单独的对象表示,其中包含与其颜色、大小、座位、最大速度等相关的大量数据。每当你的 RAM 得到填充并且无法添加当前需要的更多新对象,您的游戏会崩溃。为了避免在应用程序中出现这种情况,开发人员的首要职责是使用享元方法,它允许您通过共享对象的公共部分将更多对象放入可用的 RAM 量。

轻量级汽车

以下代码是使用享元方法编写的

Python3
class ComplexCars(object):
 
    """Separate class for Complex Cars"""
 
    def __init__(self):
 
        pass
 
    def cars(self, car_name):
 
        return "ComplexPattern[% s]" % (car_name)
 
 
class CarFamilies(object):
 
    """dictionary to store ids of the car"""
 
    car_family = {}
 
    def __new__(cls, name, car_family_id):
        try:
            id = cls.car_family[car_family_id]
        except KeyError:
            id = object.__new__(cls)
            cls.car_family[car_family_id] = id
        return id
 
    def set_car_info(self, car_info):
 
        """set the car information"""
 
        cg = ComplexCars()
        self.car_info = cg.cars(car_info)
 
    def get_car_info(self):
 
        """return the car information"""
 
        return (self.car_info)
 
 
 
if __name__ == '__main__':
    car_data = (('a', 1, 'Audi'), ('a', 2, 'Ferrari'), ('b', 1, 'Audi'))
    car_family_objects = []
    for i in car_data:
        obj = CarFamilies(i[0], i[1])
        obj.set_car_info(i[2])
        car_family_objects.append(obj)
 
    """similar id's says that they are same objects """
 
    for i in car_family_objects:
        print("id = " + str(id(i)))
        print(i.get_car_info())


输出

id = 58598800
ComplexPattern[Audi]
id = 58598832
ComplexPattern[Ferrari]
id = 58598800
ComplexPattern[Audi]

类图

下面是享元方法的类图

享元级图

享元级图

好处

  • 减少 RAM 的使用:当我们的应用程序中有很多类似的对象时,最好使用Flyweight 方法以节省大量 RAM 空间
  • 改进的数据缓存:当客户端或用户需要高响应时间时,总是首选使用享元方法,因为它有助于改进数据缓存。
  • 提高性能:它最终会导致性能提高,因为我们使用的重物数量更少。

缺点

  • 打破封装:每当我们试图将状态移动到对象之外时,我们都会打破封装,并且可能会变得比将状态保持在对象内部效率低。
  • 难以处理:享元方法的使用取决于我们使用的语言,易于在Python、 Java等语言中使用,其中所有对象变量都是引用,但通常在 C、C++ 等语言中使用,其中对象可以作为局部变量分配在由于程序员的操作,堆栈和销毁。
  • 复杂的代码:使用享元方法总是会增加代码的复杂性,以便新开发人员理解。

适用性

  • 减少对象的数量:一般来说,当我们的应用程序有很多重量级的对象时,会使用享元方法,为了解决这个问题,我们使用享元方法来摆脱不必要的内存消耗。
  • 对象独立应用程序:当我们的应用程序如果独立于对象创建时,那么我们可以利用这种方法来节省大量的机器空间。
  • 项目成本降低:当需要在空间和时间复杂度方面降低项目成本时,总是首选使用享元法。

进一步阅读Java中的享元方法