四种对象型创建模式:抽象工厂、 build模式、原型ProtoType与单例模式

作者:CoderIsArt日期:2025/10/2

1. 抽象工厂模式 (Abstract Factory)

组件框图

1┌─────────────────┐         ┌──────────────────┐
2│   Client        │         │ AbstractFactory  │
3├─────────────────┤         ├──────────────────┤
4│                 │───────>│+createProductA()5│                 │         │+createProductB()6└─────────────────┘         └──────────────────┘
78                     ┌─────────────────┼─────────────────┐
9           ┌──────────┴──────────┐            ┌──────────┴──────────┐
10           │ ConcreteFactory1    │            │ ConcreteFactory2    │
11           ├─────────────────────┤            ├─────────────────────┤
12           │+createProductA()    │            │+createProductA()13           │+createProductB()    │            │+createProductB()14           └─────────────────────┘            └─────────────────────┘
15                     │                                  │
16           ┌─────────┼─────────┐              ┌─────────┼─────────┐
17    ┌──────┴─────┐ ┌─┴──────┐        ┌──────┴─────┐ ┌─┴──────┐
18    │ ProductA1  │ │ProductB1│        │ ProductA2  │ │ProductB2│
19    └────────────┘ └─────────┘        └────────────┘ └─────────┘

详细描述

问题:
需要创建一系列相关或依赖的对象,但不希望指定具体的类。例如,需要创建跨平台的UI组件。

解决方案:
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

效果:

  • 优点:保证产品系列的兼容性,易于交换产品系列
  • 缺点:难以支持新种类的产品

Python实现

1from abc import ABC, abstractmethod
2
3# 抽象产品A
4class Button(ABC):
5    @abstractmethod
6    def render(self):
7        pass
8
9# 抽象产品B
10class Checkbox(ABC):
11    @abstractmethod
12    def paint(self):
13        pass
14
15# 具体产品A1
16class WindowsButton(Button):
17    def render(self):
18        return "渲染Windows风格按钮"
19
20# 具体产品B1
21class WindowsCheckbox(Checkbox):
22    def paint(self):
23        return "绘制Windows风格复选框"
24
25# 具体产品A2
26class MacButton(Button):
27    def render(self):
28        return "渲染macOS风格按钮"
29
30# 具体产品B2
31class MacCheckbox(Checkbox):
32    def paint(self):
33        return "绘制macOS风格复选框"
34
35# 抽象工厂
36class GUIFactory(ABC):
37    @abstractmethod
38    def create_button(self) -> Button:
39        pass
40    
41    @abstractmethod
42    def create_checkbox(self) -> Checkbox:
43        pass
44
45# 具体工厂1
46class WindowsFactory(GUIFactory):
47    def create_button(self) -> Button:
48        return WindowsButton()
49    
50    def create_checkbox(self) -> Checkbox:
51        return WindowsCheckbox()
52
53# 具体工厂2
54class MacFactory(GUIFactory):
55    def create_button(self) -> Button:
56        return MacButton()
57    
58    def create_checkbox(self) -> Checkbox:
59        return MacCheckbox()
60
61# 客户端代码
62class Application:
63    def __init__(self, factory: GUIFactory):
64        self.factory = factory
65        self.button = None
66        self.checkbox = None
67    
68    def create_ui(self):
69        self.button = self.factory.create_button()
70        self.checkbox = self.factory.create_checkbox()
71    
72    def paint(self):
73        print(self.button.render())
74        print(self.checkbox.paint())
75
76# 使用
77if __name__ == "__main__":
78    print("=== Windows UI ===")
79    windows_factory = WindowsFactory()
80    app1 = Application(windows_factory)
81    app1.create_ui()
82    app1.paint()
83    
84    print("\n=== macOS UI ===")
85    mac_factory = MacFactory()
86    app2 = Application(mac_factory)
87    app2.create_ui()
88    app2.paint()

C++实现

