🎭 创建型设计模式:对象诞生的艺术与智慧
💡 温馨提示:本文将以轻松有趣的方式带你探索设计模式的世界,就像在听一个关于"如何优雅地生孩子"的故事一样!
🚪 传送门 :在开始我们的"对象制造之旅"之前,建议先通过这个 🎨 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
🎬 设计模式英雄联盟大结局 🎬
┌─────────────────────────────────────┐
│ 🎊 恭喜你完成学习之旅! │
│ │
│ 🎭 单例侠:"我是唯一的存在!" │
│ 🏭 工厂侠:"我让子类选择!" │
│ 🏭 抽象工厂侠:"我创建系列产品!" │
│ 🏭 建造者侠:"我一步步组装!" │
│ 🏭 原型侠:"我会克隆!" │
│ │
│ 🦸♂️ 五位英雄联手,代码更优雅! │
└─────────────────────────────────────┘
🎯 选择建议(简单记忆法):
- 🎭 单例模式:当你需要"唯一"时
- 🏭 工厂方法模式:当你需要"选择"时
- 🏭 抽象工厂模式:当你需要"系列"时
- 🏭 建造者模式:当你需要"组装"时
- 🏭 原型模式:当你需要"复制"时
💡 实践要点:
- 🎯 理解场景:根据具体业务场景选择合适的设计模式
- 🚫 避免过度设计:不是所有地方都需要使用设计模式(不要为了用而用)
- ⚡ 考虑性能:设计模式可能带来一定的性能开销
- ✨ 保持简单:优先选择简单的解决方案(KISS原则)
🎊 恭喜你!
通过这次学习,你已经掌握了创建型设计模式的核心思想!现在你可以在实际项目中:
- 🎯 更好地管理对象的创建过程
- 🚀 提高代码的可维护性和可扩展性
- 💪 写出更优雅、更专业的代码
记住:设计模式不是银弹,而是工具箱中的工具。选择合适的设计模式,让你的代码更加优雅!🌟
本文使用 markdown.com.cn 排版