一. 概念
工厂模式和单例模式都是面向对象编程中常用的设计模式。
工厂模式(FactoryPattern):
是一种创建型模式,它提供了一种方法来创建对象,而不需要暴露对象的创建逻辑。这种模式通过定义一个工厂类,通过工厂方法来创建对象。工厂模式可以将对象的创建过程独立到一个单独的工厂类中,从而实现解耦,降低系统的耦合性,并提高系统的可扩展性和可维护性。工厂模式包括简单工厂模式、工厂方法模式和抽象工厂模式等。单例模式(Singleton Pattern):
是一种创建型模式,它保证一个类只有一个实例,并提供一个全局访问点,让外界能够访问到这个实例。单例模式可以避免系统中出现过多的重复对象,从而提高系统的性能和效率。确保一个类只有一个实例存在,从而实现对象的共享和控制对象的创建,同时可以提高系统性能。
二. 区别
-
目的不同:工厂模式的主要目的是将对象的创建过程独立到一个单独的工厂类中,从而实现解耦,降低系统的耦合性,并提高系统的可扩展性和可维护性;而单例模式的主要目的是确保一个类只有一个实例存在,从而实现对象的共享和控制对象的创建。
-
返回值不同:工厂模式通常会返回一个新的对象实例,而单例模式则会返回同一个实例。
-
实现方式不同:工厂模式通常会定义一个工厂类,用于创建对象,可以根据不同的参数值来创建不同的对象实例;而单例模式则需要在类中定义一个静态成员对象,通过调用类的静态方法来获取这个对象实例。
三. 示例代码
1. 工厂模式
示例代码
class Car:
def __init__(self, brand):
self.brand = brand
def run(self):
print(f'{self.brand} car is running')
class CarFactory:
def create(self, brand):
return Car(brand)
car_factory = CarFactory()
car1 = car_factory.create('BMW')
car1.run()
car2 = car_factory.create('Benz')
car2.run()
print(car1 is car2)
运行结果
可以看到以上运行的结果,实例对象传进去的参数输出都是独立的,并且对象也都是不一样的。
2. 单例模式
示例代码
在类的内部,定义了一个实例变量 __instance
,并重写了 __new__
方法来控制实例的创建。在实例化该类的时候,如果实例对象不存在,则创建该实例对象,否则直接返回实例对象。
class Singleton:
__instance = None
def __new__(cls):
if not cls.__instance:
cls.__instance = super().__new__(cls)
return cls.__instance
def __init__(self):
self.at = False
def set_at(self, a):
if a:
self.at = True
else:
self.at = False
if __name__ == '__main__':
s1 = Singleton()
s2 = Singleton()
print('s1 is s2 --->', s1 == s2) # True
s1.set_at(0)
print('set s1 at -->', s1.at)
print('s2 at ------>', s2.at)
s2.set_at(1)
print('set s2 at -->', s2.at)
print('=====================')
print('s1 at -->', s1.at)
print('s2 at -->', s2.at)
运行结果
从以上运行结果我们可以看到,两个实列s1和s2创建之后是指向同一个对象的,在设置属性时也是以最后的实例设置的结果为准,这样就可以实现数据的同步与共享了。
四. 附上其他单例模式几种写法
1. 使用模块方式实现单例模式
Python中加载模块时会缓存,所以在导入一个模块时,不管导入多少次,都只会创建一个实例。
# singleton.py
class Singleton:
def __init__(self):
pass
singleton = Singleton()
# main.py
from singleton import singleton
s1 = singleton
s2 = singleton
print(s1 is s2) # 输出 True
2. 使用装饰器实现单例模式
def singleton(cls):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class MyClass:
pass
3. 使用元类实现单例模式
元类是Python中比较高级的概念,我们可以通过定义一个元类,并在该元类的__call__()方法中判断类是否已经被实例化,从而实现单例模式。
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class MyClass(metaclass=SingletonMeta):
pass
s1 = MyClass()
s2 = MyClass()
print(s1 == s2) # 输出True
在上面的代码中,我们创建了一个元类 SingletonMeta
,它继承自 type 类,同时重写了 __call__
方法。__call__
方法在创建实例的时候被调用,我们重写了该方法来控制实例的创建。在实例化 Singleton
的时候,会自动调用元类中的 __call__
方法,创建实例对象。
五. 总结
工厂模式和单例模式是两种不同的设计模式,它们的目的和实现方式都有所不同。工厂模式主要用于对象的创建,单例模式则主要用于对象的共享。在实际应用中,我们可以根据具体的需求和场景进行选择。