← 返回首页
🏗️

Java设计模式入门:单例、工厂与建造者模式

📂 java ⏱ 5 min 819 words

Java设计模式入门:单例、工厂与建造者模式

概述

设计模式是软件开发中经过验证的解决方案模板。它们提供了处理常见设计问题的最佳实践。本教程介绍三种最常用的设计模式。

1. 单例模式

单例模式确保一个类只有一个实例,并提供全局访问点。

饿汉式

public class SingletonHungry {
    // 类加载时就创建实例
    private static final SingletonHungry INSTANCE = new SingletonHungry();
    
    // 私有构造方法
    private SingletonHungry() {}
    
    // 获取实例
    public static SingletonHungry getInstance() {
        return INSTANCE;
    }
    
    public void doSomething() {
        System.out.println("单例方法执行");
    }
    
    public static void main(String[] args) {
        SingletonHungry s1 = SingletonHungry.getInstance();
        SingletonHungry s2 = SingletonHungry.getInstance();
        
        System.out.println("s1 == s2: " + (s1 == s2));
        s1.doSomething();
    }
}

懒汉式(线程安全)

public class SingletonLazy {
    private static volatile SingletonLazy instance;
    
    private SingletonLazy() {}
    
    public static SingletonLazy getInstance() {
        if (instance == null) {
            synchronized (SingletonLazy.class) {
                if (instance == null) {
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }
    
    public void doSomething() {
        System.out.println("懒汉式单例执行");
    }
}

枚举单例

public enum SingletonEnum {
    INSTANCE;
    
    public void doSomething() {
        System.out.println("枚举单例执行");
    }
    
    public static void main(String[] args) {
        SingletonEnum.INSTANCE.doSomething();
    }
}

2. 工厂模式

工厂模式定义了一个创建对象的接口,让子类决定实例化哪个类。

简单工厂

public interface Shape {
    void draw();
}

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("画圆形");
    }
}

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("画矩形");
    }
}

public class Triangle implements Shape {
    @Override
    public void draw() {
        System.out.println("画三角形");
    }
}

public class ShapeFactory {
    public static Shape createShape(String type) {
        switch (type.toLowerCase()) {
            case "circle":
                return new Circle();
            case "rectangle":
                return new Rectangle();
            case "triangle":
                return new Triangle();
            default:
                throw new IllegalArgumentException("未知形状: " + type);
        }
    }
}

public class FactoryDemo {
    public static void main(String[] args) {
        Shape circle = ShapeFactory.createShape("circle");
        Shape rectangle = ShapeFactory.createShape("rectangle");
        Shape triangle = ShapeFactory.createShape("triangle");
        
        circle.draw();
        rectangle.draw();
        triangle.draw();
    }
}

工厂方法模式

public abstract class AbstractFactory {
    public abstract Shape createShape();
}

public class CircleFactory extends AbstractFactory {
    @Override
    public Shape createShape() {
        return new Circle();
    }
}

public class RectangleFactory extends AbstractFactory {
    @Override
    public Shape createShape() {
        return new Rectangle();
    }
}

public class FactoryMethodDemo {
    public static void main(String[] args) {
        AbstractFactory circleFactory = new CircleFactory();
        AbstractFactory rectangleFactory = new RectangleFactory();
        
        Shape circle = circleFactory.createShape();
        Shape rectangle = rectangleFactory.createShape();
        
        circle.draw();
        rectangle.draw();
    }
}

3. 建造者模式

建造者模式将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。

public class Computer {
    private String cpu;
    private String ram;
    private String storage;
    private String gpu;
    
    private Computer() {}
    
    // Getters
    public String getCpu() { return cpu; }
    public String getRam() { return ram; }
    public String getStorage() { return storage; }
    public String getGpu() { return gpu; }
    
    @Override
    public String toString() {
        return "Computer{cpu='" + cpu + "', ram='" + ram + "', storage='" + storage + "', gpu='" + gpu + "'}";
    }
    
    // 静态内部类Builder
    public static class Builder {
        private Computer computer = new Computer();
        
