当前位置: 首页 > news >正文

设计模式工厂模式和单例模式结合

1 工厂模式:
class CarFactory:
    def createCar(self, brand):
        if brand == "奔驰":
            return Benz()
        elif brand == "宝马":
            return BMW()
        elif brand == '比亚迪':
            return BYD()
        else:
            return "未知品牌,无法创建"
class Benz:
    pass
class BMW:
    pass
class BYD:
    pass
factory = CarFactory()
c1 = factory.createCar("奔驰")
c2 = factory.createCar("宝马")
print(c1)
print(c2)
2 单例模式:
class MySingleton:
    __obj = None
    __init_flag = True
    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls)
        return cls.__obj
    def __init__(self, name):
        if MySingleton.__init_flag:
            print("init....")
        self.name = name
        MySingleton.__init_flag = False
a = MySingleton("aa")
print(a)
b = MySingleton("bb")
print(b)
代码分析:
这段代码实现了一个单例模式,确保 `MySingleton` 类只有一个实例。让我们逐步分析这段代码的行为。
### **1. 类定义**
```python
class MySingleton:
    __obj = None
    __init_flag = True
    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls)
        return cls.__obj
    def __init__(self, name):
        if MySingleton.__init_flag:
            print("init....")
        self.name = name
        MySingleton.__init_flag = False
```
#### **`__obj` 和 `__init_flag` 类属性**
- `__obj`:用于存储单例实例。初始值为 `None`,表示尚未创建实例。
- `__init_flag`:用于确保 `__init__` 方法只在第一次创建实例时调用。初始值为 `True`。
#### **`__new__` 方法**
- `__new__` 是一个静态方法,负责创建类的新实例。
- 如果 `__obj` 是 `None`,表示尚未创建实例,调用 `object.__new__(cls)` 创建一个新的实例,并存储在 `__obj` 中。
- 返回 `__obj`,即单例实例。
#### **`__init__` 方法**
- `__init__` 是一个实例方法,用于初始化实例的属性。
- 通过 `__init_flag` 确保 `__init__` 方法只在第一次创建实例时调用。
- 设置实例的 `name` 属性,并将 `__init_flag` 设置为 `False`,防止后续调用 `__init__` 方法。
### **2. 创建实例**
```python
a = MySingleton("aa")
print(a)
b = MySingleton("bb")
print(b)
```
#### **创建 `a`**
1. 调用 `MySingleton("aa")`,实际上是调用 `__new__` 方法。
2. `__new__` 方法检查 `__obj` 是否为 `None`,发现是 `None`,因此创建一个新的实例并存储在 `__obj` 中。
3. 返回新创建的实例,赋值给 `a`。
4. 调用 `__init__` 方法,`__init_flag` 为 `True`,因此打印 `"init...."`,设置 `name` 属性为 `"aa"`,并将 `__init_flag` 设置为 `False`。
#### **创建 `b`**
1. 调用 `MySingleton("bb")`,实际上是调用 `__new__` 方法。
2. `__new__` 方法检查 `__obj` 是否为 `None`,发现不是 `None`,因此直接返回已有的实例。
3. 返回的实例赋值给 `b`。
4. 调用 `__init__` 方法,但 `__init_flag` 为 `False`,因此不会打印 `"init...."`,也不会设置 `name` 属性为 `"bb"`。
### **3. 输出结果**
```python
init....
<__main__.MySingleton object at 0x...>
<__main__.MySingleton object at 0x...>
```
- `a` 和 `b` 指向同一个实例,因此它们的内存地址相同。
- 只有在第一次创建实例时,`__init__` 方法会被调用并打印 `"init...."`。
### **4. 总结**
- **单例模式**:确保 `MySingleton` 类只有一个实例。
- **`__new__` 方法**:负责创建类的新实例,确保每次调用都返回同一个实例。
- **`__init__` 方法**:通过 `__init_flag` 确保只在第一次创建实例时调用,防止多次初始化。

 
工厂模式和单例模式结合:
class CarFactory:
    __obj = None #类属性
    __init_flag = True
    def create_car(self,brand):
        if brand =="奔驰":
            return Benz()
        elif brand =="宝马":
            return BMW()
        elif brand == "比亚迪":
            return BYD()
        else:
            return "未知品牌,无法创建"
    def __new__(cls, *args, **kwargs):
        if cls.__obj ==None:
            cls.__obj = object.__new__(cls)
        return cls.__obj
    def __init__(self):
        if CarFactory.__init_flag:
            print("init CarFactory....")
            CarFactory.__init_flag = False
class Benz:
    pass
class BMW:
    pass
class BYD:
    pass
