Java工厂模式,创建特定的类



我在一次采访中遇到了一个问题,我吃了两种食物,比如面包和蛋糕,得到了以下答案:

 public class FoodFactory{};
 public class Food{};
 public static void main(String[] args) {
    Food foo = FoodFactory.get("bread");
    System.out.println(foo.getClass().getName());
 }

考虑到FoodFactory类和Food类,我不知道如何使其工作,以便它打印出该类的"bread"。让它打印面包的唯一方法似乎是创建一个Bread类,并让FoodFactory返回它。

我只是想知道我是否遗漏了什么,因为FoodFactoryFood是给定的类,所以我认为这是我只需要更改的两个类。有没有一种方法可以实现给定的两个类,并在只使用这两个类的情况下打印"bread"

因此,一种方法是创建一个扩展类Food的类Bread,并让FoodFactory.get()根据传递的字符串返回适当的对象。

class Food {};
class Bread extends Food {};
class FoodFactory {
    public static Food get(String type){
        switch(type){
            case "bread" : return new Bread();
            default : return new Food();
        }     
    }
}

另一种方法是使用反射。

除非您在运行时编译一个新类(这是可能的,但在这里不合适),否则如果您想返回Bread实例,您当然需要添加一个类。

理想情况下,Food最多应该变成一个接口或抽象类。然后有类BreadCake实现/扩展Food。您的FoodFactory有一个静态方法get,它将食物作为字符串接受。根据值的不同,您可以实例化并返回一个具体的类,它将在打印类名时为您提供所需的内容。

我认为面试官问的真正问题是你是否理解模式和多态性。正如其中一条评论中所指出的,除非真的有Bread类,否则getClass().getName()不会返回"Bread"。你本可以做的是建议面试官Food是基类,在这种情况下应该由CakeBread类扩展,甚至建议将其更改为抽象类或接口。然后,您可以提出一个简单的工厂类,它将在基类接口后面创建所需的实现"隐藏"。

您的问题基本上是Java工厂设计模式的一个例子。假设你有一个项目,分别是一个具有多个接口和不同类的类层次结构,那么创建任何类的最简单方法是什么?这就是工厂用来处理与类实例创建有关的所有操作的地方。

现在,对于您的情况,最方便的方法是将Class Food更改为一个接口,例如:

public interface Food {
    String getType();
}

现在您需要实现interface FoodCakeBread

public class Cake implements Food{
    @Override
    public String getType() {
        return "Cake";
    }
}
public class Bread implements Food{
    @Override
    public String getType() {
        return "Bread";
    }
}

现在,您需要定义FoodFactory类,该类具有一个静态get方法,该方法根据提供的条件返回一个Food

public class FoodFactory {
    public static Food get(String classifier){
        if(classifier.equals("Cake")) return new Cake();
        if(classifier.equals("Bread")) return new Bread();
    //no matching Food to create    
    throw new IllegalArgumentException("The " + classifier + " is not a valid classifier");
    }
}

拥有Factory后,您可以将其用于任何创建操作。如果你想从Food实例中打印出Bread,你可以这样实现:

//food is now an instanceof Bread
Food food = FoodFactory.get("Bread");
System.out.println(food.getType());

它只是打印

Bread

此外:为了确保每个创建都只由FoodFactory处理,您应该使Food类的每个构造函数protected

最新更新