Skip to the content.
package com.bookshop.creational.singleton;

import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Shop-wide configuration as an enum singleton -- the simplest thread-safe,
 * serialization-proof way to guarantee exactly one instance (Effective Java, Item 3).
 */
public enum ShopConfig {

    INSTANCE;

    private final Map<String, Boolean> featureFlags = new ConcurrentHashMap<>();
    private volatile BigDecimal freeShippingThreshold = new BigDecimal("25.00");

    public String currency() {
        return "GBP";
    }

    public BigDecimal freeShippingThreshold() {
        return freeShippingThreshold;
    }

    public void freeShippingThreshold(BigDecimal threshold) {
        this.freeShippingThreshold = threshold;
    }

    public boolean isEnabled(String feature) {
        return featureFlags.getOrDefault(feature, false);
    }

    public void enable(String feature) {
        featureFlags.put(feature, true);
    }

    /** Test hook: singletons hold global state, so tests must be able to reset it. */
    public void reset() {
        featureFlags.clear();
        freeShippingThreshold = new BigDecimal("25.00");
    }
}

Raw file