factory = CarFactory()
c1 = factory.create_car("奔驰")
c2 = factory.create_car("比亚迪")
print(c1)
print(c2)
factory2 = CarFactory()
print(factory)
print(factory2)
print(factory==factory2)
代码分析:这段代码实现了一个单例模式的工厂类 `CarFactory`,用于创建不同品牌的汽车实例。同时,`CarFactory` 类确保在整个程序中只有一个实例。让我们逐步分析这段代码的行为。
### **1. 类定义**
```python
class CarFactory:
    __obj = None  # 类属性
    __init_flag = True
    def create_car(self, brand):
        if brand == "奔驰":
            return Benz()
        elif brand == "宝马":
            return BMW()
        elif brand == "比亚迪":
            return BYD()
        else:
            return "未知品牌,无法创建"
    def __new__(cls, *args, **kwargs):
        if cls.__obj is None:
            cls.__obj = object.__new__(cls)
        return cls.__obj
    def __init__(self):
        if CarFactory.__init_flag:
            print("init CarFactory....")
            CarFactory.__init_flag = False
```
#### **`__obj` 和 `__init_flag` 类属性**
- `__obj`:用于存储单例实例。初始值为 `None`,表示尚未创建实例。
- `__init_flag`:用于确保 `__init__` 方法只在第一次创建实例时调用。初始值为 `True`。
#### **`create_car` 方法**
- `create_car` 方法根据传入的 `brand` 参数创建不同品牌的汽车实例。
- 支持的品牌包括 "奔驰"、"宝马" 和 "比亚迪"。
- 如果传入的 `brand` 不在支持的范围内,返回字符串 `"未知品牌,无法创建"`。
#### **`__new__` 方法**
- `__new__` 是一个静态方法,负责创建类的新实例。
- 如果 `__obj` 是 `None`,表示尚未创建实例,调用 `object.__new__(cls)` 创建一个新的实例,并存储在 `__obj` 中。
- 返回 `__obj`,即单例实例。
#### **`__init__` 方法**
- `__init__` 是一个实例方法,用于初始化实例的属性。
- 通过 `__init_flag` 确保 `__init__` 方法只在第一次创建实例时调用。
- 设置 `__init_flag` 为 `False`,防止后续调用 `__init__` 方法。
### **2. 定义汽车品牌类**
```python
class Benz:
    pass
class BMW:
    pass
class BYD:
    pass
```
- 这些类是简单的汽车品牌类,目前没有实现任何方法或属性。
### **3. 创建实例**
```python
factory = CarFactory()
c1 = factory.create_car("奔驰")
c2 = factory.create_car("比亚迪")
print(c1)
print(c2)
factory2 = CarFactory()
print(factory)
print(factory2)
print(factory == factory2)
```
#### **创建 `factory`**
1. 调用 `CarFactory()`,实际上是调用 `__new__` 方法。
2. `__new__` 方法检查 `__obj` 是否为 `None`,发现是 `None`,因此创建一个新的 `CarFactory` 实例并存储在 `__obj` 中。
3. 返回新创建的实例,赋值给 `factory`。
4. 调用 `__init__` 方法,`__init_flag` 为 `True`,因此打印 `"init CarFactory...."`,并将 `__init_flag` 设置为 `False`。
#### **创建 `c1`**
1. 调用 `factory.create_car("奔驰")`。
2. `create_car` 方法检查 `brand` 参数,发现是 `"奔驰"`,因此创建一个 `Benz` 实例并返回。
3. 返回的实例赋值给 `c1`。
#### **创建 `c2`**
1. 调用 `factory.create_car("比亚迪")`。
2. `create_car` 方法检查 `brand` 参数,发现是 `"比亚迪"`,因此创建一个 `BYD` 实例并返回。
3. 返回的实例赋值给 `c2`。
#### **创建 `factory2`**
1. 调用 `CarFactory()`,实际上是调用 `__new__` 方法。
2. `__new__` 方法检查 `__obj` 是否为 `None`,发现不是 `None`,因此直接返回已有的实例。
3. 返回的实例赋值给 `factory2`。
#### **比较 `factory` 和 `factory2`**
1. `factory == factory2` 检查 `factory` 和 `factory2` 是否指向同一个对象。
2. 由于 `CarFactory` 是单例模式,`factory` 和 `factory2` 指向同一个实例,因此输出 `True`。
### **4. 输出结果**
```python
init CarFactory....
<__main__.Benz object at 0x...>
<__main__.BYD object at 0x...>
<__main__.CarFactory object at 0x...>
<__main__.CarFactory object at 0x...>
True
```
- `factory` 和 `factory2` 指向同一个 `CarFactory` 实例,因此它们的内存地址相同。
- `c1` 是一个 `Benz` 实例,`c2` 是一个 `BYD` 实例。
### **5. 总结**
- **单例模式**:确保 `CarFactory` 类只有一个实例。
- **工厂模式**:通过 `create_car` 方法根据品牌创建不同类型的汽车实例。
- **`__new__` 方法**:负责创建类的新实例,确保每次调用都返回同一个实例。
- **`__init__` 方法**:通过 `__init_flag` 确保只在第一次创建实例时调用,防止多次初始化。

相关文章:

  • QwQ-32B 模型结构
  • 杰理科技JL703N双模蓝牙芯片—云信
  • 在node.js环境中使用web服务器http-server运行html静态文件
  • pytorch 笔记:张量索引的维度扩展规则
  • 【Linux】进程概念和进程状态
  • 单片机写的小液晶屏驱动+汉字滚屏
  • 天梯赛 L2-008 最长对称子串 (天梯赛常用string函数)
  • Stable Diffusion lora训练(一)
  • 为什么要学习人工智能(AI)?—— 未来已来,AI引领时代变革
  • 第二十八篇 数据获取与数据分析:数仓体系下的专业化分工与协同
  • IIC读写EEPROM
  • 基于springboot医疗平台系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 基于物联网的便携式土壤综合参数检测仪设计
  • MySQL外键约束下的索引删除难题:从报错到完美解决的实战指南
  • 医疗数据大集结
  • deepseek本地化部署
  • MySQL主从同步面试核心20问:从原理到实战深度拆解
  • System V共享内存详解:在Linux上实现内存共享的最佳实践
  • Powershell WSL部署ubuntu22.04.5子系统
  • 深入 Linux 声卡驱动开发:核心问题与实战解析
  • 美乌签署协议建立美乌重建投资基金
  • 我国成功发射卫星互联网低轨卫星
  • 光明网评论员:手机“二次放号”,需要重新确认“你是你”
  • 监狱法修订草案提请全国人大常委会会议审议
  • 国家税务总局:“二套转首套”可以享受贷款利息个税专项扣除
  • 春暖花开,为何皮肤却闹起了小情绪?