# # 优化前简单工厂模式 - 原始实现 # # 1. 产品父类 # 缺陷没有使用抽象类任何人都可以直接实例化 Phone() # 子类忘记实现 call() 也不会报错要等运行时调用时才发现 class Phone: def call(self): raise NotImplementedError(子类必须实现call方法) # 2. 具体产品 class HuaweiPhone(Phone): def call(self): print(华为手机鸿蒙系统通话) class IPhone(Phone): def call(self): print(苹果手机iOS系统通话) # 3. 简单工厂唯一工厂类 # 缺陷brand 参数是 str 类型传入任意字符串编译都不报错 # 新增品牌必须修改 create_phone 方法加 elif 分支 class PhoneSimpleFactory: staticmethod def create_phone(brand: str) - Phone: 静态工厂方法根据品牌返回对应手机实例 if brand huawei: return HuaweiPhone() elif brand iphone: return IPhone() else: raise ValueError(不支持的手机品牌) # 客户端调用 if __name__ __main__: # ✅ 正常调用 phone1 PhoneSimpleFactory.create_phone(huawei) phone1.call() phone2 PhoneSimpleFactory.create_phone(iphone) phone2.call() # ❌ 以下调用都能编译通过但运行时才会报错 # phone3 PhoneSimpleFactory.create_phone(huawaei) # 拼写错误 # phone4 PhoneSimpleFactory.create_phone(Huawei) # 大小写错误 # ❌ 父类可以直接实例化没有报错 # base Phone() # 能运行但调 base.call() 就炸优化后# # 优化后简单工厂模式 - 改进实现 # from abc import ABC, abstractmethod # 引入抽象基类模块 from enum import Enum # 引入枚举模块 # # 【优化2】用枚举替代字符串保证类型安全 # # 好处所有合法品牌被限定在这一个地方 # IDE 能自动补全拼写错误编辑时就报红线 class PhoneBrand(Enum): HUAWEI huawei IPHONE iphone # # 【优化3】改为严格抽象类禁止直接实例化 # # 好处Phone() 直接报 TypeError不可能产生半成品对象 # 子类漏写 call() 也会在实例化时被拦截 class Phone(ABC): abstractmethod def call(self): 抽象方法子类必须实现否则不能实例化 pass # 2. 具体产品不变 class HuaweiPhone(Phone): def call(self): print(华为手机鸿蒙系统通话) class IPhone(Phone): def call(self): print(苹果手机iOS系统通话) # # 【优化1】用注册表替代 if-elif遵循开闭原则 # # 好处新增品牌只需加枚举值 加映射create_phone 方法本身不需要改动 class PhoneSimpleFactory: # 注册表枚举值 - 产品类 的映射关系 _registry { PhoneBrand.HUAWEI: HuaweiPhone, PhoneBrand.IPHONE: IPhone, } classmethod def create_phone(cls, brand: PhoneBrand) - Phone: 类方法根据枚举值从注册表查找对应产品类并实例化 参数 brand: PhoneBrand 枚举类型不再是 str 返回 Phone 子类的实例 异常 ValueError: 传入了未注册的品牌枚举值 # 从字典中查找替代原来的 if-elif 链 phone_class cls._registry.get(brand) if phone_class is None: raise ValueError(f不支持的手机品牌: {brand}) return phone_class() # 客户端调用 if __name__ __main__: # ✅ 正常调用传入的是枚举不是字符串 phone1 PhoneSimpleFactory.create_phone(PhoneBrand.HUAWEI) phone1.call() phone2 PhoneSimpleFactory.create_phone(PhoneBrand.IPHONE) phone2.call() # ❌ 编辑时就报错枚举没有 HUAEWI 这个值 # phone3 PhoneSimpleFactory.create_phone(PhoneBrand.HUAEWI) # ❌ 编辑时就报错参数类型不匹配不能传 str # phone4 PhoneSimpleFactory.create_phone(huawei) # ❌ 实例化就报错Phone 是抽象类不能直接创建 # base Phone()