🎭 创建型设计模式:对象诞生的艺术与智慧

🎭 创建型设计模式:对象诞生的艺术与智慧

💡 温馨提示:本文将以轻松有趣的方式带你探索设计模式的世界,就像在听一个关于"如何优雅地生孩子"的故事一样!
🚪 传送门 :在开始我们的"对象制造之旅"之前,建议先通过这个 🎨 Java设计模式详解:让代码优雅如诗的秘密武器 了解设计模式的基础概念和整体架构,这样能让你更好地理解本文内容!就像玩游戏要先看新手教程一样!🎮

🎪 引言:为什么我们需要设计模式?

arduino 复制代码
🏭 场景:混乱的代码工厂 🏭
┌─────────────────────────────────────┐
│  💻 程序员小王的一天 💻              │
│                                     │
│  😵 "new"操作符满天飞!             │
│  🔥 代码重复像复制粘贴大赛!         │
│  🐛 Bug多得像夏天的蚊子!           │
│                                     │
│  💡 突然,设计模式英雄出现了!       │
│  🦸‍♂️ "让我来拯救你的代码!"         │
└─────────────────────────────────────┘

创建型设计模式就像是"对象制造"的标准作业流程,让代码变得优雅、可维护、可扩展。

本文将带你探索五种创建型设计模式,就像参观五个不同的"对象制造车间"一样有趣!


🎯 本文你将学到什么?

复制代码
🎬 设计模式英雄联盟 🎬
┌─────────────────────────────────────┐
│  🦸‍♂️ 五位设计模式英雄登场!         │
│                                     │
│  🎭 单例侠:确保全局唯一            │
│  🏭 工厂侠:让子类决定创建什么      │
│  🏭 抽象工厂侠:创建系列相关产品    │
│  🏭 建造者侠:分步骤构建复杂对象    │
│  🏭 原型侠:克隆现有对象            │
│                                     │
│  🚀 准备好开始冒险了吗?            │
└─────────────────────────────────────┘

🏭 第一部分:单例模式(Singleton Pattern)

arduino 复制代码
🎭 单例侠的登场 🎭
┌─────────────────────────────────────┐
│  👑 单例侠:我是唯一的存在!        │
│                                     │
│  🏢 公司CEO:"我要一个总经理!"     │
│  👔 单例侠:"只能有一个!"          │
│  🏢 公司CEO:"再来一个!"           │
│  👔 单例侠:"还是同一个!"          │
│                                     │
│  💡 核心思想:确保全局唯一          │
└─────────────────────────────────────┘

🏗️ 单例模式UML类图

1.1 🎭 什么是单例模式?

一句话理解:确保一个类只有一个实例,就像公司只有一个总经理!

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

应用场景:数据库连接池、配置管理器、日志记录器、缓存管理器

1.2 🛠️ 单例模式的实现方式

实现方式 特点 推荐度
饿汉式 线程安全,但可能浪费内存 ⭐⭐⭐
懒汉式 延迟加载,但线程不安全 ⭐⭐
双重检查锁定 延迟加载 + 线程安全 ⭐⭐⭐⭐
枚举单例 自动线程安全,最优雅 ⭐⭐⭐⭐⭐
1.2.1 🍔 饿汉式单例(Eager Singleton)

💡 小贴士:就像你提前准备好午餐一样,饿汉式在类加载时就创建了实例,所以叫"饿汉"(迫不及待)!

特点:线程安全,但可能造成不必要的内存占用

csharp 复制代码
public class EagerSingleton {
    private static final EagerSingleton INSTANCE = new EagerSingleton();
    
    private EagerSingleton() {}
    
    public static EagerSingleton getInstance() {
        return INSTANCE;
    }
}
1.2.2 😴 懒汉式单例(Lazy Singleton)

💡 小贴士:就像你等到饿了才去做饭一样,懒汉式只有在第一次使用时才创建实例,所以叫"懒汉"(能拖就拖)!

特点:延迟加载,但需要处理线程安全问题

csharp 复制代码
public class LazySingleton {
    private static LazySingleton instance;
    
    private LazySingleton() {}
    
    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}
1.2.3 🔒 双重检查锁定单例(Double-Checked Locking)

💡 小贴士:这是懒汉式的升级版!就像你进房间前先敲门,确认没人再进去,然后再锁门一样,双重检查确保线程安全!

特点:延迟加载 + 线程安全,性能最优

csharp 复制代码
public class DoubleCheckedSingleton {
    private static volatile DoubleCheckedSingleton instance;
    
