避免使用'ifs'调用方法的最佳实践

时间:2015-10-08 18:33:26

标签: java

我有遗留代码,与此类似

#include<stdio.h>

int main()
{
    int a,b,max,lcm;

    printf("Enter 2 numbers: ");
    scanf("%d %d", &a, &b);

    if(a>b)
    {
        max=a;
    }
    else
    {
        max=b;  
    }

    do
    {
        max++;
    } while(max%a!=0 && max%b!=0);

    lcm=max;
    printf("LCM of %d and %d is %d\n", a,b,lcm);

    return 0;
}

正如你所看到的那样,对于新类型来说难以维持......

解决这个问题的最佳做法是什么?

我正在考虑为每个将实现相同接口的资源函数创建Class。

然后创建一个private Resource getResource(String type){ Resource resource = null; if("A".equals(type)){ resource = Utils.getResourceA(); //static func }else if("B".equals(type)){ resource = Utils.getResourceB(); //static func }else if("C".equals(type)){ resource = Utils.getResourceC(); //static func }else if // etc.. } 键是类型,IResource将是类的实例。

但是这个解决方案存在问题。

  • 在哪里创建此地图?在getResource()方法里面?包含此方法的内部类?
  • 我将在内存中保存类的实例,以防我不使用其中许多类
  • 我现在将拥有一个完整的对象(对于每种方法)而不是简单的静态方法!

注意:我没有使用任何框架,纯java。

由于

2 个答案:

答案 0 :(得分:3)

通常的解决方案确实是您描述的解决方案。使用Java 8的示例(但可以在Java7中以更详细的方式编写):

private Map<String, Supplier<Resource>> resourceSuppliers;

public TheClass() {
    resourceSuppliers = new HashMap<>();
    resourceSuppliers.put("A", Utils::getResourceA);
    resourceSuppliers.put("B", Utils::getResourceB);
    resourceSuppliers.put("C", Utils::getResourceC);
    ...
}

private Resource getResource(String type){
    return resourceSuppliers.get(type).get();
}    

如果所有实例的类型/资源映射相同,则映射也可以是静态final并由所有TheClass实例共享:

private static final Map<String, Supplier<Resource>> RESOURCE_SUPPLIERS = createResourceSuppliers();

private static Map<String, Supplier<Resource>> createResourceSuppliers() {
    // same code as in constructor above
}

在较旧的Java版本中,您必须定义供应商界面,并通过以更明确的方式创建供应商来定义供应商,例如,使用匿名内部类:

resourceSuppliers.put("A", new Supplier<Resource>() {
    @Override
    public Resource get() {
        return Utils.getResourceA();
    }
});

答案 1 :(得分:3)

public enum ResourceType { A { @Override public Resource getResource() { return Utils.getResourceA(); } }, B { @Override public Resource getResource() { return Utils.getResourceB(); } }, C { @Override public Resource getResource() { return Utils.getResourceC(); } }; public abstract Resource getResource(); } 变为String的最佳方式。这样可以防止任意类型,并且需要为任何新类型实现enum方法。

ResourceType type = ResourceType.valueOf("A");

<强>更新

PropName = "AllowBypassKey" CurrentDb.Properties(PropName) = False 转换为public interface ModuleInterface { public Response getSomething(@Valid RequestObj obj); } 很简单(内置):

@Service
@Path("/foo")
public class FooClass implements moduleInterface {
public Response getSomething(@Valid Request obj){
// code
}
}