1#include <iostream>
2#include <memory>
3#include <string>
4
5// 抽象产品A
6class Button {
7public:
8    virtual ~Button() = default;
9    virtual std::string render() = 0;
10};
11
12// 抽象产品B
13class Checkbox {
14public:
15    virtual ~Checkbox() = default;
16    virtual std::string paint() = 0;
17};
18
19// 具体产品A1
20class WindowsButton : public Button {
21public:
22    std::string render() override {
23        return "渲染Windows风格按钮";
24    }
25};
26
27// 具体产品B1
28class WindowsCheckbox : public Checkbox {
29public:
30    std::string paint() override {
31        return "绘制Windows风格复选框";
32    }
33};
34
35// 具体产品A2
36class MacButton : public Button {
37public:
38    std::string render() override {
39        return "渲染macOS风格按钮";
40    }
41};
42
43// 具体产品B2
44class MacCheckbox : public Checkbox {
45public:
46    std::string paint() override {
47        return "绘制macOS风格复选框";
48    }
49};
50
51// 抽象工厂
52class GUIFactory {
53public:
54    virtual ~GUIFactory() = default;
55    virtual std::unique_ptr<Button> createButton() = 0;
56    virtual std::unique_ptr<Checkbox> createCheckbox() = 0;
57};
58
59// 具体工厂1
60class WindowsFactory : public GUIFactory {
61public:
62    std::unique_ptr<Button> createButton() override {
63        return std::make_unique<WindowsButton>();
64    }
65    
66    std::unique_ptr<Checkbox> createCheckbox() override {
67        return std::make_unique<WindowsCheckbox>();
68    }
69};
70
71// 具体工厂2
72class MacFactory : public GUIFactory {
73public:
74    std::unique_ptr<Button> createButton() override {
75        return std::make_unique<MacButton>();
76    }
77    
78    std::unique_ptr<Checkbox> createCheckbox() override {
79        return std::make_unique<MacCheckbox>();
80    }
81};
82
83// 客户端代码
84class Application {
85private:
86    std::unique_ptr<GUIFactory> factory;
87    std::unique_ptr<Button> button;
88    std::unique_ptr<Checkbox> checkbox;
89    
90public:
91    Application(std::unique_ptr<GUIFactory> factory) 
92        : factory(std::move(factory)) {}
93    
94    void createUI() {
95        button = this->factory->createButton();
96        checkbox = this->factory->createCheckbox();
97    }
98    
99    void paint() {
100        std::cout << button->render() << std::endl;
101        std::cout << checkbox->paint() << std::endl;
102    }
103};
104
105// 使用
106int main() {
107    std::cout << "=== Windows UI ===" << std::endl;
108    auto windowsFactory = std::make_unique<WindowsFactory>();
109    Application app1(std::move(windowsFactory));
110    app1.createUI();
111    app1.paint();
112    
113    std::cout << "\n=== macOS UI ===" << std::endl;
114    auto macFactory = std::make_unique<MacFactory>();
115    Application app2(std::move(macFactory));
116    app2.createUI();
117    app2.paint();
118    
119    return 0;
120}

2. 建造者模式 (Builder)

组件框图

1┌─────────────────┐         ┌──────────────────┐
2│   Director      │         │    Builder       │
3├─────────────────┤         ├──────────────────┤
4│+construct()     │───────>│+buildPartA()5│                 │         │+buildPartB()6│                 │         │+getResult()7└─────────────────┘         └──────────────────┘
89                     ┌─────────────────┼─────────────────┐
10           ┌──────────┴──────────┐            ┌──────────┴──────────┐
11           │ ConcreteBuilder1    │            │ ConcreteBuilder2    │
12           ├─────────────────────┤            ├─────────────────────┤
13           │+buildPartA()        │            │+buildPartA()14           │+buildPartB()        │            │+buildPartB()15           │+getResult()         │            │+getResult()16           └─────────────────────┘            └─────────────────────┘
17                     │                                  │
18           ┌─────────┴─────────┐              ┌─────────┴─────────┐
19           │     Product1      │              │     Product2      │
20           └───────────────────┘              └───────────────────┘

详细描述

问题:
创建复杂对象时,构造过程复杂且可能有多个步骤,或者需要创建不同表示的对象。

解决方案:
将复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

效果:

  • 优点:封装了复杂对象的创建过程,可以精细控制构建过程
  • 缺点:增加了系统复杂度,需要多个具体建造者类

Python实现

1from abc import ABC, abstractmethod
2from typing import List
3
4# 产品类
5class Computer:
6    def __init__(self):
7        self.parts: List[str] = []
8    
9    def add(self, part: str):
10        self.parts.append(part)
11    
12    def list_parts(self):
13        return f"计算机配置: {', '.join(self.parts)}"
14    
15    def __str__(self):
16        return self.list_parts()
17
18# 抽象建造者
19class ComputerBuilder(ABC):
20    def __init__(self):
21        self.computer = Computer()
22    
23    @abstractmethod
24    def build_cpu(self):
25        pass
26    
27    @abstractmethod
28    def build_memory(self):
29        pass
30    
31    @abstractmethod
32    def build_storage(self):
33        pass
34    
35    @abstractmethod
36    def build_graphics_card(self):
37        pass
38    
39    def get_computer(self) -> Computer:
40        computer = self.computer
41        self.computer = Computer()  # 重置用于下次构建
42        return computer
43
44# 具体建造者 - 游戏电脑
45class GamingComputerBuilder(ComputerBuilder):
46    def build_cpu(self):
47        self.computer.add("Intel i9-13900K CPU")
48    
49    def build_memory(self):
50        self.computer.add("32GB DDR5 RAM")
51    
52    def build_storage(self):
53        self.computer.add("2TB NVMe SSD")
54    
55    def build_graphics_card(self):
56        self.computer.add("NVIDIA RTX 4090")
57
58# 具体建造者 - 办公电脑
59class OfficeComputerBuilder(ComputerBuilder):
60    def build_cpu(self):
61        self.computer.add("Intel i5-12400 CPU")
62    
63    def build_memory(self):
64        self.computer.add("16GB DDR4 RAM")
65    
66    def build_storage(self):
67        self.computer.add("512GB SSD + 1TB HDD")
68    
69    def build_graphics_card(self):
70        self.computer.add("Integrated Graphics")
71
72# 导演类
73class ComputerEngineer:
74    def __init__(self):
75        self.builder: ComputerBuilder = None
76    
77    def set_builder(self, builder: ComputerBuilder):
78        self.builder = builder
79    
80    def build_computer(self):
81        self.builder.build_cpu()
82        self.builder.build_memory()
83        self.builder.build_storage()
84        self.builder.build_graphics_card()
85        return self.builder.get_computer()
86    
87    def build_minimal_computer(self):
88        """构建简化版电脑"""
89        self.builder.build_cpu()
90        self.builder.build_memory()
91        return self.builder.get_computer()
92
93# 使用
94if __name__ == "__main__":
95    engineer = ComputerEngineer()
96    
97    # 构建游戏电脑
98    gaming_builder = GamingComputerBuilder()
99    engineer.set_builder(gaming_builder)
100    gaming_computer = engineer.build_computer()
101    print("=== 游戏电脑 ===")
102    print(gaming_computer)
103    
104    # 构建办公电脑
105    office_builder = OfficeComputerBuilder()
106    engineer.set_builder(office_builder)
107    office_computer = engineer.build_computer()
108    print("\n=== 办公电脑 ===")
109    print(office_computer)
110    
111    # 构建简化版办公电脑
112    minimal_office_computer = engineer.build_minimal_computer()
113    print("\n=== 简化版办公电脑 ===")
114    print(minimal_office_computer)