        public Builder cpu(String cpu) {
            computer.cpu = cpu;
            return this;
        }
        
        public Builder ram(String ram) {
            computer.ram = ram;
            return this;
        }
        
        public Builder storage(String storage) {
            computer.storage = storage;
            return this;
        }
        
        public Builder gpu(String gpu) {
            computer.gpu = gpu;
            return this;
        }
        
        public Computer build() {
            return computer;
        }
    }
}

public class BuilderDemo {
    public static void main(String[] args) {
        Computer gamingPC = new Computer.Builder()
            .cpu("Intel i9")
            .ram("32GB")
            .storage("1TB SSD")
            .gpu("RTX 4080")
            .build();
        
        Computer officePC = new Computer.Builder()
            .cpu("Intel i5")
            .ram("16GB")
            .storage("512GB SSD")
            .gpu("集成显卡")
            .build();
        
        System.out.println("游戏电脑: " + gamingPC);
        System.out.println("办公电脑: " + officePC);
    }
}

4. 实际应用示例

数据库连接工厂

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DatabaseFactory {
    private static final Map<String, String> DB_CONFIGS = new HashMap<>();
    
    static {
        DB_CONFIGS.put("mysql", "jdbc:mysql://localhost:3306/mydb");
        DB_CONFIGS.put("postgresql", "jdbc:postgresql://localhost:5432/mydb");
        DB_CONFIGS.put("h2", "jdbc:h2:mem:testdb");
    }
    
    public static Connection getConnection(String dbType) throws SQLException {
        String url = DB_CONFIGS.get(dbType);
        if (url == null) {
            throw new IllegalArgumentException("不支持的数据库类型: " + dbType);
        }
        return DriverManager.getConnection(url, "user", "password");
    }
}

// 使用示例
public class DatabaseDemo {
    public static void main(String[] args) {
        try {
            Connection conn = DatabaseFactory.getConnection("mysql");
            System.out.println("数据库连接成功");
        } catch (SQLException e) {
            System.out.println("连接失败: " + e.getMessage());
        }
    }
}

HTTP请求建造者

public class HttpRequest {
    private String url;
    private String method;
    private Map<String, String> headers;
    private String body;
    
    private HttpRequest() {}
    
    public String getUrl() { return url; }
    public String getMethod() { return method; }
    public Map<String, String> getHeaders() { return headers; }
    public String getBody() { return body; }
    
    @Override
    public String toString() {
        return method + " " + url + " Headers: " + headers + " Body: " + body;
    }
    
    public static class Builder {
        private HttpRequest request = new HttpRequest();
        
        public Builder url(String url) {
            request.url = url;
            return this;
        }
        
        public Builder method(String method) {
            request.method = method;
            return this;
        }
        
        public Builder header(String key, String value) {
            if (request.headers == null) {
                request.headers = new HashMap<>();
            }
            request.headers.put(key, value);
            return this;
        }
        
        public Builder body(String body) {
            request.body = body;
            return this;
        }
        
        public HttpRequest build() {
            return request;
        }
    }
}

public class HttpRequestDemo {
    public static void main(String[] args) {
        HttpRequest request = new HttpRequest.Builder()
            .url("https://api.example.com/users")
            .method("POST")
            .header("Content-Type", "application/json")
            .header("Authorization", "Bearer token123")
            .body("{\"name\": \"Alice\"}")
            .build();
        
        System.out.println("请求: " + request);
    }
}

5. 最佳实践

  1. 单例模式
    • 使用枚举单例最简单、最安全
    • 避免使用懒汉式(除非有特殊需求)
    • 注意序列化问题
  2. 工厂模式
    • 简单工厂适合简单场景
    • 工厂方法模式更灵活
    • 抽象工厂适合创建产品族
  3. 建造者模式
    • 适合创建复杂对象
    • 链式调用使代码更简洁
    • 可以进行参数验证

总结

设计模式是软件开发中的重要概念。掌握单例、工厂和建造者模式,可以帮助我们编写更灵活、更可维护的代码。在实际编程中,要根据需求选择合适的设计模式。