- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在使用 RestTemplate
作为我的 HttpClient
执行 URL,服务器将返回一个 json 字符串作为响应。客户将通过传递 DataKey
对象来调用此库,其中包含 userId
。
userId
,我将找出可以访问哪些机器来获取数据,然后将这些机器存储在 LinkedList
中,以便我可以按顺序执行。下面是我的 DataClient 类,客户将调用它,他们会将 DataKey
对象传递给 getData
方法。
public class DataClient implements Client {
private RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
private ExecutorService service = Executors.newFixedThreadPool(15);
public Future<DataResponse> getData(DataKey key) {
DataExecutorTask task = new DataExecutorTask(key, restTemplate);
Future<DataResponse> future = service.submit(task);
return future;
}
}
下面是我的 DataExecutorTask 类:
public class DataExecutorTask implements Callable<DataResponse> {
private DataKey key;
private RestTemplate restTemplate;
public DataExecutorTask(DataKey key, RestTemplate restTemplate) {
this.restTemplate = restTemplate;
this.key = key;
}
@Override
public DataResponse call() {
DataResponse dataResponse = null;
ResponseEntity<String> response = null;
MappingsHolder mappings = ShardMappings.getMappings(key.getTypeOfFlow());
// given a userId, find all the hostnames
// it can also have four hostname or one hostname or six hostname as well in the list
List<String> hostnames = mappings.getListOfHostnames(key.getUserId());
for (String hostname : hostnames) {
// If host name is null or host name is in local block list, skip sending request to this host
if (ClientUtils.isEmpty(hostname) || ShardMappings.isBlockHost(hostname)) {
continue;
}
try {
String url = generateURL(hostname);
response = restTemplate.exchange(url, HttpMethod.GET, key.getEntity(), String.class);
if (response.getStatusCode() == HttpStatus.NO_CONTENT) {
dataResponse = new DataResponse(response.getBody(), DataErrorEnum.NO_CONTENT,
DataStatusEnum.SUCCESS);
} else {
dataResponse = new DataResponse(response.getBody(), DataErrorEnum.OK,
DataStatusEnum.SUCCESS);
}
break;
// below codes are duplicated looks like
} catch (HttpClientErrorException ex) {
HttpStatusCodeException httpException = (HttpStatusCodeException) ex;
DataErrorEnum error = DataErrorEnum.getErrorEnumByException(httpException);
String errorMessage = httpException.getResponseBodyAsString();
dataResponse = new DataResponse(errorMessage, error, DataStatusEnum.ERROR);
return dataResponse;
} catch (HttpServerErrorException ex) {
HttpStatusCodeException httpException = (HttpStatusCodeException) ex;
DataErrorEnum error = DataErrorEnum.getErrorEnumByException(httpException);
String errorMessage = httpException.getResponseBodyAsString();
dataResponse = new DataResponse(errorMessage, error, DataStatusEnum.ERROR);
return dataResponse;
} catch (RestClientException ex) {
// if it comes here, then it means some of the servers are down so adding it into block list
ShardMappings.blockHost(hostname);
}
}
if (ClientUtils.isEmpty(hostnames)) {
dataResponse = new DataResponse(null, DataErrorEnum.PERT_ERROR, DataStatusEnum.ERROR);
} else if (response == null) { // either all the servers are down or all the servers were in block list
dataResponse = new DataResponse(null, DataErrorEnum.SERVICE_UNAVAILABLE, DataStatusEnum.ERROR);
}
return dataResponse;
}
}
我的阻止列表每 1 分钟从另一个后台线程更新一次。如果任何服务器关闭并且没有响应,那么我需要使用它来阻止该服务器 -
ShardMappings.blockHost(hostname);
为了检查任何服务器是否在阻止列表中,我使用它 -
ShardMappings.isBlockHost(hostname);
如果服务器关闭或在阻止列表中,我将返回 SERVICE_UNAVAILABLE
,基于 response == null
检查,不确定是否方法是否正确。
我想我根本没有遵循单一职责原则。谁能在这里举个例子,什么是使用 SRP 原则的最佳方式。
经过深思熟虑,我能够像下面给出的那样提取主机类,但不确定在我的上面使用它的最佳方法是什么 DataExecutorTask
类。
public class Hosts {
private final LinkedList<String> hostsnames = new LinkedList<String>();
public Hosts(final List<String> hosts) {
checkNotNull(hosts, "hosts cannot be null");
this.hostsnames.addAll(hosts);
}
public Optional<String> getNextAvailableHostname() {
while (!hostsnames.isEmpty()) {
String firstHostname = hostsnames.removeFirst();
if (!ClientUtils.isEmpty(firstHostname) && !ShardMappings.isBlockHost(firstHostname)) {
return Optional.of(firstHostname);
}
}
return Optional.absent();
}
public boolean isEmpty() {
return hostsnames.isEmpty();
}
}
最佳答案
您的担忧是有道理的。首先,我们来看看原始数据执行器是做什么的:
First, it is getting list of hostnames
Next, it loops through every hostnames that do the following things:
It checks whether the hostname is valid to send request.
If not valid: skip.
Else continue.
Generate the URL based on hostname
Send the request
Translate the request response to domain response
Handle exceptions
If the hostnames is empty, generate an empty response
Return response
现在,我们可以做些什么来遵循 SRP?正如我所看到的,我们可以将这些操作分组到一些组中。我可以看到的是,这些操作可以分为:
HostnameValidator: checks whether the hostname is valid to send request
--------------
HostnameRequestSender: Generate the URL
Send the request
--------------
HttpToDataResponse: Translate the request response to domain response
--------------
HostnameExceptionHandler: Handle exceptions
也就是说,一种解耦您的操作并遵循 SRP 的方法。还有其他方法,例如简化您的操作:
First, it is getting list of hostnames
If the hostnames is empty, generate an empty response
Next, it loops through every hostnames that do the following things:
It checks whether the hostname is valid to send request
If not valid: remove hostname
Else: Generate the URL based on hostname
Next, it loops through every valid hostnames that do the following things:
Send the request
Translate the request response to domain response
Handle exceptions
Return response
那么也可以拆分为:
HostnameValidator: checks whether the hostname is valid to send request
--------------
ValidHostnameData: Getting list of hostnames
Loops through every hostnames that do the following things:
Checks whether the hostname is valid to send request
If not valid: remove hostname
Else: Generate the URL based on hostname
--------------
HostnameRequestSender: Send the request
--------------
HttpToDataResponse: Translate the request response to domain response
--------------
HostnameExceptionHandler: Handle exceptions
当然还有其他方法可以做到。我将实现细节留空,因为有很多实现方法。
关于java - 如何在我的 HttpClient 执行程序中遵循单一职责原则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29742523/
我刚刚开始 iOS 应用程序开发,到目前为止,这是一次很棒的体验。 Apple 文档很棒,但我有一些问题不是技术性的,只有有经验的人才能回答。 我有一堆 UIViewController 处理它们控制
我几天前开始学习 react-redux-immutable,但我仍然对构建我的应用程序感到困惑。我有 php(symfony/laravel MVC 背景),所以要理解一些 javascript 概
每次查看 SharpDX 代码并尝试遵循 DirectX 文档时,我都会遇到困难。有没有一个地方清楚地列出了每个编号的类映射到什么以及它们存在的原因? 我说的是这样的事情: D
我正在使用 Robospice 库 创建应用程序。这是处理互联网连接的绝佳选择,因为库的核心是基于 Android 服务的,所以我们的连接与 Activity 生命周期无关。 我们正在创建我们的请求并
我可能在这里分析过度了,但是根据我对 MVC 的阅读,似乎有很多关于如何做事情的观点。 是否有一个“最佳实践”网站或文档来定义 MVC 各个部分的职责? 请记住,我使用 EF/Repository&U
我是一名优秀的程序员,十分优秀!