延遲初始化與單例模式

Java 程式碼最佳化

Pavlos Kosmetatos

Lead Engineer @Wealthyhood

建立 Redis 快取用戶端

  • 想像你要建立一個連到 Redis 的快取用戶端
  • 我們的 Redis 用戶端託管在第三方供應商
  • 設定連線需要走網路呼叫——假設要花 500ms

$$

透過網路呼叫來建立 Redis 連線

Java 程式碼最佳化

簡單(積極初始化)的實作

public class RedisCache {
    // The client library we use to connect to Redis
    private final RedisClient client;

    public RedisCache() {
        // The connection is setup inside the constructor
        connection = new RedisClient("cache.mycompany.com");
    }
}
  • 以積極初始化方式建立 Redis 連線
Java 程式碼最佳化

此作法的潛在問題

看起來簡單、也能運作,但可能有個問題

如果根本不需要 Redis 用戶端呢?

  • 啟動時白白多花時間
  • 建立了不必要的連線
Java 程式碼最佳化

延遲初始化

public class RedisCache {
    private RedisClient client;

    // Instead of setting up the connection in the constructor,
    // we only set it up when someone needs to get the client.
    public RedisClient getClient() {
        if (connection == null) {
            connection = new RedisClient("cache.mycompany.com");
        }
        return connection;
    }
}
Java 程式碼最佳化

此作法的另一個問題

// UserService needs cache access
public class UserService {
    private RedisCache userCache = new RedisCache();  // First connection
}

// PaymentService also needs cache
public class PaymentService {
    private RedisCache paymentCache = new RedisCache();  // Second connection
}

// ...same for OrderService ...
Java 程式碼最佳化

單例模式

public class RedisCache {
    private static RedisCache instance;
    private RedisClient client;

    // The constructor is private so that we ensure we only
    // create RedisCache inside this class
    private RedisCache() {}

    public static RedisCache getInstance() 
        // We only create a RedisCache if one does not already exist
        if (instance == null) { instance = new RedisCache(); }
        return instance;
    }

    // ... The rest is the same as before ...
}
Java 程式碼最佳化

一起來練習吧!

Java 程式碼最佳化

Preparing Video For Download...