我发现很难将这个问题作为一个具体的标题,因为我并不知道如何命名我的问题类型。欢迎任何建议。
我有一个运行逻辑的服务,字面上执行相同的操作(例如保存缩略图),但包含不同提供商的完全不同的逻辑:
@Service
public class ThumbnailService {
public void saveForProvider1(Prov1 url) {
}
public void saveForProvider2(Prov2 url) {
//completely different logic than Provider1; also a different parameter Object "Prov2"
}
}
问题1 :对于任何新的provider
,我必须在ThumbnailService
中创建其他方法。
现在在特定点,我想运行这些方法async:
//basically just an async wrapper service
@Service
@Async
public class ThumbnailServiceAsync {
@Autowired
private ThumbnailService delegator;
public class asyncSaveForProvider1(Prov1 url) {
delegator.saveForProvider1(url);
}
public class asyncSaveForProvider2(Prov2 url) {
delegator.saveForProvider2(url);
}
}
切换Integer
变量,我知道哪个号码代表哪个提供商:
int provider;
switch (provider) {
case 1: thumbServiceAsync.asyncSaveForProvider1(url); break;
case 2: thumbServiceAsync.asyncSaveForProvider2(url); break;
default: throw NotSupportedException();
}
问题2 :正如您所看到的,我为了委派特定的提供程序例程而编写了大量代码。而且我还必须至少触及引入任何其他提供者时提到的那3个类。
问题:如何优化此流程?特别是在时间上可以实现更多的提供者。此外,不仅是缩略图例程,还包括必须为每个提供程序实现的更多方法,但这些方法与其逻辑不同。就像“为providerX创建用户”或“为providerX运行一些清理例程”。
答案 0 :(得分:0)
interface Provider {
void specificProviderCode();
}
public class Provider1 implements Provider {
public void specificProviderCode(){
}
}
public class ProviderFactory{
public static Provider createProvider(ProviderType providerType){
if(providerType.equals(ProviderType.TYPE_1){
return new Provider1();
}
}
}
@Service
public class ThumbnailService {
public void saveForProvider(Provider provider){
provider.specificProviderCode();
}
}
@Service
@Async
public class ThumbnailServiceAsync {
@Autowired
private ThumbnailService delegator;
public class asyncSaveForProvider(ProviderType providerType) {
Provider url = ProviderFactory.createprovider(providerType);
delegator.saveForProvider(url);
}
}
现在,当您只在那里添加新提供者时,您需要进行更改(创建具有特定逻辑的新提供者),这两种服务都不会被更改,这也意味着所有服务调用者都不需要更改其代码。
答案 1 :(得分:0)
Command Pattern非常适合。
将save
方法视为Runnable或Callable(Java中的基本命令接口)的实例。如果ThumbnailService
将每个唯一save
方法及其唯一参数包装到其中一个命令接口中,则ThumbnailServiceAsync
可能会变为简单Executor,而不知道{{1} }}。 Providers
语句消失了,因为Executor通过调用switch
或run()
来处理每个命令:
这留下了关闭call()
的问题。我们也希望从该课程中消除具体ThumbnailService
的知识。显而易见的OOP方法是将不同的逻辑分解为单独的类,可能是Providers
本身。如果必须围绕提供者包装公共接口,则可能需要求助于序列化不同的参数,例如作为字符串,铸造或使用反射。