如何实现具有完全不同逻辑的多策略的方法?

时间:2016-05-25 08:26:03

标签: java spring design-patterns

我发现很难将这个问题作为一个具体的标题,因为我并不知道如何命名我的问题类型。欢迎任何建议。

我有一个运行逻辑的服务,字面上执行相同的操作(例如保存缩略图),但包含不同提供商的完全不同的逻辑:

@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运行一些清理例程”。

2 个答案:

答案 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方法视为RunnableCallable(Java中的基本命令接口)的实例。如果ThumbnailService将每个唯一save方法及其唯一参数包装到其中一个命令接口中,则ThumbnailServiceAsync可能会变为简单Executor,而不知道{{1} }}。 Providers语句消失了,因为Executor通过调用switchrun()来处理每个命令:

这留下了关闭call()的问题。我们也希望从该课程中消除具体ThumbnailService的知识。显而易见的OOP方法是将不同的逻辑分解为单独的类,可能是Providers本身。如果必须围绕提供者包装公共接口,则可能需要求助于序列化不同的参数,例如作为字符串,铸造或使用反射。