Image Deduplicator:一站式AI图像去重解决方案,高效清理重复图片
2026/7/14 15:18:47
欢迎来到第67天!
写代码就像盖房子。初学者只要能把砖头砌起来,房子不塌就行。但资深工程师追求的是结构优雅、易于维护、可扩展。
设计模式 (Design Patterns)就是前人总结出来的"建筑图纸"。遇到什么问题,套用什么模式,往往能事半功倍。
本节内容:
通常分为三类:
今天我们先攻克最常用的两个创建型模式。
场景:
__new____new__是 Python 中真正负责创建对象的方法(比__init__更早执行)。
classSingleton:_instance=None# 用于存储唯一实例def__new__(cls,*args,**kwargs):ifnotcls._instance:print("创建新的实例...")# 调用父类的 __new__ 创建实例cls._instance=super().__new__(cls)returncls._instancedef__init__(self,name):self.name=name# 测试s1=Singleton("配置A")s2=Singleton("配置B")print(s1iss2)# True (它们是同一个对象)print(s1.name)# 配置B (s2 初始化时覆盖了 s1 的属性)print(s2.name)# 配置B写一个装饰器,把类包起来,让它变成单例。
defsingleton(cls):instances={}defwrapper(*args,**kwargs):ifclsnotininstances:instances[cls]=cls(*args,**kwargs)returninstances[cls]returnwrapper@singletonclassDatabase:def__init__(self):print("连接数据库...")db1=Database()db2=Database()# 不会再次打印 "连接数据库..."print(db1isdb2)# True其实,Python 的模块本身就是单例。
因为 Python 导入模块时会缓存,第二次导入直接从缓存拿。
# config.pyclassConfig:passsettings=Config()# main.py# from config import settings# 无论在哪里导入 settings,它都是同一个对象。场景:
一个工厂类,根据参数决定生产什么产品。
classDog:defspeak(self):return"汪汪"classCat:defspeak(self):return"喵喵"classAnimalFactory:@staticmethoddefcreate_animal(animal_type):ifanimal_type=="dog":returnDog()elifanimal_type=="cat":returnCat()else:raiseValueError("未知动物类型")# 使用pet1=AnimalFactory.create_animal("dog")print(pet1.speak())缺点:如果新增一种动物(如 Pig),必须修改create_animal的源代码(违反开闭原则)。
定义一个创建对象的接口,让子类决定实例化哪一个类。
# 抽象工厂基类classFactory:defcreate(self):raiseNotImplementedError# 具体工厂classDogFactory(Factory):defcreate(self):returnDog()classCatFactory(Factory):defcreate(self):returnCat()# 使用dog_factory=DogFactory()pet=dog_factory.create()print(pet.speak())利用 Python 的字典,我们可以实现一个无需修改代码就能扩展的工厂。
classPaymentFactory:_creators={}@classmethoddefregister(cls,type_name,creator_cls):cls._creators[type_name]=creator_cls@classmethoddefget_payment(cls,type_name):creator=cls._creators.get(type_name)ifnotcreator:raiseValueError(f"不支持的支付方式:{type_name}")returncreator()classAliPay:defpay(self):print("支付宝支付")classWeChatPay:defpay(self):print("微信支付")# 注册PaymentFactory.register("alipay",AliPay)PaymentFactory.register("wechat",WeChatPay)# 使用p=PaymentFactory.get_payment("alipay")p.pay()结合单例和工厂模式,设计一个日志系统。
LoggerManager是单例。get_logger(type)方法,根据类型返回FileLogger或ConsoleLogger。classConsoleLogger:deflog(self,msg):print(f"[Console]{msg}")classFileLogger:deflog(self,msg):print(f"[File] 写入:{msg}")# 单例装饰器defsingleton(cls):instances={}defwrapper(*args,**kwargs):ifclsnotininstances:instances[cls]=cls(*args,**kwargs)returninstances[cls]returnwrapper@singletonclassLoggerManager:defget_logger(self,log_type):iflog_type=="file":returnFileLogger()else:returnConsoleLogger()# 测试m1=LoggerManager()m2=LoggerManager()print(f"管理器单例检查:{m1ism2}")# Truelog=m1.get_logger("file")log.log("系统启动")关键要点:
ConnectionPool类,使用单例模式,保证全局只有一个池子。池子里最多有 5 个连接。JsonParser,XmlParser…)。Day 68:设计模式 (Design Patterns) 下篇 - 观察者与策略- 如果说创建型模式是造房子,那行为型模式就是房子里的电路系统。明天我们学习如何让对象之间优雅地通信。
系列导航: