引言:设计模式的重要性
想象一下建造一座高楼大厦。没有蓝图和标准施工方法,每个建筑工人按自己的想法随意建造,结果会是灾难性的。同样,在软件开发中,设计模式就是经过验证的"蓝图",它帮助我们构建可维护、可扩展、可复用的代码。设计模式不是具体代码,而是解决特定问题的思想模型。
设计模式分类概览
java
设计模式分为三大类:
├── 创建型模式 (Creational Patterns)
│ ├── 单例模式 (Singleton)
│ ├── 工厂方法模式 (Factory Method)
│ ├── 抽象工厂模式 (Abstract Factory)
│ ├── 建造者模式 (Builder)
│ └── 原型模式 (Prototype)
│
├── 结构型模式 (Structural Patterns)
│ ├── 适配器模式 (Adapter)
│ ├── 装饰器模式 (Decorator)
│ ├── 代理模式 (Proxy)
│ └── ...
│
└── 行为型模式 (Behavioral Patterns)
├── 观察者模式 (Observer)
├── 策略模式 (Strategy)
├── 责任链模式 (Chain of Responsibility)
└── ...
本文将深入探讨创建型模式,这些模式关注对象的创建过程,隐藏创建细节,使系统独立于对象的创建、组合和表示。
单例模式:确保唯一性
问题场景
在某些情况下,系统中只需要一个类的实例,比如:
- 数据库连接池
- 配置文件管理器
- 日志记录器
- 线程池
多种实现方式对比
java
public class SingletonPattern {
// 方式1:饿汉式(线程安全,但可能造成资源浪费)
static class EagerSingleton {
private static final EagerSingleton INSTANCE = new EagerSingleton();
private EagerSingleton() {
// 私有构造器防止外部实例化
System.out.println("饿汉式单例被创建");
}
public static EagerSingleton getInstance() {
return INSTANCE;
}
public void doSomething() {
System.out.println("饿汉式单例工作");
}
}
// 方式2:懒汉式(线程不安全)
static class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
System.out.println("懒汉式单例被创建");
}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton(); // 多线程环境下可能创建多个实例
}
return instance;
}
}
// 方式3:同步方法懒汉式(线程安全但效率低)
static class SynchronizedLazySingleton {
private static SynchronizedLazySingleton instance;
private SynchronizedLazySingleton() {
System.out.println("同步懒汉式单例被创建");
}
public static synchronized SynchronizedLazySingleton getInstance() {
if (instance == null) {
instance = new SynchronizedLazySingleton();
}
return instance;
}
}
// 方式4:双重检查锁定(DCL)
static class DoubleCheckedSingleton {
// 使用volatile防止指令重排序
private static volatile DoubleCheckedSingleton instance;
private DoubleCheckedSingleton() {
System.out.println("双重检查单例被创建");
}
public static DoubleCheckedSingleton getInstance() {
if (instance == null) { // 第一次检查,避免不必要的同步
synchronized (DoubleCheckedSingleton.class) {
if (instance == null) { // 第二次检查,确保唯一性
instance = new DoubleCheckedSingleton();
}
}
}
return instance;
}
}
// 方式5:静态内部类(推荐)
static class StaticInnerClassSingleton {
private StaticInnerClassSingleton() {
System.out.println("静态内部类单例被创建");
}
// 静态内部类在第一次使用时才会加载
private static class SingletonHolder {
private static final StaticInnerClassSingleton INSTANCE =
new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
// 方式6:枚举单例(最安全,防止反射攻击和序列化问题)
enum EnumSingleton {
INSTANCE;
private EnumSingleton() {
System.out.println("枚举单例被创建");
}
public void doSomething() {
System.out.println("枚举单例工作");
}
}
// 测试代码
public static void main(String[] args) {
// 测试饿汉式
EagerSingleton eager1 = EagerSingleton.getInstance();
EagerSingleton eager2 = EagerSingleton.getInstance();
System.out.println("饿汉式是否是同一个实例: " + (eager1 == eager2));
// 测试双重检查
DoubleCheckedSingleton dcl1 = DoubleCheckedSingleton.getInstance();
DoubleCheckedSingleton dcl2 = DoubleCheckedSingleton.getInstance();
System.out.println("双重检查是否是同一个实例: " + (dcl1 == dcl2));
// 测试枚举单例
EnumSingleton enum1 = EnumSingleton.INSTANCE;
EnumSingleton enum2 = EnumSingleton.INSTANCE;
System.out.println("枚举是否是同一个实例: " + (enum1 == enum2));
enum1.doSomething();
}
}
实际应用:数据库连接池
java
// 数据库连接池的单例实现
public class DatabaseConnectionPool {
private static DatabaseConnectionPool instance;
private final List<Connection> connectionPool;
private final int maxConnections;
private final String url;
private final String username;
private final String password;
private DatabaseConnectionPool() {
this.maxConnections = 10;
this.url = "jdbc:mysql://localhost:3306/mydb";
this.username = "root";
this.password = "password";
this.connectionPool = new ArrayList<>();
// 初始化连接池
initializePool();
}
public static synchronized DatabaseConnectionPool getInstance() {
if (instance == null) {
instance = new DatabaseConnectionPool();
}
return instance;
}
private void initializePool() {
try {
for (int i = 0; i < maxConnections; i++) {
Connection conn = DriverManager.getConnection(url, username, password);
connectionPool.add(conn);
}
System.out.println("数据库连接池初始化完成,连接数: " + connectionPool.size());
} catch (SQLException e) {
throw new RuntimeException("初始化数据库连接池失败", e);
}
}
public synchronized Connection getConnection() {
if (connectionPool.isEmpty()) {
throw new RuntimeException("连接池已耗尽");
}
return connectionPool.remove(0);
}
public synchronized void releaseConnection(Connection conn) {
if (connectionPool.size() < maxConnections) {
connectionPool.add(conn);
} else {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public synchronized void closeAllConnections() {
for (Connection conn : connectionPool) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
connectionPool.clear();
}
}
工厂方法模式:解耦创建逻辑
问题场景
当创建对象的过程比较复杂,或者需要根据不同的条件创建不同的对象时,直接使用new关键字会使得代码耦合度高,难以维护。
基本实现
java
public class FactoryMethodPattern {
// 产品接口
interface Shape {
void draw();
double getArea();
}
// 具体产品
static class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("绘制圆形,半径: " + radius);
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}
static class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("绘制矩形,宽: " + width + ", 高: " + height);
}
@Override
public double getArea() {
return width * height;
}
}
static class Square implements Shape {
private double side;
public Square(double side) {
this.side = side;
}
@Override
public void draw() {
System.out.println("绘制正方形,边长: " + side);
}
@Override
public double getArea() {
return side * side;
}
}
// 工厂接口
interface ShapeFactory {
Shape createShape();
}
// 具体工厂
static class CircleFactory implements ShapeFactory {
private final double radius;
public CircleFactory(double radius) {
this.radius = radius;
}
@Override
public Shape createShape() {
return new Circle(radius);
}
}
static class RectangleFactory implements ShapeFactory {
private final double width;
private final double height;
public RectangleFactory(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public Shape createShape() {
return new Rectangle(width, height);
}
}
static class SquareFactory implements ShapeFactory {
private final double side;
public SquareFactory(double side) {
this.side = side;
}
@Override
public Shape createShape() {
return new Square(side);
}
}
// 客户端代码
public static void main(String[] args) {
// 使用工厂创建对象
ShapeFactory circleFactory = new CircleFactory(5.0);
Shape circle = circleFactory.createShape();
circle.draw();
System.out.println("圆形面积: " + circle.getArea());
ShapeFactory rectangleFactory = new RectangleFactory(4.0, 6.0);
Shape rectangle = rectangleFactory.createShape();
rectangle.draw();
System.out.println("矩形面积: " + rectangle.getArea());
// 通过配置文件决定使用哪个工厂
String shapeType = "square"; // 可以从配置文件中读取
ShapeFactory factory = createFactory(shapeType, 3.0, 0.0);
Shape shape = factory.createShape();
shape.draw();
}
// 根据类型创建工厂(可以扩展为从配置文件读取)
private static ShapeFactory createFactory(String type, double param1, double param2) {
switch (type.toLowerCase()) {
case "circle":
return new CircleFactory(param1);
case "rectangle":
return new RectangleFactory(param1, param2);
case "square":
return new SquareFactory(param1);
default:
throw new IllegalArgumentException("不支持的形状类型: " + type);
}
}
}
实际应用:数据库连接工厂
java
// 数据库连接工厂
public class DatabaseConnectionFactory {
// 数据库类型枚举
enum DatabaseType {
MYSQL,
POSTGRESQL,
ORACLE,
SQLSERVER
}
// 数据库连接接口
interface DatabaseConnection {
Connection getConnection();
String getDatabaseInfo();
void executeQuery(String sql);
}
// MySQL连接实现
static class MySQLConnection implements DatabaseConnection {
private final String url;
private final String username;
private final String password;
public MySQLConnection(String url, String username, String password) {
this.url = url;
this.username = username;
this.password = password;
}
@Override
public Connection getConnection() {
try {
return DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
throw new RuntimeException("MySQL连接失败", e);
}
}
@Override
public String getDatabaseInfo() {
return "MySQL数据库连接: " + url;
}
@Override
public void executeQuery(String sql) {
try (Connection conn = getConnection();
Statement stmt = conn.createStatement()) {
stmt.execute(sql);
System.out.println("MySQL查询执行成功: " + sql);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// PostgreSQL连接实现
static class PostgreSQLConnection implements DatabaseConnection {
// 类似MySQLConnection的实现,省略...
}
// 数据库连接工厂
static class ConnectionFactory {
private final Properties config;
public ConnectionFactory(String configFile) {
config = loadConfig(configFile);
}
public DatabaseConnection createConnection(DatabaseType type) {
String url = config.getProperty(type.name().toLowerCase() + ".url");
String username = config.getProperty(type.name().toLowerCase() + ".username");
String password = config.getProperty(type.name().toLowerCase() + ".password");
switch (type) {
case MYSQL:
return new MySQLConnection(url, username, password);
case POSTGRESQL:
return new PostgreSQLConnection(url, username, password);
// 其他数据库类型...
default:
throw new IllegalArgumentException("不支持的数据库类型: " + type);
}
}
private Properties loadConfig(String configFile) {
Properties props = new Properties();
try (InputStream input = getClass().getClassLoader().getResourceAsStream(configFile)) {
props.load(input);
} catch (IOException e) {
throw new RuntimeException("加载配置文件失败", e);
}
return props;
}
}
public static void main(String[] args) {
// 使用工厂创建数据库连接
ConnectionFactory factory = new ConnectionFactory("database.properties");
DatabaseConnection mysqlConn = factory.createConnection(DatabaseType.MYSQL);
System.out.println(mysqlConn.getDatabaseInfo());
mysqlConn.executeQuery("SELECT * FROM users");
// 切换数据库类型只需修改参数
DatabaseConnection pgConn = factory.createConnection(DatabaseType.POSTGRESQL);
System.out.println(pgConn.getDatabaseInfo());
}
}
抽象工厂模式:创建产品族
问题场景
当需要创建一系列相关或相互依赖的对象时,比如:
- GUI组件:不同操作系统的按钮、文本框、对话框
- 数据库访问:不同数据库的连接、命令、适配器
- 游戏开发:不同主题的角色、武器、场景
基本实现
java
public class AbstractFactoryPattern {
// 抽象产品A:UI组件
interface Button {
void render();
void onClick();
}
interface TextField {
void render();
String getText();
void setText(String text);
}
interface Dialog {
void render();
void addButton(Button button);
void addTextField(TextField field);
}
// 具体产品:Windows风格
static class WindowsButton implements Button {
@Override
public void render() {
System.out.println("渲染Windows风格按钮");
}
@Override
public void onClick() {
System.out.println("Windows按钮被点击");
}
}
static class WindowsTextField implements TextField {
private String text = "";
@Override
public void render() {
System.out.println("渲染Windows风格文本框,内容: " + text);
}
@Override
public String getText() {
return text;
}
@Override
public void setText(String text) {
this.text = text;
}
}
static class WindowsDialog implements Dialog {
private final List<Button> buttons = new ArrayList<>();
private final List<TextField> textFields = new ArrayList<>();
@Override
public void render() {
System.out.println("渲染Windows风格对话框");
System.out.println("包含 " + buttons.size() + " 个按钮");
System.out.println("包含 " + textFields.size() + " 个文本框");
}
@Override
public void addButton(Button button) {
buttons.add(button);
}
@Override
public void addTextField(TextField field) {
textFields.add(field);
}
}
// 具体产品:Mac风格
static class MacButton implements Button {
@Override
public void render() {
System.out.println("渲染Mac风格按钮");
}
@Override
public void onClick() {
System.out.println("Mac按钮被点击");
}
}
static class MacTextField implements TextField {
private String text = "";
@Override
public void render() {
System.out.println("渲染Mac风格文本框,内容: " + text);
}
@Override
public String getText() {
return text;
}
@Override
public void setText(String text) {
this.text = text;
}
}
static class MacDialog implements Dialog {
// 类似WindowsDialog的实现,省略...
}
// 抽象工厂
interface UIFactory {
Button createButton();
TextField createTextField();
Dialog createDialog();
}
// 具体工厂:Windows工厂
static class WindowsUIFactory implements UIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public TextField createTextField() {
return new WindowsTextField();
}
@Override
public Dialog createDialog() {
return new WindowsDialog();
}
}
// 具体工厂:Mac工厂
static class MacUIFactory implements UIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public TextField createTextField() {
return new MacTextField();
}
@Override
public Dialog createDialog() {
return new MacDialog();
}
}
// 客户端代码
public static class Application {
private final UIFactory factory;
private Button button;
private TextField textField;
private Dialog dialog;
public Application(UIFactory factory) {
this.factory = factory;
}
public void createUI() {
this.button = factory.createButton();
this.textField = factory.createTextField();
this.dialog = factory.createDialog();
}
public void renderUI() {
System.out.println("=== 渲染应用程序界面 ===");
button.render();
textField.render();
dialog.render();
}
}
public static void main(String[] args) {
// 根据配置决定使用哪个工厂
String os = System.getProperty("os.name").toLowerCase();
UIFactory factory;
if (os.contains("win")) {
factory = new WindowsUIFactory();
System.out.println("检测到Windows系统,使用Windows UI工厂");
} else if (os.contains("mac")) {
factory = new MacUIFactory();
System.out.println("检测到Mac系统,使用Mac UI工厂");
} else {
throw new UnsupportedOperationException("不支持的操作系统: " + os);
}
// 创建应用程序
Application app = new Application(factory);
app.createUI();
app.renderUI();
}
}
实际应用:数据库访问抽象工厂
java
// 数据库访问抽象工厂
public class DatabaseAccessFactory {
// 抽象产品:数据库连接
interface DBConnection {
Connection connect();
void disconnect();
boolean isConnected();
}
// 抽象产品:数据库命令
interface DBCommand {
void execute(String sql);
ResultSet executeQuery(String sql);
int executeUpdate(String sql);
}
// 抽象产品:数据适配器
interface DBAdapter {
<T> List<T> executeQuery(String sql, RowMapper<T> mapper);
int executeUpdate(String sql, Object... params);
}
// 行映射器接口
interface RowMapper<T> {
T mapRow(ResultSet rs) throws SQLException;
}
// MySQL具体产品
static class MySQLConnection implements DBConnection {
private Connection connection;
private final String url;
private final String username;
private final String password;
public MySQLConnection(String url, String username, String password) {
this.url = url;
this.username = username;
this.password = password;
}
@Override
public Connection connect() {
try {
connection = DriverManager.getConnection(url, username, password);
System.out.println("MySQL连接成功");
return connection;
} catch (SQLException e) {
throw new RuntimeException("MySQL连接失败", e);
}
}
@Override
public void disconnect() {
if (connection != null) {
try {
connection.close();
System.out.println("MySQL连接关闭");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
@Override
public boolean isConnected() {
try {
return connection != null && !connection.isClosed();
} catch (SQLException e) {
return false;
}
}
}
static class MySQLCommand implements DBCommand {
private final Connection connection;
public MySQLCommand(Connection connection) {
this.connection = connection;
}
@Override
public void execute(String sql) {
try (Statement stmt = connection.createStatement()) {
stmt.execute(sql);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public ResultSet executeQuery(String sql) {
try {
Statement stmt = connection.createStatement();
return stmt.executeQuery(sql);
} catch (SQLException e) {
throw new RuntimeException("查询执行失败", e);
}
}
@Override
public int executeUpdate(String sql) {
try (Statement stmt = connection.createStatement()) {
return stmt.executeUpdate(sql);
} catch (SQLException e) {
throw new RuntimeException("更新执行失败", e);
}
}
}
static class MySQLAdapter implements DBAdapter {
private final Connection connection;
public MySQLAdapter(Connection connection) {
this.connection = connection;
}
@Override
public <T> List<T> executeQuery(String sql, RowMapper<T> mapper) {
List<T> results = new ArrayList<>();
try (PreparedStatement stmt = connection.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
results.add(mapper.mapRow(rs));
}
} catch (SQLException e) {
throw new RuntimeException("查询执行失败", e);
}
return results;
}
@Override
public int executeUpdate(String sql, Object... params) {
try (PreparedStatement stmt = connection.prepareStatement(sql)) {
for (int i = 0; i < params.length; i++) {
stmt.setObject(i + 1, params[i]);
}
return stmt.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("更新执行失败", e);
}
}
}
// PostgreSQL具体产品(类似MySQL,省略)
// 抽象工厂
interface DatabaseFactory {
DBConnection createConnection();
DBCommand createCommand(Connection connection);
DBAdapter createAdapter(Connection connection);
}
// MySQL工厂
static class MySQLFactory implements DatabaseFactory {
private final String url;
private final String username;
private final String password;
public MySQLFactory(String url, String username, String password) {
this.url = url;
this.username = username;
this.password = password;
}
@Override
public DBConnection createConnection() {
return new MySQLConnection(url, username, password);
}
@Override
public DBCommand createCommand(Connection connection) {
return new MySQLCommand(connection);
}
@Override
public DBAdapter createAdapter(Connection connection) {
return new MySQLAdapter(connection);
}
}
// PostgreSQL工厂(类似MySQLFactory,省略)
// 客户端:数据库访问层
public static class DatabaseAccessLayer {
private final DatabaseFactory factory;
private DBConnection connection;
private DBCommand command;
private DBAdapter adapter;
public DatabaseAccessLayer(DatabaseFactory factory) {
this.factory = factory;
}
public void connect() {
connection = factory.createConnection();
connection.connect();
command = factory.createCommand(connection.connect());
adapter = factory.createAdapter(connection.connect());
}
public void executeQuery(String sql) {
command.execute(sql);
}
public <T> List<T> query(String sql, RowMapper<T> mapper) {
return adapter.executeQuery(sql, mapper);
}
public void disconnect() {
if (connection != null) {
connection.disconnect();
}
}
}
}
建造者模式:构建复杂对象
问题场景
当一个对象有多个属性,且构建过程复杂,或者需要构建不可变对象时,使用构造器会非常冗长且难以维护。
基本实现
java
public class BuilderPattern {
// 复杂产品:电脑
static class Computer {
private final String cpu;
private final String motherboard;
private final String memory;
private final String storage;
private final String gpu;
private final String powerSupply;
private final String coolingSystem;
private final boolean hasBluetooth;
private final boolean hasWiFi;
// 私有构造器,只能通过Builder创建
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.motherboard = builder.motherboard;
this.memory = builder.memory;
this.storage = builder.storage;
this.gpu = builder.gpu;
this.powerSupply = builder.powerSupply;
this.coolingSystem = builder.coolingSystem;
this.hasBluetooth = builder.hasBluetooth;
this.hasWiFi = builder.hasWiFi;
}
@Override
public String toString() {
return "Computer配置:\n" +
" CPU: " + cpu + "\n" +
" 主板: " + motherboard + "\n" +
" 内存: " + memory + "\n" +
" 存储: " + storage + "\n" +
" 显卡: " + (gpu != null ? gpu : "集成显卡") + "\n" +
" 电源: " + powerSupply + "\n" +
" 散热: " + coolingSystem + "\n" +
" 蓝牙: " + (hasBluetooth ? "有" : "无") + "\n" +
" WiFi: " + (hasWiFi ? "有" : "无");
}
// 建造者类
static class Builder {
// 必需参数
private final String cpu;
private final String motherboard;
private final String memory;
// 可选参数(带默认值)
private String storage = "512GB SSD";
private String gpu = null; // 默认集成显卡
private String powerSupply = "500W 80+ Bronze";
private String coolingSystem = "风冷";
private boolean hasBluetooth = false;
private boolean hasWiFi = false;
// 必需参数的构造器
public Builder(String cpu, String motherboard, String memory) {
this.cpu = cpu;
this.motherboard = motherboard;
this.memory = memory;
}
// 可选参数设置方法
public Builder storage(String storage) {
this.storage = storage;
return this;
}
public Builder gpu(String gpu) {
this.gpu = gpu;
return this;
}
public Builder powerSupply(String powerSupply) {
this.powerSupply = powerSupply;
return this;
}
public Builder coolingSystem(String coolingSystem) {
this.coolingSystem = coolingSystem;
return this;
}
public Builder hasBluetooth(boolean hasBluetooth) {
this.hasBluetooth = hasBluetooth;
return this;
}
public Builder hasWiFi(boolean hasWiFi) {
this.hasWiFi = hasWiFi;
return this;
}
// 构建方法
public Computer build() {
return new Computer(this);
}
}
}
// 使用示例
public static void main(String[] args) {
// 构建基础版电脑
Computer basicComputer = new Computer.Builder("Intel i5", "B660", "16GB DDR4")
.build();
System.out.println("基础版电脑:");
System.out.println(basicComputer);
System.out.println("\n" + "=".repeat(50) + "\n");
// 构建游戏电脑
Computer gamingComputer = new Computer.Builder("Intel i9", "Z790", "32GB DDR5")
.storage("2TB NVMe SSD")
.gpu("NVIDIA RTX 4080")
.powerSupply("850W 80+ Gold")
.coolingSystem("360mm水冷")
.hasBluetooth(true)
.hasWiFi(true)
.build();
System.out.println("游戏电脑:");
System.out.println(gamingComputer);
System.out.println("\n" + "=".repeat(50) + "\n");
// 构建办公电脑
Computer officeComputer = new Computer.Builder("AMD Ryzen 7", "B650", "32GB DDR4")
.storage("1TB SSD")
.gpu("集成显卡")
.hasWiFi(true)
.build();
System.out.println("办公电脑:");
System.out.println(officeComputer);
}
}
实际应用:HTTP请求构建器
java
// HTTP请求构建器
public class HttpRequestBuilder {
// HTTP请求类
static class HttpRequest {
private final String url;
private final HttpMethod method;
private final Map<String, String> headers;
private final Map<String, String> queryParams;
private final String body;
private final int timeout;
private final boolean followRedirects;
private final SSLContext sslContext;
private HttpRequest(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = Collections.unmodifiableMap(builder.headers);
this.queryParams = Collections.unmodifiableMap(builder.queryParams);
this.body = builder.body;
this.timeout = builder.timeout;
this.followRedirects = builder.followRedirects;
this.sslContext = builder.sslContext;
}
public void execute() {
System.out.println("执行HTTP请求:");
System.out.println(" URL: " + url);
System.out.println(" 方法: " + method);
System.out.println(" 请求头: " + headers);
System.out.println(" 查询参数: " + queryParams);
System.out.println(" 请求体: " + (body != null ? body.substring(0, Math.min(50, body.length())) : "null"));
System.out.println(" 超时: " + timeout + "ms");
System.out.println(" 跟随重定向: " + followRedirects);
// 实际执行HTTP请求的代码...
}
// 获取完整URL(包含查询参数)
public String getFullUrl() {
if (queryParams.isEmpty()) {
return url;
}
StringBuilder urlBuilder = new StringBuilder(url);
urlBuilder.append("?");
boolean first = true;
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
if (!first) {
urlBuilder.append("&");
}
urlBuilder.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8))
.append("=")
.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
first = false;
}
return urlBuilder.toString();
}
// 建造者类
static class Builder {
private final String url;
private HttpMethod method = HttpMethod.GET;
private Map<String, String> headers = new HashMap<>();
private Map<String, String> queryParams = new HashMap<>();
private String body;
private int timeout = 10000; // 默认10秒
private boolean followRedirects = true;
private SSLContext sslContext;
public Builder(String url) {
this.url = url;
// 设置默认请求头
headers.put("User-Agent", "HttpRequestBuilder/1.0");
headers.put("Accept", "application/json");
}
public Builder method(HttpMethod method) {
this.method = method;
return this;
}
public Builder header(String name, String value) {
this.headers.put(name, value);
return this;
}
public Builder headers(Map<String, String> headers) {
this.headers.putAll(headers);
return this;
}
public Builder queryParam(String name, String value) {
this.queryParams.put(name, value);
return this;
}
public Builder queryParams(Map<String, String> params) {
this.queryParams.putAll(params);
return this;
}
public Builder body(String body) {
this.body = body;
if (body != null && !headers.containsKey("Content-Type")) {
headers.put("Content-Type", "application/json");
}
return this;
}
public Builder timeout(int timeout) {
this.timeout = timeout;
return this;
}
public Builder followRedirects(boolean followRedirects) {
this.followRedirects = followRedirects;
return this;
}
public Builder sslContext(SSLContext sslContext) {
this.sslContext = sslContext;
return this;
}
public HttpRequest build() {
// 验证必要参数
if (url == null || url.trim().isEmpty()) {
throw new IllegalArgumentException("URL不能为空");
}
// 如果是POST/PUT请求且有body,确保Content-Type已设置
if ((method == HttpMethod.POST || method == HttpMethod.PUT) && body != null) {
if (!headers.containsKey("Content-Type")) {
throw new IllegalArgumentException("POST/PUT请求必须设置Content-Type");
}
}
return new HttpRequest(this);
}
}
}
// HTTP方法枚举
enum HttpMethod {
GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
}
// 使用示例
public static void main(String[] args) {
// 构建简单的GET请求
HttpRequest getRequest = new HttpRequest.Builder("https://api.example.com/users")
.method(HttpMethod.GET)
.queryParam("page", "1")
.queryParam("limit", "10")
.header("Authorization", "Bearer token123")
.timeout(5000)
.build();
getRequest.execute();
System.out.println("完整URL: " + getRequest.getFullUrl());
System.out.println("\n" + "=".repeat(50) + "\n");
// 构建复杂的POST请求
String jsonBody = "{"name":"John","email":"john@example.com"}";
HttpRequest postRequest = new HttpRequest.Builder("https://api.example.com/users")
.method(HttpMethod.POST)
.header("Authorization", "Bearer token123")
.header("Content-Type", "application/json")
.body(jsonBody)
.timeout(15000)
.followRedirects(false)
.build();
postRequest.execute();
}
}
原型模式:克隆对象
问题场景
当创建对象的成本较高(如需要复杂的数据库查询、网络请求),或者需要创建大量相似对象时,使用原型模式可以提高性能。
基本实现
java
public class PrototypePattern {
// 原型接口
interface Prototype<T> extends Cloneable {
T clone() throws CloneNotSupportedException;
T deepClone();
}
// 具体原型:简历
static class Resume implements Prototype<Resume> {
private String name;
private String email;
private String phone;
private WorkExperience workExperience;
private List<String> skills;
public Resume(String name, String email, String phone) {
this.name = name;
this.email = email;
this.phone = phone;
this.workExperience = new WorkExperience();
this.skills = new ArrayList<>();
}
// 设置工作经验
public void setWorkExperience(String company, String position, Date startDate, Date endDate) {
this.workExperience = new WorkExperience(company, position, startDate, endDate);
}
// 添加技能
public void addSkill(String skill) {
skills.add(skill);
}
@Override
public String toString() {
return "简历信息:\n" +
" 姓名: " + name + "\n" +
" 邮箱: " + email + "\n" +
" 电话: " + phone + "\n" +
" 工作经验: " + workExperience + "\n" +
" 技能: " + skills;
}
// 浅克隆(使用Java的clone方法)
@Override
public Resume clone() throws CloneNotSupportedException {
return (Resume) super.clone();
}
// 深克隆
@Override
public Resume deepClone() {
Resume cloned = new Resume(this.name, this.email, this.phone);
// 克隆工作经验(WorkExperience也需要实现深克隆)
cloned.workExperience = this.workExperience.clone();
// 克隆技能列表
cloned.skills = new ArrayList<>(this.skills);
return cloned;
}
// 修改姓名(用于测试克隆是否成功)
public void setName(String name) {
this.name = name;
}
}
// 工作经验类(也需要实现克隆)
static class WorkExperience implements Cloneable {
private String company;
private String position;
private Date startDate;
private Date endDate;
public WorkExperience() {
// 默认构造器
}
public WorkExperience(String company, String position, Date startDate, Date endDate) {
this.company = company;
this.position = position;
this.startDate = (Date) startDate.clone();
this.endDate = (Date) endDate.clone();
}
@Override
public String toString() {
return company + " - " + position + " (" + startDate + " 至 " + endDate + ")";
}
@Override
public WorkExperience clone() {
try {
WorkExperience cloned = (WorkExperience) super.clone();
// Date是可变的,需要深克隆
cloned.startDate = (Date) this.startDate.clone();
cloned.endDate = (Date) this.endDate.clone();
return cloned;
} catch (CloneNotSupportedException e) {
throw new RuntimeException("克隆失败", e);
}
}
}
// 原型管理器
static class PrototypeManager {
private static final Map<String, Prototype<?>> prototypes = new HashMap<>();
static {
// 预置一些原型
Resume defaultResume = new Resume("张三", "zhangsan@example.com", "13800138000");
defaultResume.setWorkExperience("ABC公司", "Java开发",
new Date(121, 0, 1), new Date(123, 11, 31));
defaultResume.addSkill("Java");
defaultResume.addSkill("Spring");
defaultResume.addSkill("MySQL");
prototypes.put("defaultResume", defaultResume);
// 可以添加更多原型...
}
public static void registerPrototype(String key, Prototype<?> prototype) {
prototypes.put(key, prototype);
}
@SuppressWarnings("unchecked")
public static <T extends Prototype<T>> T getPrototype(String key) {
Prototype<T> prototype = (Prototype<T>) prototypes.get(key);
if (prototype == null) {
throw new IllegalArgumentException("未找到原型: " + key);
}
return prototype.clone();
}
}
// 使用示例
public static void main(String[] args) throws CloneNotSupportedException {
System.out.println("=== 直接克隆示例 ===");
// 创建原始简历
Resume original = new Resume("李四", "lisi@example.com", "13900139000");
original.setWorkExperience("XYZ公司", "高级开发",
new Date(120, 0, 1), new Date(122, 11, 31));
original.addSkill("Python");
original.addSkill("Django");
System.out.println("原始简历:");
System.out.println(original);
// 浅克隆
Resume shallowClone = original.clone();
shallowClone.setName("王五"); // 修改克隆体的名字
System.out.println("\n浅克隆后:");
System.out.println("原始简历: " + original.name);
System.out.println("克隆简历: " + shallowClone.name);
// 深克隆
Resume deepClone = original.deepClone();
deepClone.setName("赵六");
System.out.println("\n深克隆后:");
System.out.println("原始简历: " + original.name);
System.out.println("深克隆简历: " + deepClone.name);
System.out.println("\n=== 原型管理器示例 ===");
// 使用原型管理器获取原型并克隆
Resume templateResume = PrototypeManager.getPrototype("defaultResume");
System.out.println("模板简历:");
System.out.println(templateResume);
// 基于模板创建个性化简历
Resume myResume = templateResume.deepClone();
myResume.setName("陈七");
myResume.addSkill("Redis");
myResume.addSkill("Docker");
System.out.println("\n个性化简历:");
System.out.println(myResume);
// 注册新原型
Resume newTemplate = new Resume("新模板", "template@example.com", "10000000000");
newTemplate.setWorkExperience("模板公司", "模板职位",
new Date(120, 0, 1), new Date(123, 11, 31));
newTemplate.addSkill("模板技能1");
newTemplate.addSkill("模板技能2");
PrototypeManager.registerPrototype("newTemplate", newTemplate);
System.out.println("\n新模板已注册");
}
}
实际应用:图形编辑器
java
// 图形编辑器原型模式实现
public class GraphicEditorPrototype {
// 图形接口
interface Graphic extends Cloneable {
void draw(int x, int y);
Graphic clone();
String getType();
void setColor(String color);
}
// 具体图形:圆形
static class Circle implements Graphic {
private String color;
private int radius;
public Circle(String color, int radius) {
this.color = color;
this.radius = radius;
}
@Override
public void draw(int x, int y) {
System.out.printf("在(%d, %d)绘制%s圆形,半径%d%n", x, y, color, radius);
}
@Override
public Circle clone() {
try {
return (Circle) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("克隆失败", e);
}
}
@Override
public String getType() {
return "圆形";
}
@Override
public void setColor(String color) {
this.color = color;
}
public void setRadius(int radius) {
this.radius = radius;
}
}
// 具体图形:矩形
static class Rectangle implements Graphic {
private String color;
private int width;
private int height;
public Rectangle(String color, int width, int height) {
this.color = color;
this.width = width;
this.height = height;
}
@Override
public void draw(int x, int y) {
System.out.printf("在(%d, %d)绘制%s矩形,宽%d,高%d%n", x, y, color, width, height);
}
@Override
public Rectangle clone() {
try {
return (Rectangle) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("克隆失败", e);
}
}
@Override
public String getType() {
return "矩形";
}
@Override
public void setColor(String color) {
this.color = color;
}
public void setSize(int width, int height) {
this.width = width;
this.height = height;
}
}
// 图形工厂(使用原型模式)
static class GraphicFactory {
private final Map<String, Graphic> prototypes = new HashMap<>();
public GraphicFactory() {
// 初始化原型
prototypes.put("红色小圆", new Circle("红色", 10));
prototypes.put("蓝色大圆", new Circle("蓝色", 50));
prototypes.put("绿色矩形", new Rectangle("绿色", 30, 40));
prototypes.put("黄色正方形", new Rectangle("黄色", 25, 25));
}
public void registerPrototype(String name, Graphic prototype) {
prototypes.put(name, prototype);
}
public Graphic createGraphic(String name) {
Graphic prototype = prototypes.get(name);
if (prototype == null) {
throw new IllegalArgumentException("未知的图形类型: " + name);
}
return prototype.clone();
}
public List<String> getAvailableGraphics() {
return new ArrayList<>(prototypes.keySet());
}
}
// 图形编辑器
static class GraphicEditor {
private final GraphicFactory factory;
private final List<Graphic> graphics = new ArrayList<>();
public GraphicEditor(GraphicFactory factory) {
this.factory = factory;
}
public void addGraphic(String type, int x, int y) {
Graphic graphic = factory.createGraphic(type);
graphic.draw(x, y);
graphics.add(graphic);
}
public void addCustomGraphic(Graphic graphic, int x, int y) {
graphic.draw(x, y);
graphics.add(graphic);
}
public void changeColor(int index, String newColor) {
if (index >= 0 && index < graphics.size()) {
graphics.get(index).setColor(newColor);
System.out.println("第" + (index + 1) + "个图形颜色改为" + newColor);
}
}
public void listAllGraphics() {
System.out.println("\n当前所有图形:");
for (int i = 0; i < graphics.size(); i++) {
System.out.println((i + 1) + ". " + graphics.get(i).getType());
}
}
}
// 使用示例
public static void main(String[] args) {
GraphicFactory factory = new GraphicFactory();
GraphicEditor editor = new GraphicEditor(factory);
System.out.println("可用的图形类型: " + factory.getAvailableGraphics());
System.out.println("\n=== 添加预设图形 ===");
editor.addGraphic("红色小圆", 10, 20);
editor.addGraphic("蓝色大圆", 50, 60);
editor.addGraphic("绿色矩形", 100, 120);
System.out.println("\n=== 创建自定义图形 ===");
// 创建自定义图形并注册为原型
Circle customCircle = new Circle("紫色", 15);
factory.registerPrototype("紫色中圆", customCircle);
editor.addGraphic("紫色中圆", 150, 80);
System.out.println("\n=== 克隆并修改图形 ===");
// 获取原型并修改
Graphic clonedCircle = factory.createGraphic("红色小圆");
if (clonedCircle instanceof Circle) {
((Circle) clonedCircle).setRadius(20); // 修改半径
((Circle) clonedCircle).setColor("橙色"); // 修改颜色
editor.addCustomGraphic(clonedCircle, 200, 100);
}
editor.listAllGraphics();
System.out.println("\n=== 修改现有图形颜色 ===");
editor.changeColor(0, "粉红色");
editor.changeColor(2, "深绿色");
}
}
模式选择指南:何时使用哪种创建型模式
决策流程图
java
开始
│
├── 是否需要确保只有一个实例?
│ ├── 是 → 使用单例模式
│ └── 否 → 继续
│
├── 创建过程是否复杂,需要逐步构建?
│ ├── 是 → 使用建造者模式
│ └── 否 → 继续
│
├── 是否需要创建一系列相关对象?
│ ├── 是 → 使用抽象工厂模式
│ └── 否 → 继续
│
├── 创建逻辑是否需要封装,以便子类决定具体类型?
│ ├── 是 → 使用工厂方法模式
│ └── 否 → 继续
│
└── 是否需要通过克隆现有对象来创建新对象?
├── 是 → 使用原型模式
└── 否 → 直接使用 new 关键字
实际项目中的综合应用
java
// 电子商务系统中的创建型模式综合应用
public class ECommerceSystem {
// 使用单例模式:购物车服务
static class ShoppingCartService {
private static ShoppingCartService instance;
private final Map<String, List<Product>> userCarts = new ConcurrentHashMap<>();
private ShoppingCartService() {
// 私有构造器
}
public static synchronized ShoppingCartService getInstance() {
if (instance == null) {
instance = new ShoppingCartService();
}
return instance;
}
public void addToCart(String userId, Product product) {
userCarts.computeIfAbsent(userId, k -> new ArrayList<>()).add(product);
System.out.println("用户 " + userId + " 添加商品: " + product.getName());
}
public List<Product> getCart(String userId) {
return userCarts.getOrDefault(userId, new ArrayList<>());
}
}
// 使用工厂方法模式:支付方式工厂
interface PaymentMethod {
boolean pay(double amount);
String getType();
}
static class CreditCardPayment implements PaymentMethod {
@Override
public boolean pay(double amount) {
System.out.println("信用卡支付: " + amount);
return true;
}
@Override
public String getType() {
return "信用卡";
}
}
static class PayPalPayment implements PaymentMethod {
@Override
public boolean pay(double amount) {
System.out.println("PayPal支付: " + amount);
return true;
}
@Override
public String getType() {
return "PayPal";
}
}
interface PaymentFactory {
PaymentMethod createPayment();
}
static class CreditCardFactory implements PaymentFactory {
@Override
public PaymentMethod createPayment() {
return new CreditCardPayment();
}
}
static class PayPalFactory implements PaymentFactory {
@Override
public PaymentMethod createPayment() {
return new PayPalPayment();
}
}
// 使用建造者模式:订单构建
static class Order {
private final String orderId;
private final String userId;
private final List<Product> products;
private final PaymentMethod payment;
private final ShippingAddress address;
private final Date orderDate;
private final OrderStatus status;
private Order(Builder builder) {
this.orderId = builder.orderId;
this.userId = builder.userId;
this.products = builder.products;
this.payment = builder.payment;
this.address = builder.address;
this.orderDate = builder.orderDate;
this.status = builder.status;
}
static class Builder {
private final String orderId;
private final String userId;
private List<Product> products = new ArrayList<>();
private PaymentMethod payment;
private ShippingAddress address;
private Date orderDate = new Date();
private OrderStatus status = OrderStatus.PENDING;
public Builder(String orderId, String userId) {
this.orderId = orderId;
this.userId = userId;
}
public Builder products(List<Product> products) {
this.products = products;
return this;
}
public Builder payment(PaymentMethod payment) {
this.payment = payment;
return this;
}
public Builder address(ShippingAddress address) {
this.address = address;
return this;
}
public Builder orderDate(Date orderDate) {
this.orderDate = orderDate;
return this;
}
public Builder status(OrderStatus status) {
this.status = status;
return this;
}
public Order build() {
// 验证
if (payment == null) {
throw new IllegalStateException("支付方式必须设置");
}
if (address == null) {
throw new IllegalStateException("收货地址必须设置");
}
if (products.isEmpty()) {
throw new IllegalStateException("订单商品不能为空");
}
return new Order(this);
}
}
}
// 使用抽象工厂模式:不同国家的电商工厂
interface ECommerceFactory {
TaxCalculator createTaxCalculator();
ShippingCalculator createShippingCalculator();
CurrencyFormatter createCurrencyFormatter();
}
static class USFactory implements ECommerceFactory {
@Override
public TaxCalculator createTaxCalculator() {
return new USTaxCalculator();
}
@Override
public ShippingCalculator createShippingCalculator() {
return new USShippingCalculator();
}
@Override
public CurrencyFormatter createCurrencyFormatter() {
return new USDCurrencyFormatter();
}
}
static class CNFactory implements ECommerceFactory {
@Override
public TaxCalculator createTaxCalculator() {
return new CNTaxCalculator();
}
@Override
public ShippingCalculator createShippingCalculator() {
return new CNShippingCalculator();
}
@Override
public CurrencyFormatter createCurrencyFormatter() {
return new CNYCurrencyFormatter();
}
}
// 辅助类(省略具体实现)
interface TaxCalculator {
double calculateTax(double amount);
}
static class USTaxCalculator implements TaxCalculator {
@Override
public double calculateTax(double amount) {
return amount * 0.08; // 8%税率
}
}
static class CNTaxCalculator implements TaxCalculator {
@Override
public double calculateTax(double amount) {
return amount * 0.06; // 6%税率
}
}
interface ShippingCalculator {
double calculateShipping(double weight, String address);
}
static class USShippingCalculator implements ShippingCalculator {
@Override
public double calculateShipping(double weight, String address) {
return weight * 2.5; // 美国运费计算
}
}
static class CNShippingCalculator implements ShippingCalculator {
@Override
public double calculateShipping(double weight, String address) {
return weight * 1.5; // 中国运费计算
}
}
interface CurrencyFormatter {
String format(double amount);
}
static class USDCurrencyFormatter implements CurrencyFormatter {
@Override
public String format(double amount) {
return String.format("$%.2f", amount);
}
}
static class CNYCurrencyFormatter implements CurrencyFormatter {
@Override
public String format(double amount) {
return String.format("¥%.2f", amount);
}
}
// 实体类
static class Product {
private String id;
private String name;
private double price;
// 其他属性...
// getter/setter省略
}
static class ShippingAddress {
private String address;
// 其他属性...
// getter/setter省略
}
enum OrderStatus {
PENDING, PROCESSING, SHIPPED, DELIVERED, CANCELLED
}
// 客户端代码
public static void main(String[] args) {
System.out.println("=== 电子商务系统演示 ===");
// 1. 使用单例模式:购物车服务
ShoppingCartService cartService = ShoppingCartService.getInstance();
cartService.addToCart("user123", new Product());
// 2. 使用工厂方法模式:创建支付方式
PaymentFactory paymentFactory = new CreditCardFactory();
PaymentMethod payment = paymentFactory.createPayment();
// 3. 使用建造者模式:创建订单
Order order = new Order.Builder("ORD123", "user123")
.products(cartService.getCart("user123"))
.payment(payment)
.address(new ShippingAddress())
.status(OrderStatus.PROCESSING)
.build();
System.out.println("订单创建成功: " + order);
// 4. 使用抽象工厂模式:根据不同地区创建相关对象
String country = "US"; // 可以从用户配置获取
ECommerceFactory factory;
if ("US".equals(country)) {
factory = new USFactory();
} else {
factory = new CNFactory();
}
TaxCalculator taxCalculator = factory.createTaxCalculator();
ShippingCalculator shippingCalculator = factory.createShippingCalculator();
CurrencyFormatter currencyFormatter = factory.createCurrencyFormatter();
double subtotal = 100.0;
double tax = taxCalculator.calculateTax(subtotal);
double shipping = shippingCalculator.calculateShipping(2.0, "New York");
double total = subtotal + tax + shipping;
System.out.println("小计: " + currencyFormatter.format(subtotal));
System.out.println("税费: " + currencyFormatter.format(tax));
System.out.println("运费: " + currencyFormatter.format(shipping));
System.out.println("总计: " + currencyFormatter.format(total));
}
}
总结:创建型模式的核心思想
- 单例模式:控制实例数量,确保全局唯一访问点
- 工厂方法模式:将对象的创建延迟到子类,实现开闭原则
- 抽象工厂模式:创建相关对象族,确保产品兼容性
- 建造者模式:分离复杂对象的构建与表示,支持逐步构建
- 原型模式:通过克隆创建对象,提高创建效率
设计原则体现
- 单一职责原则:每个类只负责自己的创建逻辑
- 开闭原则:通过扩展而非修改来支持新的对象类型
- 依赖倒置原则:依赖抽象而非具体实现
- 里氏替换原则:子类可以替换父类