← 返回首页

Java创建型模式详解:单例、工厂、建造者

📂 java ⏱ 4 min 634 words

Java创建型模式详解

单例模式(Singleton)

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

双重检查锁定

public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

枚举单例(推荐)

public enum Singleton {
    INSTANCE;

    private int count;

    public void doSomething() {
        count++;
        System.out.println("执行操作, count=" + count);
    }
}

// 使用
Singleton.INSTANCE.doSomething();

静态内部类

public class Singleton {
    private Singleton() {}

    private static class Holder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return Holder.INSTANCE;
    }
}

工厂方法模式(Factory Method)

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

public interface Notification {
    void send(String message);
}

public class EmailNotification implements Notification {
    @Override
    public void send(String message) {
        System.out.println("发送邮件: " + message);
    }
}

public class SmsNotification implements Notification {
    @Override
    public void send(String message) {
        System.out.println("发送短信: " + message);
    }
}

public abstract class NotificationFactory {
    protected abstract Notification createNotification();

    public void notify(String message) {
        Notification notification = createNotification();
        notification.send(message);
    }
}

public class EmailFactory extends NotificationFactory {
    @Override
    protected Notification createNotification() {
        return new EmailNotification();
    }
}

public class SmsFactory extends NotificationFactory {
    @Override
    protected Notification createNotification() {
        return new SmsNotification();
    }
}

抽象工厂模式(Abstract Factory)

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

public interface Button {
    void render();
}

public interface TextBox {
    void render();
}

public class WindowsButton implements Button {
    @Override
    public void render() { System.out.println("渲染Windows按钮"); }
}

public class WindowsTextBox implements TextBox {
    @Override
    public void render() { System.out.println("渲染Windows文本框"); }
}

public class MacButton implements Button {
    @Override
    public void render() { System.out.println("渲染Mac按钮"); }
}

public class MacTextBox implements TextBox {
    @Override
    public void render() { System.out.println("渲染Mac文本框"); }
}

public interface GUIFactory {
    Button createButton();
    TextBox createTextBox();
}

public class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() { return new WindowsButton(); }
    @Override
    public TextBox createTextBox() { return new WindowsTextBox(); }
}

public class MacFactory implements GUIFactory {
    @Override
    public Button createButton() { return new MacButton(); }
    @Override
    public TextBox createTextBox() { return new MacTextBox(); }
}

public class Application {
    private Button button;
    private TextBox textBox;

    public Application(GUIFactory factory) {
        button = factory.createButton();
        textBox = factory.createTextBox();
    }

    public void render() {
        button.render();
        textBox.render();
    }
}

// 使用
GUIFactory factory = new WindowsFactory();
Application app = new Application(factory);
app.render();

建造者模式(Builder)

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

public class HttpRequest {
    private final String url;
    private final String method;
    private final Map<String, String> headers;
    private final String body;
    private final int timeout;

    private HttpRequest(Builder builder) {
        this.url = builder.url;
        this.method = builder.method;
        this.headers = builder.headers;
        this.body = builder.body;
        this.timeout = builder.timeout;
    }

    public static class Builder {
        private final String url;
        private String method = "GET";
        private Map<String, String> headers = new HashMap<>();
        private String body;
        private int timeout = 3000;

        public Builder(String url) { this.url = url; }

        public Builder method(String method) {
            this.method = method;
            return this;
        }

        public Builder header(String key, String value) {
            headers.put(key, value);
            return this;
        }

        public Builder body(String body) {
            this.body = body;
            return this;
        }

        public Builder timeout(int timeout) {
            this.timeout = timeout;
            return this;
        }

        public HttpRequest build() {
            if (url == null || url.isBlank()) {
                throw new IllegalArgumentException("URL不能为空");
            }
            return new HttpRequest(this);
        }
    }
}

// 使用
HttpRequest request = new HttpRequest.Builder("https://api.example.com")
    .method("POST")
    .header("Content-Type", "application/json")
    .body("{\"name\": \"test\"}")
    .timeout(5000)
    .build();

原型模式(Prototype)

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

public class Document implements Cloneable {
    private String title;
    private String content;
    private List<String> attachments;

    public Document(String title, String content) {
        this.title = title;
        this.content = content;
        this.attachments = new ArrayList<>();
    }

    @Override
    public Document clone() {
        try {
            Document cloned = (Document) super.clone();
            cloned.attachments = new ArrayList<>(this.attachments);
            return cloned;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }

    public void addAttachment(String attachment) {
        attachments.add(attachment);
    }
}

// 使用
Document template = new Document("报告模板", "报告内容...");
template.addAttachment("logo.png");

Document report1 = template.clone();
report1.setTitle("月度报告");

Document report2 = template.clone();
report2.setTitle("季度报告");

总结

创建型模式的核心是解耦对象的创建和使用。单例保证唯一实例,工厂封装创建逻辑,建造者处理复杂对象构建,原型通过复制提高创建效率。根据场景选择合适的模式。