设计模式之单例、工厂、观察者模式
一、单例模式
1、意图
确保一个类里面只有一个实例,并且提供一个全局访问点来访问该实例。
2、分类
2.1懒汉式
懒汉式单例在只有第一次被使用的时候才创建实例,就是懒加载。他的缺点就是在多线程的情况下可能会被创建多个实例,所以通常要加锁来确保线程的安全。
import threading
#懒汉式
class SingletonLazy:_instance_lock = threading.Lock()_instance = Nonedef __new__(cls,*args,**kwargs):if not cls._instance:with cls._instance_lock:if not cls._instance:cls._instance = super().__new__(cls)return cls._instancedef task():singleton = SingletonLazy()print(singleton)task()
# 创建多个线程来测试单例
# threads = [threading.Thread(target=task) for _ in range(10)]
# for t in threads:
# t.start()
# for t in threads:
# t.join()
2.2饿汉式
饿汉式单例就是在类加载时就完成了实例的初始化,所以他的线程是安全的。但是他的缺点是如果整个程序没有调用这个类,那么就会造成内存、资源等浪费。
class SingletonEager: _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super().__new__(cls) return cls._instance # 示例使用
singleton = SingletonEager()
print(singleton)
二、工厂模式
1、意图
提供了一种创建对象的方式,使得创建对象的过程与使用对象的过程分离。
2、分类
2.1简单工厂模式
创建一个工厂类,用于根据传入的信息(如参数、字符串等)来创建不同类型的对象。
#工厂模式
#简单工厂模式:将创建对象过程和使用对象过程分离开来
class Shape: def draw(self): pass # 这是一个抽象方法,具体实现由子类完成 # 接下来,我们定义具体的形状类
class Circle(Shape): def draw(self): print("Inside Circle::draw() method.") class Rectangle(Shape): def draw(self): print("Inside Rectangle::draw() method.") class Square(Shape): def draw(self): print("Inside Square::draw() method.") # 现在,我们定义一个形状工厂类
class ShapeFactory: @staticmethod def get_shape(shape_type): if shape_type == "CIRCLE": return Circle() elif shape_type == "RECTANGLE": return Rectangle() elif shape_type == "SQUARE": return Square() else: return None # 使用形状工厂
if __name__ == "__main__": shape1 = ShapeFactory.get_shape("CIRCLE") if shape1 is not None: shape1.draw() shape2 = ShapeFactory.get_shape("RECTANGLE") if shape2 is not None: shape2.draw() shape3 = ShapeFactory.get_shape("SQUARE") if shape3 is not None: shape3.draw() # 尝试获取一个不支持的形状类型,这里将打印None shape4 = ShapeFactory.get_shape("TRIANGLE") if shape4 is not None: shape4.draw() else: print("Shape of type TRIANGLE is not supported.")
2.2抽象工厂模式
抽象工厂模式提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。
# 产品接口
class Button: def display(self): pass class TextField: def display(self): pass # 具体产品
class WindowsButton(Button): def display(self): return "Rendering Windows Button" class MacButton(Button): def display(self): return "Rendering Mac Button" class WindowsTextField(TextField): def display(self): return "Rendering Windows TextField" class MacTextField(TextField): def display(self): return "Rendering Mac TextField" # 抽象工厂接口
class GuiFactory: def get_button(self): raise NotImplementedError("Subclasses should implement this method") def get_text_field(self): raise NotImplementedError("Subclasses should implement this method") # 具体工厂
class WindowsGuiFactory(GuiFactory): def get_button(self): return WindowsButton() def get_text_field(self): return WindowsTextField() class MacGuiFactory(GuiFactory): def get_button(self): return MacButton() def get_text_field(self): return MacTextField() # 客户端代码
def make_gui(gui_factory): button = gui_factory.get_button() text_field = gui_factory.get_text_field() print(button.display()) print(text_field.display()) if __name__ == "__main__": print("Creating Windows GUI:") make_gui(WindowsGuiFactory()) print("\nCreating Mac GUI:") make_gui(MacGuiFactory())
2.3工厂方法模式
工厂方法模式定义了一个创建对象的接口,但由子类决定实例化哪个类。工厂方法将对象的创建延迟到子类。
# 形状基类
class Shape: def draw(self): pass # 抽象方法,由子类实现 # 形状工厂基类
class ShapeFactory: def get_shape(self, shape_type): raise NotImplementedError("Subclasses should implement this method") # 圆形类
class Circle(Shape): def draw(self): print("Inside Circle::draw() method.") # 圆形工厂类
class CircleFactory(ShapeFactory): def get_shape(self, shape_type): if shape_type == "CIRCLE": return Circle() return None # 矩形类
class Rectangle(Shape): def draw(self): print("Inside Rectangle::draw() method.") # 矩形工厂类
class RectangleFactory(ShapeFactory): def get_shape(self, shape_type): if shape_type == "RECTANGLE": return Rectangle() return None # 正方形类(这里为了简单起见,可以认为正方形是矩形的一个特例,但通常会有单独的实现)
class Square(Rectangle): def draw(self): print("Inside Square::draw() method. (Note: This is a specialization of Rectangle)") # 正方形工厂类(可选,如果正方形被视为矩形的一个特例,则可能不需要单独的工厂)
class SquareFactory(RectangleFactory): # 这里可以重写get_shape来专门处理"SQUARE",但在这个例子中,我们假设使用RectangleFactory即可 pass # 使用工厂方法模式
if __name__ == "__main__": circle_factory = CircleFactory() circle = circle_factory.get_shape("CIRCLE") if circle: circle.draw() rectangle_factory = RectangleFactory() rectangle = rectangle_factory.get_shape("RECTANGLE") if rectangle: rectangle.draw() # 假设我们有一个专门的正方形工厂 square_factory = SquareFactory() square = square_factory.get_shape("SQUARE") if square: square.draw() # 注意:这里的输出可能会与Rectangle相同,因为Square继承自Rectangle # 尝试获取不支持的形状类型 unsupported_shape = circle_factory.get_shape("TRIANGLE") if not unsupported_shape: print("Shape of type TRIANGLE is not supported.")
三、观察者模式
1、概念
观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
# 定义一个观察者基类
class Observer: def update(self, message): """ 接收主题发送的消息并更新自己 """ pass # 定义一个具体的观察者类
class ConcreteObserver(Observer): def __init__(self, name): self.name = name def update(self, message): print(f"{self.name} received message: {message}") # 定义一个主题类
class Subject: def __init__(self): self.observers = [] def attach(self, observer): """ 向主题中添加观察者 """ if observer not in self.observers: self.observers.append(observer) def detach(self, observer): """ 从主题中移除观察者 """ self.observers.remove(observer) def notify(self, message): """ 通知所有观察者 """ for observer in self.observers: observer.update(message) # 使用示例
if __name__ == "__main__": # 创建主题 subject = Subject() # 创建观察者 observer1 = ConcreteObserver("Observer 1") observer2 = ConcreteObserver("Observer 2") # 将观察者添加到主题中 subject.attach(observer1) subject.attach(observer2) # 主题发送消息 subject.notify("Hello, Observers!") # 移除一个观察者 subject.detach(observer1) # 再次发送消息,只有observer2会收到 subject.notify("Only Observer 2 will receive this.")