C++实现

1#include <iostream>
2#include <memory>
3#include <vector>
4#include <string>
5
6// 产品类
7class Computer {
8private:
9    std::vector<std::string> parts;
10    
11public:
12    void addPart(const std::string& part) {
13        parts.push_back(part);
14    }
15    
16    void listParts() const {
17        std::cout << "计算机配置: ";
18        for (size_t i = 0; i < parts.size(); ++i) {
19            std::cout << parts[i];
20            if (i != parts.size() - 1) {
21                std::cout << ", ";
22            }
23        }
24        std::cout << std::endl;
25    }
26};
27
28// 抽象建造者
29class ComputerBuilder {
30protected:
31    std::unique_ptr<Computer> computer;
32    
33public:
34    ComputerBuilder() : computer(std::make_unique<Computer>()) {}
35    virtual ~ComputerBuilder() = default;
36    
37    virtual void buildCPU() = 0;
38    virtual void buildMemory() = 0;
39    virtual void buildStorage() = 0;
40    virtual void buildGraphicsCard() = 0;
41    
42    std::unique_ptr<Computer> getComputer() {
43        auto result = std::move(computer);
44        computer = std::make_unique<Computer>();  // 重置用于下次构建
45        return result;
46    }
47};
48
49// 具体建造者 - 游戏电脑
50class GamingComputerBuilder : public ComputerBuilder {
51public:
52    void buildCPU() override {
53        computer->addPart("Intel i9-13900K CPU");
54    }
55    
56    void buildMemory() override {
57        computer->addPart("32GB DDR5 RAM");
58    }
59    
60    void buildStorage() override {
61        computer->addPart("2TB NVMe SSD");
62    }
63    
64    void buildGraphicsCard() override {
65        computer->addPart("NVIDIA RTX 4090");
66    }
67};
68
69// 具体建造者 - 办公电脑
70class OfficeComputerBuilder : public ComputerBuilder {
71public:
72    void buildCPU() override {
73        computer->addPart("Intel i5-12400 CPU");
74    }
75    
76    void buildMemory() override {
77        computer->addPart("16GB DDR4 RAM");
78    }
79    
80    void buildStorage() override {
81        computer->addPart("512GB SSD + 1TB HDD");
82    }
83    
84    void buildGraphicsCard() override {
85        computer->addPart("Integrated Graphics");
86    }
87};
88
89// 导演类
90class ComputerEngineer {
91private:
92    ComputerBuilder* builder;
93    
94public:
95    void setBuilder(ComputerBuilder* newBuilder) {
96        builder = newBuilder;
97    }
98    
99    std::unique_ptr<Computer> buildComputer() {
100        builder->buildCPU();
101        builder->buildMemory();
102        builder->buildStorage();
103        builder->buildGraphicsCard();
104        return builder->getComputer();
105    }
106    
107    std::unique_ptr<Computer> buildMinimalComputer() {
108        builder->buildCPU();
109        builder->buildMemory();
110        return builder->getComputer();
111    }
112};
113
114// 使用
115int main() {
116    ComputerEngineer engineer;
117    
118    // 构建游戏电脑
119    GamingComputerBuilder gamingBuilder;
120    engineer.setBuilder(&gamingBuilder);
121    auto gamingComputer = engineer.buildComputer();
122    std::cout << "=== 游戏电脑 ===" << std::endl;
123    gamingComputer->listParts();
124    
125    // 构建办公电脑
126    OfficeComputerBuilder officeBuilder;
127    engineer.setBuilder(&officeBuilder);
128    auto officeComputer = engineer.buildComputer();
129    std::cout << "\n=== 办公电脑 ===" << std::endl;
130    officeComputer->listParts();
131    
132    // 构建简化版办公电脑
133    auto minimalOfficeComputer = engineer.buildMinimalComputer();
134    std::cout << "\n=== 简化版办公电脑 ===" << std::endl;
135    minimalOfficeComputer->listParts();
136    
137    return 0;
138}

3. 原型模式 (Prototype)

组件框图

