假设我有一个支持 Elasticsearch 或 OpenSearch 服务的应用程序。我有一个
SearchClient
接口,可实现特定客户端(即 ES 或 OS)。每个方法都实现相同的逻辑,只是类型不同。
Java 中是否有可能以及推荐的方法来消除重复代码并集中核心逻辑?我知道有关于提取最低共同祖先的建议,但在这种情况下,它最终会是
Object
。我还探索了使用 Adapter 类的可能性,但最终处于适配器的返回类型与客户端类型相关的相同位置。
代码
public interface SearchClient {
[...]
void update(
String indexName,
Pair<String, String> fieldAndValue,
Pair<String, Map<String, Object>> updates);
[...]
}
public class ElasticSearchClient implements SearchClient {
[...]
@Override
public void update(
String indexName,
Pair<String, String> fieldAndValue,
Pair<String, Map<String, Object>> updates) {
if (isClientAvailable) {
UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(indexName);
updateByQueryRequest.setQuery(
new MatchQueryBuilder(fieldAndValue.getKey(), fieldAndValue.getValue())
.operator(Operator.AND));
Script script =
new Script(
ScriptType.INLINE,
Script.DEFAULT_SCRIPT_LANG,
updates.getKey(),
JsonUtils.getMap(updates.getValue() == null ? new HashMap<>() : updates.getValue()));
updateByQueryRequest.setScript(script);
updateElasticSearchByQuery(updateByQueryRequest);
}
}
}
[...]
public class OpenSearchClient implements SearchClient {
[...]
@Override
public void update(
String indexName,
Pair<String, String> fieldAndValue,
Pair<String, Map<String, Object>> updates) {
if (isClientAvailable) {
UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(indexName);
updateByQueryRequest.setQuery(
new MatchQueryBuilder(fieldAndValue.getKey(), fieldAndValue.getValue())
.operator(Operator.AND));
Script script =
new Script(
ScriptType.INLINE,
Script.DEFAULT_SCRIPT_LANG,
updates.getKey(),
JsonUtils.getMap(updates.getValue() == null ? new HashMap<>() : updates.getValue()));
updateByQueryRequest.setScript(script);
updateElasticSearchByQuery(updateByQueryRequest);
}
}
}
[...]
为了避免 ElasticSearchClient 和 OpenSearchClient 类中的代码重复,您可以将公共逻辑提取到单独的类或方法中。
具体操作方法如下:
这是一个示例实现:
SearchClient界面(无变化)
public interface SearchClient {
void update(String indexName, Pair<String, String> fieldAndValue, Pair<String, Map<String, Object>> updates);
}
ElasticSearchClient 类(添加了 SearchClientCommon 实例)
public class ElasticSearchClient implements SearchClient {
private final SearchClientCommon common;
public ElasticSearchClient(SearchClientCommon common) {
this.common = common;
}
@Override
public void update(String indexName, Pair<String, String> fieldAndValue, Pair<String, Map<String, Object>> updates) {
if (isClientAvailable) {
common.update(indexName, fieldAndValue, updates);
}
}
}
OpenSearchClient类(添加了SearchClientCommon实例)
public class OpenSearchClient implements SearchClient {
private final SearchClientCommon common;
public OpenSearchClient(SearchClientCommon common) {
this.common = common;
}
@Override
public void update(String indexName, Pair<String, String> fieldAndValue, Pair<String, Map<String, Object>> updates) {
if (isClientAvailable) {
common.update(indexName, fieldAndValue, updates);
}
}
}
SearchClientCommon类(添加了公共逻辑)
public class SearchClientCommon {
public void update(String indexName, Pair<String, String> fieldAndValue, Pair<String, Map<String, Object>> updates) {
UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(indexName);
updateByQueryRequest.setQuery(
new MatchQueryBuilder(fieldAndValue.getKey(), fieldAndValue.getValue())
.operator(Operator.AND));
Script script =
new Script(
ScriptType.INLINE,
Script.DEFAULT_SCRIPT_LANG,
updates.getKey(),
JsonUtils.getMap(updates.getValue() == null ? new HashMap<>() : updates.getValue()));
updateByQueryRequest.setScript(script);
updateElasticSearchByQuery(updateByQueryRequest);
}
}