当前位置: 首页 > 面试题库 >

在Java中创建不依赖if-else的工厂方法

傅玮
2023-03-14
问题内容

目前,我有一种方法可以根据给定的String充当工厂。例如:

public Animal createAnimal(String action)
{
    if (action.equals("Meow"))
    {
        return new Cat();
    }
    else if (action.equals("Woof"))
    {
        return new Dog();
    }

    ...
    etc.
}

我要做的是避免在类列表增加时出现整个if-else问题。我想我需要有两种方法,一种将Strings注册到类中,另一种基于操作的String返回类。

用Java做到这一点的一种好方法是什么?


问题答案:

在打开字符串之前,您所做的可能是最好的方法。( 编辑2019: 可以打开字符串-使用它。)

您可以创建工厂对象以及从字符串到这些对象的映射。但这确实在当前的Java中有些冗长。

private interface AnimalFactory {
    Animal create();
}
private static final Map<String,AnimalFactory> factoryMap =
    Collections.unmodifiableMap(new HashMap<String,AnimalFactory>() {{
        put("Meow", new AnimalFactory() { public Animal create() { return new Cat(); }});
        put("Woof", new AnimalFactory() { public Animal create() { return new Dog(); }});
    }});

public Animal createAnimal(String action) {
    AnimalFactory factory = factoryMap.get(action);
    if (factory == null) {
        throw new EhException();
    }
    return factory.create();
}

在最初编写此答案时,用于JDK7的功能可能会使代码看起来如下所示。事实证明,lambdas出现在Java SE 8中,据我所知,还没有针对地图文字的计划。(
2016年编辑

private interface AnimalFactory {
    Animal create();
}
private static final Map<String,AnimalFactory> factoryMap = {
    "Meow" : { -> new Cat() },
    "Woof" : { -> new Dog() },
};

public Animal createAnimal(String action) {
    AnimalFactory factory = factoryMap.get(action);
    if (factory == null) {
        throw EhException();
    }
    return factory.create();
}

编辑2019: 目前看起来像这样。

import java.util.function.*;
import static java.util.Map.entry;

private static final Map<String,Supplier<Animal>> factoryMap = Map.of(
    "Meow", Cat::new, // Alternatively: () -> new Cat()
    "Woof", Dog::new // Note: No extra comma like arrays.
);

// For more than 10, use Map.ofEntries and Map.entry.
private static final Map<String,Supplier<Animal>> factoryMap2 = Map.ofEntries(
    entry("Meow", Cat::new),
    ...
    entry("Woof", Dog::new) // Note: No extra comma.
);

public Animal createAnimal(String action) {
    Supplier<Animal> factory = factoryMap.get(action);
    if (factory == null) {
        throw EhException();
    }
    return factory.get();
}

如果要添加参数,则需要切换SupplierFactory(并且get变得apply在上下文中也没有意义)。对于两个参数BiFunction。有两个以上的参数,您又回到了使其再次可读的状态。



 类似资料:
  • 我使用方法遇到了麻烦,无论我用什么方法尝试,我都得到了: null 我的代码:

  • Perl条件语句有助于决策,这需要程序员指定一个或多个要由程序评估或测试的条件,以及在条件被确定为真时要执行的一个或多个语句,以及可选的其他条件如果确定条件为假,则执行语句。 以下是大多数编程语言中的典型决策结构的一般性 - 数字0,字符串'0'和“”,空列表()和undef在布尔上下文中都是false ,所有其他值都为true 。 否定真正的价值! 或not返回特殊的假值。 Perl编程语言提供

  • 本文向大家介绍C# if, if...else, if... else if ,包括了C# if, if...else, if... else if 的使用技巧和注意事项,需要的朋友参考一下 示例 该if语句用于控制程序的流程。一条if语句根据Boolean表达式的值标识要运行的语句。 对于单个语句,braces{}是可选的,但建议使用。 该if还可以有一个else条款,将在案件条件的计算结果来执

  • 问题内容: 我正在寻找一种缩短此代码并避免重复代码和if语句的方法。我正在做的是创建一个计算器,该计算器在字符串中搜索运算符“ * / +-”并相应地执行它们。有任何想法吗? 另外,是否有解决方案来接受带有两个以上操作数的字符串?即5 + 10 * 2/3 问题答案: 要更改代码,可以使用switch语句,并将一些冗余代码放在开关之前或之后。

  • if语句之后可以跟一个可选的else if...else语句,这对于使用单个if ... else if语句测试各种条件非常有用。 当使用if...else if…else语句时,请记住 - 一个if可以有零个或一个else语句,它必须在任何其他if之后。 如果语句可以有零到多个if,它们必须在else之前。 一旦else if成功,其余的if或else语句都不会被测试。 if ... else

  • 当我们使用时,我们通常有类,它有一个函数,我们在这个函数中传递参数,我们在传递参数的函数中有或逻辑,以决定返回哪个工厂。是创建传递的参数、枚举或对象,然后在这些对象中具有返回哪个工厂的逻辑会更好。例如: 让我们这样说吧,我们的工厂制造商是通过枚举国家代码来决定工厂的。 取而代之的是: 和枚举将进行如下修改: 但我不认为这是普遍遵循的。为什么会这样?为什么我们不能让传递的参数始终是一个对象,并且在对