1┌─────────────────┐         ┌──────────────────┐
2│   Client        │         │   Prototype      │
3├─────────────────┤         ├──────────────────┤
4│                 │───────>│+clone()5│                 │         └──────────────────┘
6└─────────────────┘                   △
7                             ┌─────────┴─────────┐
8                   ┌──────────┴──────────┐ ┌─────┴────────┐
9                   │ ConcretePrototype1  │ │ConcretePrototype2│
10                   ├─────────────────────┤ ├────────────────┤
11                   │+clone()             │ │+clone()12                   │-field               │ │-field          │
13                   └─────────────────────┘ └────────────────┘

详细描述

问题:
需要创建的对象成本较高(如数据库操作、网络请求),或者希望避免使用子类来扩展对象创建。

解决方案:
通过复制现有对象来创建新对象,而不是通过新建类实例。

效果:

  • 优点:避免重复初始化操作,动态添加或删除产品
  • 缺点:复杂对象的克隆可能较困难,需要深拷贝考虑

Python实现

1import copy
2from abc import ABC, abstractmethod
3from typing import List, Dict
4
5# 原型接口
6class Prototype(ABC):
7    @abstractmethod
8    def clone(self):
9        pass
10
11# 具体原型 - 简历
12class Resume(Prototype):
13    def __init__(self, name: str = ""):
14        self.name = name
15        self.work_experience: List[str] = []
16        self.skills: List[str] = []
17        self.personal_info: Dict[str, str] = {}
18    
19    def set_personal_info(self, key: str, value: str):
20        self.personal_info[key] = value
21    
22    def add_work_experience(self, experience: str):
23        self.work_experience.append(experience)
24    
25    def add_skill(self, skill: str):
26        self.skills.append(skill)
27    
28    def clone(self):
29        """深拷贝克隆方法"""
30        return copy.deepcopy(self)
31    
32    def shallow_clone(self):
33        """浅拷贝克隆方法"""
34        return copy.copy(self)
35    
36    def display(self):
37        print(f"\n=== 简历: {self.name} ===")
38        print("个人信息:")
39        for key, value in self.personal_info.items():
40            print(f"  {key}: {value}")
41        
42        print("工作经历:")
43        for exp in self.work_experience:
44            print(f"  - {exp}")
45        
46        print("技能:")
47        for skill in self.skills:
48            print(f"  - {skill}")
49
50# 具体原型 - 图形对象
51class GraphicObject(Prototype):
52    def __init__(self, color: str = "black", x: int = 0, y: int = 0):
53        self.color = color
54        self.x = x
55        self.y = y
56        self.children: List[GraphicObject] = []
57    
58    def add_child(self, child: 'GraphicObject'):
59        self.children.append(child)
60    
61    def clone(self):
62        """深拷贝克隆,包括所有子对象"""
63        return copy.deepcopy(self)
64    
65    def __str__(self):
66        return f"GraphicObject(color={self.color}, position=({self.x},{self.y}), children={len(self.children)})"
67
68# 原型管理器
69class PrototypeManager:
70    def __init__(self):
71        self._prototypes: Dict[str, Prototype] = {}
72    
73    def register_prototype(self, name: str, prototype: Prototype):
74        self._prototypes[name] = prototype
75    
76    def unregister_prototype(self, name: str):
77        if name in self._prototypes:
78            del self._prototypes[name]
79    
80    def clone_prototype(self, name: str) -> Prototype:
81        if name in self._prototypes:
82            return self._prototypes[name].clone()
83        raise ValueError(f"原型 '{name}' 未注册")
84
85# 使用
86if __name__ == "__main__":
87    # 创建原型简历
88    original_resume = Resume("张三")
89    original_resume.set_personal_info("age", "28")
90    original_resume.set_personal_info("email", "[email protected]")
91    original_resume.add_work_experience("ABC公司 - 软件工程师 (2020-2023)")
92    original_resume.add_skill("Python")
93    original_resume.add_skill("C++")
94    
95    print("=== 原始简历 ===")
96    original_resume.display()
97    
98    # 克隆简历并修改
99    cloned_resume = original_resume.clone()
100    cloned_resume.name = "李四"
101    cloned_resume.set_personal_info("email", "[email protected]")
102    cloned_resume.add_work_experience("XYZ公司 - 高级工程师 (2023-至今)")
103    cloned_resume.add_skill("Java")
104    
105    print("\n=== 克隆并修改后的简历 ===")
106    cloned_resume.display()
107    
108    # 原型管理器使用
109    print("\n=== 原型管理器示例 ===")
110    manager = PrototypeManager()
111    manager.register_prototype("standard_resume", original_resume)
112    
113    # 快速创建多个相似简历
114    resume1 = manager.clone_prototype("standard_resume")
115    resume1.name = "王五"
116    resume1.display()
117    
118    # 图形对象克隆
119    print("\n=== 图形对象克隆 ===")
120    original_graphic = GraphicObject("red", 10, 20)
121    child1 = GraphicObject("blue", 5, 5)
122    child2 = GraphicObject("green", 15, 15)
123    original_graphic.add_child(child1)
124    original_graphic.add_child(child2)
125    
126    cloned_graphic = original_graphic.clone()
127    cloned_graphic.color = "yellow"
128    cloned_graphic.x = 30
129    
130    print(f"原始对象: {original_graphic}")
131    print(f"克隆对象: {cloned_graphic}")