    private DoubleCheckedSingleton() {}
    
    public static DoubleCheckedSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckedSingleton.class) {
                if (instance == null) {
                    instance = new DoubleCheckedSingleton();
                }
            }
        }
        return instance;
    }
}
1.2.4 🎯 枚举单例(Enum Singleton)

💡 小贴士:这是Java中最优雅的单例实现方式!就像枚举天生就是单例一样,简单、安全、优雅!

特点:自动线程安全,自动序列化安全,推荐使用

csharp 复制代码
public enum EnumSingleton {
    INSTANCE;
    
    public void doSomething() {
        System.out.println("枚举单例执行操作");
    }
}

1.3 🎯 单例模式的实际应用

arduino 复制代码
// 配置管理器单例
public class ConfigManager {
    private static final ConfigManager INSTANCE = new ConfigManager();
    private final Properties properties;
    
    private ConfigManager() {
        properties = new Properties();
        loadConfig();
    }
    
    public static ConfigManager getInstance() {
        return INSTANCE;
    }
    
    private void loadConfig() {
        // 加载配置文件
    }
    
    public String getProperty(String key) {
        return properties.getProperty(key);
    }
}

🏭 第二部分:工厂方法模式(Factory Method Pattern)

arduino 复制代码
🏭 工厂侠的登场 🏭
┌─────────────────────────────────────┐
│  🏭 工厂侠:我有多个车间!          │
│                                     │
│  🚗 轿车车间:"我要生产轿车!"      │
│  🚐 面包车车间:"我要生产面包车!"  │
│  🚚 卡车车间:"我要生产卡车!"      │
│                                     │
│  🏭 工厂侠:"每个车间都有自己的    │
│      制造方法,但都遵循同一协议!"  │
└─────────────────────────────────────┘

🏗️ 工厂方法模式UML类图

2.1 🏭 什么是工厂方法模式?

一句话理解:让子类决定创建什么对象,就像不同车间生产不同产品!

定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。

应用场景:数据库连接器创建、日志记录器创建、文件处理器创建

2.2 🛠️ 工厂方法模式的实现

csharp 复制代码
// 抽象产品
public interface Product {
    void operation();
}

// 具体产品
public class ConcreteProductA implements Product {
    @Override
    public void operation() {
        System.out.println("具体产品A的操作");
    }
}

// 抽象工厂
public interface Factory {
    Product createProduct();
}

// 具体工厂
public class ConcreteFactoryA implements Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

2.3 🗄️ 数据库连接器工厂示例

csharp 复制代码
// 数据库连接器接口
public interface DatabaseConnector {
    void connect();
    void disconnect();
    void executeQuery(String sql);
}

// MySQL连接器
public class MySQLConnector implements DatabaseConnector {
    @Override
    public void connect() {
        System.out.println("连接到MySQL数据库");
    }
    
    @Override
    public void disconnect() {
        System.out.println("断开MySQL数据库连接");
    }
    
    @Override
    public void executeQuery(String sql) {
        System.out.println("在MySQL中执行查询: " + sql);
    }
}

// 数据库连接器工厂接口
public interface DatabaseConnectorFactory {
    DatabaseConnector createConnector();
}

// MySQL连接器工厂
public class MySQLConnectorFactory implements DatabaseConnectorFactory {
    @Override
    public DatabaseConnector createConnector() {
        return new MySQLConnector();
    }
}

🏭 第三部分:抽象工厂模式(Abstract Factory Pattern)

arduino 复制代码
🏭 抽象工厂侠的登场 🏭
┌─────────────────────────────────────┐
│  🏭 抽象工厂侠:我提供完整生态!    │
│                                     │
│  📱 苹果工厂:"iPhone + AirPods +   │
│      苹果充电器,完美搭配!"        │
│  📱 三星工厂:"Galaxy + Galaxy Buds │
│      + 三星充电器,系列相关!"      │
│                                     │
│  🏭 抽象工厂侠:"确保产品兼容性!"  │
└─────────────────────────────────────┘

🏗️ 抽象工厂模式UML类图

3.1 🏭 什么是抽象工厂模式?

一句话理解:创建一系列相关产品,就像品牌提供完整生态!

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

应用场景:UI组件库、数据库访问层、操作系统适配、主题系统

3.2 🛠️ 抽象工厂模式的实现

csharp 复制代码
// 抽象产品A
public interface AbstractProductA {
    void operationA();
}

// 抽象产品B
public interface AbstractProductB {
    void operationB();
}

