gpt4 book ai didi

java - 如何仅在构造函数中初始化变量一次?

转载 作者:行者123 更新时间:2023-12-01 14:28:59 26 4
gpt4 key购买 nike

我有一个构建器模式,我从客户那里获取一些参数,并以此为基础构建我的构建器类,然后将该构建器类传递给我们的底层库,然后我的库将使用它。

public final class KeyHolder {
private final String clientId;
private final String deviceId;
private final int processId;
private final Cache<String, List<Response>> userCache;
private static final long MAXIMUM_CACHE_SIZE = 5000000;
private static final long EXPIRE_AFTER_WRITE = 120; // this is in seconds

private KeyHolder(Builder builder) {
this.clientId = builder.clientId;
this.deviceId = builder.deviceId;
this.processId = builder.processId;
this.maximumCacheSize = builder.maximumCacheSize;
this.expireAfterWrite = builder.expireAfterWrite;

// how to execute this line only once
this.userCache =
CacheBuilder
.newBuilder()
.maximumSize(maximumCacheSize)
.expireAfterWrite(expireAfterWrite, TimeUnit.SECONDS)
.removalListener(
RemovalListeners.asynchronous(new CustomListener(),
Executors.newSingleThreadScheduledExecutor())).build();

}

public static class Builder {
protected final int processId;
protected String clientId = null;
protected String deviceId = null;
protected long maximumCacheSize = MAXIMUM_CACHE_SIZE;
protected long expireAfterWrite = EXPIRE_AFTER_WRITE;


public Builder(int processId) {
this.processId = processId;
}

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

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

public Builder setMaximumCacheSize(long size) {
this.maximumCacheSize = size;
return this;
}

public Builder setExpiryTimeAfterWrite(long duration) {
this.expireAfterWrite = duration;
return this;
}

public KeyHolder build() {
return new KeyHolder(this);
}
}

// getters here
}

对于我们图书馆的每一次调用,他们都会创建一个新的 KeyHolder builder 类每次都传递给我们的图书馆。 processId , clientId , deviceId每次调用都会改变,但 maximumCacheSizeexpireAfterWrite每次通话都会保持不变。正如你在上面看到的,我在这里使用 Guava 缓存,因为他们正在创建 KeyHolder builder 类每次如何确保以下行在我的构造函数中只执行一次?
    this.userCache =
CacheBuilder
.newBuilder()
.maximumSize(maximumCacheSize)
.expireAfterWrite(expireAfterWrite, TimeUnit.SECONDS)
.removalListener(
RemovalListeners.asynchronous(new CustomListener(),
Executors.newSingleThreadScheduledExecutor())).build();

由于现在使用当前代码,每次调用都会执行它,并且每次我都会在我的库中获得一个新的 Guava 缓存,因此之前使用此 Guava 缓存在我的库中缓存的任何条目都将丢失。

如何仅初始化特定变量一次,然后它应该忽略传递给它的值?

更新:
public class DataClient implements Client {
private final ExecutorService executor = Executors.newFixedThreadPool(10);

// for synchronous call
@Override
public List<Response> executeSync(KeyHolder key) {
Cache<String, List<Response>> userCache = key.getUserCache();
List<Response> response = userCache.getIfPresent(key.getUUID());
if (CollectionUtils.isNotEmpty(response)) {
return response;
}
// if not in cache, then normally call the flow and populate the cache
List<Response> dataResponse = null;
Future<List<Response>> future = null;
try {
future = executeAsync(key);
dataResponse = future.get(key.getTimeout(), TimeUnit.MILLISECONDS);
userCache.put(key.getUUID(), dataResponse);
} catch (TimeoutException ex) {
// log error and return DataResponse
} catch (Exception ex) {
// log error and return DataResponse
}

return dataResponse;
}
}

最佳答案

如果只想设置一次缓存,为什么每次KeuHolder object 试图建立它吗?事实上,即使KeyHolder#Builder公开方法来帮助构建缓存,这只会有用一次。

这是非常值得怀疑的。如果第一个怎么办 KeyHolder没有指定缓存详细信息?我的意思是,它不是被迫的(您没有正确使用构建器模式,最后会详细介绍)。

解决此问题的第一步是确保在开始创建 KeyHolder 之前设置缓存。对象的。您可以通过创建一个静态工厂并制作 userCache 来做到这一点。静止的:

class KeyHolder {
private static Map<String, List<Response>> userCache;

public static KeyHolder.Builder newBuilder(int id) {
if(userCache == null) {
userCache = ...;
}

return new Builder(id);
}
}

但正如您可能已经从我的评论中读到的,这只是针对这个问题的创可贴。每次我们想要创建一个新的 KeyHolder 时都会检查 userCache ,这不应该发生。

相反,您应该将缓存与 KeyHolder 分离。全部一起。为什么它需要知道缓存呢?

您的缓存属于 DataClient :
class DataClient {
private Map<String, List<Response>> userCache;

public List<Response> executeSync(KeyHolder key) {
List<Response> response = userCache.getIfPresent(key.getUUID());
//...
}
}

您可以通过 DataClient 接受设置构造函数,或者将缓存传递给 DataClient使用已经指定的设置。

至于您对构建器模式的使用,请记住我们使用它的原因:Java 缺少可选参数。

这就是构建器常见的原因:它们允许我们通过方法指定可选数据。

您将关键信息(例如缓存设置)指定为可选参数(构建器方法)。如果您不需要这些信息,您应该只使用构建器方法,并且缓存信息绝对是应该需要的。我会质疑如何可选 deviceIdclientId也是如此,看看唯一需要的数据是 productId .

关于java - 如何仅在构造函数中初始化变量一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42101665/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com