C++实现

1#include <iostream>
2#include <memory>
3#include <vector>
4#include <string>
5#include <unordered_map>
6
7// 原型接口
8class Prototype {
9public:
10    virtual ~Prototype() = default;
11    virtual std::unique_ptr<Prototype> clone() const = 0;
12    virtual void display() const = 0;
13};
14
15// 具体原型 - 简历
16class Resume : public Prototype {
17private:
18    std::string name;
19    std::vector<std::string> workExperience;
20    std::vector<std::string> skills;
21    std::unordered_map<std::string, std::string> personalInfo;
22    
23public:
24    Resume(const std::string& name = "") : name(name) {}
25    
26    void setPersonalInfo(const std::string& key, const std::string& value) {
27        personalInfo[key] = value;
28    }
29    
30    void addWorkExperience(const std::string& experience) {
31        workExperience.push_back(experience);
32    }
33    
34    void addSkill(const std::string& skill) {
35        skills.push_back(skill);
36    }
37    
38    std::unique_ptr<Prototype> clone() const override {
39        return std::make_unique<Resume>(*this);  // 使用拷贝构造函数
40    }
41    
42    void display() const override {
43        std::cout << "\n=== 简历: " << name << " ===" << std::endl;
44        std::cout << "个人信息:" << std::endl;
45        for (const auto& [key, value] : personalInfo) {
46            std::cout << "  " << key << ": " << value << std::endl;
47        }
48        
49        std::cout << "工作经历:" << std::endl;
50        for (const auto& exp : workExperience) {
51            std::cout << "  - " << exp << std::endl;
52        }
53        
54        std::cout << "技能:" << std::endl;
55        for (const auto& skill : skills) {
56            std::cout << "  - " << skill << std::endl;
57        }
58    }
59    
60    // 拷贝构造函数
61    Resume(const Resume& other)
62        : name(other.name),
63          workExperience(other.workExperience),
64          skills(other.skills),
65          personalInfo(other.personalInfo) {}
66};
67
68// 原型管理器
69class PrototypeManager {
70private:
71    std::unordered_map<std::string, std::unique_ptr<Prototype>> prototypes;
72    
73public:
74    void registerPrototype(const std::string& name, std::unique_ptr<Prototype> prototype) {
75        prototypes[name] = std::move(prototype);
76    }
77    
78    void unregisterPrototype(const std::string& name) {
79        prototypes.erase(name);
80    }
81    
82    std::unique_ptr<Prototype> clonePrototype(const std::string& name) {
83        auto it = prototypes.find(name);
84        if (it != prototypes.end()) {
85            return it->second->clone();
86        }
87        throw std::runtime_error("原型 '" + name + "' 未注册");
88    }
89};
90
91// 使用
92int main() {
93    // 创建原型简历
94    auto originalResume = std::make_unique<Resume>("张三");
95    originalResume->setPersonalInfo("age", "28");
96    originalResume->setPersonalInfo("email", "[email protected]");
97    originalResume->addWorkExperience("ABC公司 - 软件工程师 (2020-2023)");
98    originalResume->addSkill("Python");
99    originalResume->addSkill("C++");
100    
101    std::cout << "=== 原始简历 ===" << std::endl;
102    originalResume->display();
103    
104    // 克隆简历
105    auto clonedResume = originalResume->clone();
106    auto* resumePtr = dynamic_cast<Resume*>(clonedResume.get());
107    if (resumePtr) {
108        // 注意:这里需要修改接口以支持修改,为了示例简化
109        std::cout << "\n=== 克隆的简历 ===" << std::endl;
110        resumePtr->display();
111    }
112    
113    // 原型管理器使用
114    std::cout << "\n=== 原型管理器示例 ===" << std::endl;
115    PrototypeManager manager;
116    manager.registerPrototype("standard_resume", std::move(originalResume));
117    
118    // 快速创建多个相似简历
119    auto resume1 = manager.clonePrototype("standard_resume");
120    resume1->display();
121    
122    return 0;
123}

4. 单例模式 (Singleton)

组件框图

1┌─────────────────┐
2│   Singleton     │
3├─────────────────┤
4│-instance        │
5│-data            │
6├─────────────────┤
7│-Singleton()8│+getInstance()9│+businessLogic()10└─────────────────┘

详细描述

问题:
确保一个类只有一个实例,并提供一个全局访问点。

解决方案:
将构造函数私有化,提供一个静态方法返回唯一实例。

效果:

  • 优点:严格控制实例数量,全局访问点
  • 缺点:可能隐藏过度耦合,难以测试,违反单一职责原则

Python实现