// 具体产品A1
public class ConcreteProductA1 implements AbstractProductA {
    @Override
    public void operationA() {
        System.out.println("具体产品A1的操作");
    }
}

// 抽象工厂
public interface AbstractFactory {
    AbstractProductA createProductA();
    AbstractProductB createProductB();
}

// 具体工厂1
public class ConcreteFactory1 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }
    
    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

3.3 🖥️ UI组件工厂示例

csharp 复制代码
// UI组件接口
public interface Button {
    void render();
    void onClick();
}

public interface Checkbox {
    void render();
    void check();
}

// Windows风格组件
public class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染Windows风格按钮");
    }
    
    @Override
    public void onClick() {
        System.out.println("Windows按钮点击事件");
    }
}

// UI工厂接口
public interface UIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

// Windows UI工厂
public class WindowsUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }
    
    @Override
    public Checkbox createCheckbox() {
        return new WindowsCheckbox();
    }
}

🏭 第四部分:建造者模式(Builder Pattern)

arduino 复制代码
🏭 建造者侠的登场 🏭
┌─────────────────────────────────────┐
│  🏭 建造者侠:我一步步组装!        │
│                                     │
│  🎨 步骤1:"选择车身颜色!"         │
│  🚗 步骤2:"选择发动机型号!"       │
│  🎵 步骤3:"选择音响系统!"         │
│  🪑 步骤4:"选择座椅材质!"         │
│                                     │
│  🏭 建造者侠:"最终组装成独一无二   │
│      的汽车!"                      │
└─────────────────────────────────────┘

🏗️ 建造者模式UML类图

4.1 🏗️ 什么是建造者模式?

一句话理解:分步骤构建复杂对象,就像定制汽车一步步组装!

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

应用场景:复杂对象的创建、参数较多的构造函数、链式调用

4.2 🛠️ 建造者模式的实现

arduino 复制代码
// 产品类
public class Computer {
    private String cpu;
    private String memory;
    private String storage;
    private String graphicsCard;
    private String motherboard;
    
    // Getters and Setters
    public String getCpu() { return cpu; }
    public void setCpu(String cpu) { this.cpu = cpu; }
    
    public String getMemory() { return memory; }
    public void setMemory(String memory) { this.memory = memory; }
    