1import threading
2from typing import Dict, Any
3
4class SingletonMeta(type):
5    """单例元类,线程安全版本"""
6    _instances: Dict[type, Any] = {}
7    _lock: threading.Lock = threading.Lock()
8    
9    def __call__(cls, *args, **kwargs):
10        with cls._lock:
11            if cls not in cls._instances:
12                instance = super().__call__(*args, **kwargs)
13                cls._instances[cls] = instance
14        return cls._instances[cls]
15
16# 数据库连接单例
17class DatabaseConnection(metaclass=SingletonMeta):
18    def __init__(self, connection_string: str = "default_connection"):
19        self.connection_string = connection_string
20        self.is_connected = False
21        self._connection_count = 0
22        print(f"初始化数据库连接: {connection_string}")
23    
24    def connect(self):
25        if not self.is_connected:
26            self.is_connected = True
27            self._connection_count += 1
28            print("数据库连接已建立")
29        else:
30            print("数据库已经连接")
31    
32    def disconnect(self):
33        if self.is_connected:
34            self.is_connected = False
35            print("数据库连接已断开")
36        else:
37            print("数据库已经断开")
38    
39    def execute_query(self, query: str):
40        if self.is_connected:
41            print(f"执行查询: {query}")
42            return f"查询结果: {query}"
43        else:
44            raise Exception("数据库未连接")
45    
46    def get_connection_count(self):
47        return self._connection_count
48
49# 配置管理器单例
50class ConfigurationManager(metaclass=SingletonMeta):
51    def __init__(self):
52        self._config = {
53            "database": {
54                "host": "localhost",
55                "port": 5432,
56                "username": "admin"
57            },
58            "application": {
59                "name": "MyApp",
60                "version": "1.0.0"
61            }
62        }
63        print("配置管理器初始化完成")
64    
65    def get(self, key: str, default=None):
66        """获取配置项"""
67        keys = key.split('.')
68        value = self._config
69        try:
70            for k in keys:
71                value = value[k]
72            return value
73        except (KeyError, TypeError):
74            return default
75    
76    def set(self, key: str, value):
77        """设置配置项"""
78        keys = key.split('.')
79        config = self._config
80        for k in keys[:-1]:
81            if k not in config:
82                config[k] = {}
83            config = config[k]
84        config[keys[-1]] = value
85    
86    def show_config(self):
87        """显示所有配置"""
88        import json
89        print("当前配置:")
90        print(json.dumps(self._config, indent=2, ensure_ascii=False))
91
92# 线程测试
93def test_singleton_thread(thread_id: int):
94    """测试多线程环境下的单例"""
95    db = DatabaseConnection()
96    db.connect()
97    config = ConfigurationManager()
98    app_name = config.get("application.name")
99    print(f"线程 {thread_id} - 应用名称: {app_name}")
100
101# 使用
102if __name__ == "__main__":
103    print("=== 单例模式演示 ===")
104    
105    # 测试数据库连接单例
106    print("\n1. 数据库连接单例测试:")
107    db1 = DatabaseConnection("postgresql://localhost:5432/mydb")
108    db2 = DatabaseConnection("different_connection")  # 这个不会生效
109    
110    db1.connect()
111    db2.connect()  # 实际上是同一个实例
112    
113    print(f"db1 is db2: {db1 is db2}")
114    print(f"连接次数: {db1.get_connection_count()}")
115    
116    # 测试配置管理器单例
117    print("\n2. 配置管理器单例测试:")
118    config1 = ConfigurationManager()
119    config2 = ConfigurationManager()
120    
121    print(f"config1 is config2: {config1 is config2}")
122    
123    # 获取配置
124    db_host = config1.get("database.host")
125    app_version = config1.get("application.version")
126    print(f"数据库主机: {db_host}")
127    print(f"应用版本: {app_version}")
128    
129    # 修改配置
130    config1.set("database.port", 3306)
131    config1.show_config()
132    
133    # 多线程测试
134    print("\n3. 多线程单例测试:")
135    threads = []
136    for i in range(3):
137        thread = threading.Thread(target=test_singleton_thread, args=(i,))
138        threads.append(thread)
139        thread.start()
140    
141    for thread in threads:
142        thread.join()

C++实现