    // ... 其他getter和setter
    
    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + ''' +
                ", memory='" + memory + ''' +
                ", storage='" + storage + ''' +
                ", graphicsCard='" + graphicsCard + ''' +
                ", motherboard='" + motherboard + ''' +
                '}';
    }
}

// 抽象建造者
public abstract class ComputerBuilder {
    protected Computer computer = new Computer();
    
    public abstract void buildCpu();
    public abstract void buildMemory();
    public abstract void buildStorage();
    public abstract void buildGraphicsCard();
    public abstract void buildMotherboard();
    
    public Computer getResult() {
        return computer;
    }
}

// 具体建造者 - 游戏电脑
public class GamingComputerBuilder extends ComputerBuilder {
    @Override
    public void buildCpu() {
        computer.setCpu("Intel i9-12900K");
    }
    
    @Override
    public void buildMemory() {
        computer.setMemory("32GB DDR5");
    }
    
    @Override
    public void buildStorage() {
        computer.setStorage("2TB NVMe SSD");
    }
    
    @Override
    public void buildGraphicsCard() {
        computer.setGraphicsCard("RTX 4090");
    }
    
    @Override
    public void buildMotherboard() {
        computer.setMotherboard("Z690 Gaming");
    }
}

// 导演类
public class ComputerDirector {
    private ComputerBuilder builder;
    
    public void setBuilder(ComputerBuilder builder) {
        this.builder = builder;
    }
    
    public Computer construct() {
        builder.buildCpu();
        builder.buildMemory();
        builder.buildStorage();
        builder.buildGraphicsCard();
        builder.buildMotherboard();
        return builder.getResult();
    }
}

4.3 🔗 链式建造者(Fluent Builder)

typescript 复制代码
// 链式建造者
public class Computer {
    private String cpu;
    private String memory;
    private String storage;
    private String graphicsCard;
    private String motherboard;
    
    private Computer() {}
    
    public static ComputerBuilder builder() {
        return new ComputerBuilder();
    }
    
    // 内部建造者类
    public static class ComputerBuilder {
        private Computer computer = new Computer();
        
        public ComputerBuilder cpu(String cpu) {
            computer.cpu = cpu;
            return this;
        }
        
        public ComputerBuilder memory(String memory) {
            computer.memory = memory;
            return this;
        }
        
        public ComputerBuilder storage(String storage) {
            computer.storage = storage;
            return this;
        }
        
        public ComputerBuilder graphicsCard(String graphicsCard) {
            computer.graphicsCard = graphicsCard;
            return this;
        }
        
        public ComputerBuilder motherboard(String motherboard) {
            computer.motherboard = motherboard;
            return this;
        }
        
        public Computer build() {
            // 验证必填字段
            if (computer.cpu == null) {
                throw new IllegalArgumentException("CPU是必填项");
            }
            if (computer.memory == null) {
                throw new IllegalArgumentException("内存是必填项");
            }
            return computer;
        }
    }
}

// 使用示例
public class ChainBuilderDemo {
    public static void main(String[] args) {
        Computer computer = Computer.builder()
                .cpu("Intel i7-12700K")
                .memory("32GB DDR4")
                .storage("1TB NVMe SSD")
                .graphicsCard("RTX 3080")
                .motherboard("Z690")
                .build();
        
        System.out.println("链式构建的电脑: " + computer);
    }
}

🏭 第五部分:原型模式(Prototype Pattern)

arduino 复制代码
🏭 原型侠的登场 🏭
┌─────────────────────────────────────┐
│  🏭 原型侠:我会克隆!              │
│                                     │
│  🧬 科学家:"我要复制这个细胞!"    │
│  🏭 原型侠:"克隆成功!"            │
│  🧬 科学家:"我要创建新变种!"      │
│  🏭 原型侠:"基于原型创建!"        │
│                                     │
│  🏭 原型侠:"避免重新培养的复杂     │
│      过程!"                        │
└─────────────────────────────────────┘

🏗️ 原型模式UML类图

5.1 🧬 什么是原型模式?

一句话理解:克隆现有对象创建新对象,就像生物克隆一样神奇!

定义:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。

应用场景:对象创建成本较高、避免构造函数的约束、动态加载类

5.2 🛠️ 原型模式的实现

typescript 复制代码
// 原型接口
public interface Prototype extends Cloneable {
    Prototype clone();
}

// 具体原型
public class ConcretePrototype implements Prototype {
    private String name;
    private int age;
    private List<String> hobbies;
    
    public ConcretePrototype(String name, int age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        this.hobbies = new ArrayList<>(hobbies);
    }
    
    @Override
    public Prototype clone() {
        try {
            ConcretePrototype cloned = (ConcretePrototype) super.clone();
            // 深拷贝hobbies列表
            cloned.hobbies = new ArrayList<>(this.hobbies);
            return cloned;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException("克隆失败", e);
        }
    }
    
    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    
    public List<String> getHobbies() { return hobbies; }
    public void setHobbies(List<String> hobbies) { this.hobbies = hobbies; }
    
    @Override
    public String toString() {
        return "ConcretePrototype{" +
                "name='" + name + ''' +
                ", age=" + age +
                ", hobbies=" + hobbies +
                '}';
    }
}

5.3 📄 文档模板系统示例

typescript 复制代码
// 文档接口
public interface Document extends Cloneable {
    Document clone();
    void setContent(String content);
    void setAuthor(String author);
    void setDate(String date);
    void display();
}

// 报告文档
public class Report implements Document {
    private String title;
    private String content;
    private String author;
    private String date;
    private List<String> sections;
    
    public Report(String title) {
        this.title = title;
        this.sections = new ArrayList<>();
    }
    
    @Override
    public Document clone() {
        try {
            Report cloned = (Report) super.clone();
            // 深拷贝sections列表
            cloned.sections = new ArrayList<>(this.sections);
            return cloned;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException("克隆失败", e);
        }
    }
    
    @Override
    public void setContent(String content) {
        this.content = content;
    }
    
    @Override
    public void setAuthor(String author) {
        this.author = author;
    }
    
    @Override
    public void setDate(String date) {
        this.date = date;
    }
    
    public void addSection(String section) {
        sections.add(section);
    }
    
    @Override
    public void display() {
        System.out.println("报告标题: " + title);
        System.out.println("作者: " + author);
        System.out.println("日期: " + date);
        System.out.println("内容: " + content);
        System.out.println("章节: " + sections);
    }
}

// 文档管理器
public class DocumentManager {
    private Map<String, Document> prototypes = new HashMap<>();
    
    public void addPrototype(String key, Document document) {
        prototypes.put(key, document);
    }
    