1#include <iostream>
2#include <memory>
3#include <mutex>
4#include <string>
5#include <unordered_map>
6
7// 数据库连接单例
8class DatabaseConnection {
9private:
10    static std::unique_ptr<DatabaseConnection> instance;
11    static std::mutex mutex;
12    
13    std::string connectionString;
14    bool isConnected;
15    int connectionCount;
16    
17    // 私有构造函数
18    DatabaseConnection(const std::string& connStr = "default_connection") 
19        : connectionString(connStr), isConnected(false), connectionCount(0) {
20        std::cout << "初始化数据库连接: " << connectionString << std::endl;
21    }
22    
23public:
24    // 删除拷贝构造函数和赋值操作符
25    DatabaseConnection(const DatabaseConnection&) = delete;
26    DatabaseConnection& operator=(const DatabaseConnection&) = delete;
27    
28    // 获取单例实例
29    static DatabaseConnection& getInstance(const std::string& connStr = "default_connection") {
30        std::lock_guard<std::mutex> lock(mutex);
31        if (!instance) {
32            instance = std::unique_ptr<DatabaseConnection>(new DatabaseConnection(connStr));
33        }
34        return *instance;
35    }
36    
37    void connect() {
38        if (!isConnected) {
39            isConnected = true;
40            connectionCount++;
41            std::cout << "数据库连接已建立" << std::endl;
42        } else {
43            std::cout << "数据库已经连接" << std::endl;
44        }
45    }
46    
47    void disconnect() {
48        if (isConnected) {
49            isConnected = false;
50            std::cout << "数据库连接已断开" << std::endl;
51        } else {
52            std::cout << "数据库已经断开" << std::endl;
53        }
54    }
55    
56    void executeQuery(const std::string& query) {
57        if (isConnected) {
58            std::cout << "执行查询: " << query << std::endl;
59        } else {
60            throw std::runtime_error("数据库未连接");
61        }
62    }
63    
64    int getConnectionCount() const {
65        return connectionCount;
66    }
67    
68    std::string getConnectionString() const {
69        return connectionString;
70    }
71};
72
73// 静态成员初始化
74std::unique_ptr<DatabaseConnection> DatabaseConnection::instance = nullptr;
75std::mutex DatabaseConnection::mutex;
76
77// 配置管理器单例
78class ConfigurationManager {
79private:
80    static ConfigurationManager* instance;
81    static std::mutex mutex;
82    
83    std::unordered_map<std::string, std::string> config;
84    
85    ConfigurationManager() {
86        // 默认配置
87        config["database.host"] = "localhost";
88        config["database.port"] = "5432";
89        config["application.name"] = "MyApp";
90        config["application.version"] = "1.0.0";
91        std::cout << "配置管理器初始化完成" << std::endl;
92    }
93    
94public:
95    ConfigurationManager(const ConfigurationManager&) = delete;
96    ConfigurationManager& operator=(const ConfigurationManager&) = delete;
97    
98    static ConfigurationManager& getInstance() {
99        std::lock_guard<std::mutex> lock(mutex);
100        if (!instance) {
101            instance = new ConfigurationManager();
102        }
103        return *instance;
104    }
105    
106    static void destroyInstance() {
107        std::lock_guard<std::mutex> lock(mutex);
108        delete instance;
109        instance = nullptr;
110    }
111    
112    std::string get(const std::string& key, const std::string& defaultValue = "") {
113        auto it = config.find(key);
114        if (it != config.end()) {
115            return it->second;
116        }
117        return defaultValue;
118    }
119    
120    void set(const std::string& key, const std::string& value) {
121        config[key] = value;
122    }
123    
124    void showConfig() {
125        std::cout << "当前配置:" << std::endl;
126        for (const auto& [key, value] : config) {
127            std::cout << "  " << key << ": " << value << std::endl;
128        }
129    }
130};
131
132// 静态成员初始化
133ConfigurationManager* ConfigurationManager::instance = nullptr;
134std::mutex ConfigurationManager::mutex;
135
136// 使用
137int main() {
138    std::cout << "=== 单例模式演示 ===" << std::endl;
139    
140    // 测试数据库连接单例
141    std::cout << "\n1. 数据库连接单例测试:" << std::endl;
142    DatabaseConnection& db1 = DatabaseConnection::getInstance("postgresql://localhost:5432/mydb");
143    DatabaseConnection& db2 = DatabaseConnection::getInstance("different_connection");
144    
145    db1.connect();
146    db2.connect();  // 实际上是同一个实例
147    
148    std::cout << "db1 和 db2 是同一个实例: " << (&db1 == &db2) << std::endl;
149    std::cout << "连接次数: " << db1.getConnectionCount() << std::endl;
150    std::cout << "连接字符串: " << db1.getConnectionString() << std::endl;
151    
152    // 测试配置管理器单例
153    std::cout << "\n2. 配置管理器单例测试:" << std::endl;
154    ConfigurationManager& config1 = ConfigurationManager::getInstance();
155    ConfigurationManager& config2 = ConfigurationManager::getInstance();
156    
157    std::cout << "config1 和 config2 是同一个实例: " << (&config1 == &config2) << std::endl;
158    
159    // 获取和修改配置
160    std::string dbHost = config1.get("database.host");
161    std::string appVersion = config1.get("application.version");
162    std::cout << "数据库主机: " << dbHost << std::endl;
163    std::cout << "应用版本: " << appVersion << std::endl;
164    
165    config1.set("database.port", "3306");
166    config1.showConfig();
167    
168    // 清理
169    ConfigurationManager::destroyInstance();
170    
171    return 0;
172}

模式对比总结

模式主要目的适用场景关键特性
抽象工厂创建产品族需要系列相关产品工厂接口,产品兼容性
建造者复杂对象构建构建过程复杂,步骤多分步构建,相同过程不同表示
原型对象克隆创建成本高,避免子类克隆方法,深拷贝/浅拷贝
单例唯一实例需要全局访问点,控制实例数量私有构造,静态实例,线程安全

这些创建型模式都解决了对象创建的不同方面问题,在实际开发中可以根据具体需求选择合适的模式。


四种对象型创建模式:抽象工厂、 build模式、原型ProtoType与单例模式》 是转载文章,点击查看原文


相关推荐


垃圾分类魔法互动墙-垃圾分类展厅设备-VR垃圾分类软件
佩京科技VR2025/10/2

想让垃圾分类知识变有趣?来体验环保魔法墙软件。搭配投影融合硬件,普通墙面秒变知识乐园,每幅环保手绘图都藏着分类小秘密。 在这里,你可以用指尖开启奇妙互动:轻轻触摸手绘图上的图标,原本静态的画面瞬间 “动” 起来。 当用户用手掌触摸墙面后,灯带与灯光效果组合会一起显示,讲述了有害垃圾、厨余垃圾、其他垃圾、可回收垃圾四类垃圾回收的过程。用户可以观察垃圾的回收过程,加深对每种类型垃圾分类回收的认知。 人们将日常生活中所产生的有害垃圾投放到属于有害垃圾的垃圾桶内,就会有专门的运输垃圾车将有害垃圾运