    public Document getClone(String key) {
        Document prototype = prototypes.get(key);
        if (prototype == null) {
            throw new IllegalArgumentException("原型不存在: " + key);
        }
        return prototype.clone();
    }
}

5.4 🔍 深拷贝与浅拷贝

拷贝类型 特点 适用场景
浅拷贝 只复制对象引用,不复制引用对象 简单对象,无嵌套引用
深拷贝 复制对象及其所有引用对象 复杂对象,有嵌套引用

关键点:原型模式中通常需要深拷贝来避免对象间的相互影响。

csharp 复制代码
// 浅拷贝示例
public class ShallowCopyExample {
    public static void main(String[] args) {
        List<String> originalList = Arrays.asList("Java", "Python", "C++");
        ConcretePrototype original = new ConcretePrototype("张三", 25, originalList);
        
        ConcretePrototype cloned = (ConcretePrototype) original.clone();
        
        // 修改原始对象的hobbies
        original.getHobbies().add("JavaScript");
        
        System.out.println("原始对象: " + original);
        System.out.println("克隆对象: " + cloned);
        // 注意:浅拷贝时,克隆对象的hobbies也会被修改
    }
}

// 深拷贝实现
public class DeepCopyExample {
    public static void main(String[] args) {
        List<String> originalList = Arrays.asList("Java", "Python", "C++");
        ConcretePrototype original = new ConcretePrototype("张三", 25, originalList);
        
        ConcretePrototype cloned = (ConcretePrototype) original.clone();
        
        // 修改原始对象的hobbies
        original.getHobbies().add("JavaScript");
        
        System.out.println("原始对象: " + original);
        System.out.println("克隆对象: " + cloned);
        // 深拷贝时,克隆对象的hobbies不会被修改
    }
}

🎉 总结:创建型设计模式大揭秘

arduino 复制代码
🎬 设计模式英雄联盟大结局 🎬
┌─────────────────────────────────────┐
│  🎊 恭喜你完成学习之旅!            │
│                                     │
│  🎭 单例侠:"我是唯一的存在!"      │
│  🏭 工厂侠:"我让子类选择!"        │
│  🏭 抽象工厂侠:"我创建系列产品!"  │
│  🏭 建造者侠:"我一步步组装!"      │
│  🏭 原型侠:"我会克隆!"            │
│                                     │
│  🦸‍♂️ 五位英雄联手,代码更优雅!    │
└─────────────────────────────────────┘

🎯 选择建议(简单记忆法):

  • 🎭 单例模式:当你需要"唯一"时
  • 🏭 工厂方法模式:当你需要"选择"时
  • 🏭 抽象工厂模式:当你需要"系列"时
  • 🏭 建造者模式:当你需要"组装"时
  • 🏭 原型模式:当你需要"复制"时

💡 实践要点:

  1. 🎯 理解场景:根据具体业务场景选择合适的设计模式
  2. 🚫 避免过度设计:不是所有地方都需要使用设计模式(不要为了用而用)
  3. ⚡ 考虑性能:设计模式可能带来一定的性能开销
  4. ✨ 保持简单:优先选择简单的解决方案(KISS原则)

🎊 恭喜你!

通过这次学习,你已经掌握了创建型设计模式的核心思想!现在你可以在实际项目中:

  • 🎯 更好地管理对象的创建过程
  • 🚀 提高代码的可维护性和可扩展性
  • 💪 写出更优雅、更专业的代码

记住:设计模式不是银弹,而是工具箱中的工具。选择合适的设计模式,让你的代码更加优雅!🌟


本文使用 markdown.com.cn 排版

相关推荐
快乐的划水a1 小时前
建造者模式及优化
设计模式·建造者模式
源代码•宸1 小时前
深入浅出设计模式——创建型模式之建造者模式 Builder
c++·经验分享·设计模式·建造者模式
DKPT1 小时前
Java设计模式之行为型模式(解释器模式)实现方式详解
java·笔记·学习·设计模式·解释器模式
pointers_syc1 小时前
【设计模式】 原则
设计模式
Techie峰5 小时前
【Java23种设计模式】:模板方法模式
java·设计模式·模板方法模式
找不到、了15 小时前
Java设计模式之<建造者模式>
java·设计模式·建造者模式
LoveC52119 小时前
设计模式之适配器模式
设计模式·适配器模式
永卿00121 小时前
设计模式-责任链模式
java·设计模式·责任链模式
Codebee1 天前
OneCode 3.0 智能数据处理:快速视图中的智能分页与 @PageBar 注解详解
后端·设计模式