分布式专题——21 Kafka客户端消息流转流程
失散1310/2/2025

Kafka 的 Java 客户端、客户端工作机制(消费者分组消费机制、生产者拦截器机制、消息序列化机制、消息分区路由机制、生产者消息缓存机制、发送应答机制、生产者消息幂等性、生产者数据压缩机制、生产者消息事务)、客户端流程总结、SpringBoot集成Kafka


# vim中给变量添加双引号
猪猪侠|ZZXia10/1/2025

摘要:本文介绍在vim中为shell变量添加双引号的三种方法:1) 手动快捷键选中变量后添加引号;2) 使用全局替换命令;3) 自定义快捷键实现快速添加。还提供了.vimrc配置示例,包含单变量、单行变量和全部变量添加双引号的快捷键定义,帮助开发者避免shell语法警告和潜在风险。


删除Notepad++关于弹窗的反动字样
cpych9/30/2025

删除Notepad++关于弹窗的反动字样


复盘:第一个 AI 出海站,我做错了哪些事?
孟健AI编程2025/10/3

大家好,我是孟健。 上周,我把自己的第一个出海站点部署上线。 算是把需求挖掘、开发、部署、获客到变现的闭环跑完了。 真的是:惊喜和意外齐飞,踩坑和成长并存。 这篇文章就把整个过程拆开复盘,希望能给正在筹备 AI 出海的你一些参考。 01 选词太随意,开局就挖了坑 当时我只打开 Google Trends,看着趋势线还不错就直接选词。 上线后数据一出才发现,词的全球热度在持续下滑,而且几乎只有巴西有流量。 美国、英国、加拿大等英语主流市场几乎没人搜,打榜和运营正反馈极低。 站点一上来就被迫做多


人工智能技术的广阔前景
南鸢1.02025/10/4

博主主页:【南鸢1.0】 本文专栏:创作灵感 | 人工智能 文章目录  简介 未来前景与可能性 应对策略与建议 1. 技能提升与再培训 2. 制定与遵循伦理准则 3. 强调人机协作 4. 重视数据安全与隐私 更好的AI工具 1.TensorFlow & PyTorch 2.Tableau 3.ChatGPT和其他对话AI模型 4.Notion AI 总结  简介 人工智能技术的应用前景确实非常广阔,且其在各个领域的潜力和效益也愈加显著。在这一背景下,以下


最新版 Python 的内置函数大全
IMPYLH2025/10/5

Python 的内建函数 Python 提供了大量开箱即用的内置函数,这些函数就像是你编程工具箱中的瑞士军刀——小巧但功能强大,随时准备帮你解决各种编程挑战。从简单的数据转换到复杂的迭代操作,内置函数都能让我们的代码更加简洁、优雅和高效。 无论你是刚刚踏入编程大门的新手,还是希望提升编码效率的资深开发者,掌握Python内置函数都将为你的编程之旅带来质的飞跃。 让我们放下繁琐的重复代码,拥抱Python内置函数带来的简洁与力量。 Python 3.13 共计 71 个内置函数,以下按字母


[特殊字符]️ Spring Cloud Eureka 三步通:搭建注册中心 + 服务注册 + 服务发现,通俗易懂!
绝顶少年2025/10/7

📌 引言:什么是服务注册与发现? 在微服务架构中,我们通常会将一个大型系统拆分成多个小服务,比如: 用户服务(user-service) 订单服务(order-service) 支付服务(payment-service) 这些服务可能会​​相互调用​​,比如订单服务要查询用户信息,就需要调用用户服务。 但问题来了:​​订单服务怎么知道用户服务在哪里(IP + 端口)?​​ 👉 ​​这就是服务注册与发现要解决的问题!​​ 🤖 什么是 Eureka? ​​E


dep.ts 逐行解读
excel2025/10/8

简化归纳 一、导入与上下文说明(开头几行) import { extend, isArray, isIntegerKey, isMap, isSymbol } from '@vue/shared' import type { ComputedRefImpl } from './computed' import { type TrackOpTypes, TriggerOpTypes } from './constants' import { type DebuggerEventExtraInf


ASM1042芯片在汽车BCM项目的工程化应用探索
国科安芯2025/10/10

摘要 随着汽车产业的快速发展,车身控制模块(BCM)作为汽车电子系统的核心组件之一,对芯片的性能、可靠性和适应性提出了更高的要求。本文综合分析了国科安芯推出的ASM1042芯片的技术特性、可靠性测试结果以及实际应用案例,结合汽车BCM项目的需求背景,系统性地探讨了ASM1042芯片在汽车电子领域的工程化应用潜力。通过对芯片性能的深度剖析以及实际应用中的挑战与解决方案的详细阐述,本文旨在为汽车电子系统的设计与优化提供参考,同时推动高性能通信芯片在汽车领域的广泛应用。 一、引言 在现代汽车架构

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0