从Java Factory Pattern返回类型

时间:2014-01-18 00:01:47

标签: java javadoc factory-pattern

这可能是一个非常基本的问题,答案非常明显,但我很难搞清楚这一点。

如何知道java工厂模式中涉及的类方法的返回类型。例如,查看下面的代码...什么是方法调用的返回类型以及如何正确地进行转换...以及如何为类编写javadoc。

我正在尝试编写一个用户然后可以插入他们的项目的库...

我有一个界面

public interface myInterface
{
     public Object doA();
     public Object doB();
}

和具体的课程如下

public class concerete1 implements myInterface
{
public concerete1() {
}

@override
public Object doA()
{ return new String("Hello"); }

@override
public Object doB()
     { return "hello".getBytes(); }

}

public class concerete1 implements myInterface
{
public concerete2() {
}

@override
public Object doA()
{ return "hello".getBytes(); }

@override
public Object doB()
{ return new String("Hello"); }

}

我的工厂类如下

public class factory
{
     private myInterface mi;

     public myInterface actionProducer(String choice)
     {
           switch(choice)
           {
           case "a":
                 mi = new concerete1();
                 break;
           case "b":
                 mi = new concerete2();
                 break;
           }
           return mi;
     }
}

我的测试跑步者课程如下

String result = factory.actionProducer("a").doA();

4 个答案:

答案 0 :(得分:6)

您不必显式测试工厂方法的返回值的动态类型。静态类型应该告诉您需要知道的所有内容。这意味着返回类型应该是特定的,以告诉您可以对该对象做什么。例如,制作不同实现的地图的工厂方法应返回Map

public interface MapFactory {
    public Map makeMap();
    ...
}

MapHashMap还是TreeMap还是ConcurrentSkipListMap,您可以使用Map方法与其进行互动。如果结果是您需要调用ceilingKey,这不是Map方法,则会遇到设计问题。

在您的情况下,您的工厂方法没有意义,因为没有比Object更多的特定类型返回,并且您无法使用Object的API之外的返回值。无论对象如何实现,更合理的工厂都会返回可以用相同方式进行交互的对象。

答案 1 :(得分:1)

您不应对实际工厂产品类型感兴趣。构造抽象工厂用于使用通用接口/抽象超类来分解对象。 所以,如果你有

public abstract class Animal {
     public void eat();
     public String foo();
}

和实现者类:

public class Dog extends Animal {
    public void eat() {
     //stuff here
    }
    public String foo() {
        return "howgh";
    }
}

public class Cat extends Animal {
    public void eat() {
     //stuff here
    }
    public String foo() {
        return "meow";
    }
}

您的工厂界面将如下所示:

public interface AnimalFactory {
     public Animal createAnimal();
}

具体工厂将是

public class CatFactory implements AnimalFactory {
     public Cat createAnimal(){
         return new Cat();
     }
}


public class DogFactory implements AnimalFactory {
     public Dog createAnimal(){
         return new Dog();
     }
}

因此,您可以创建通用界面产品,而无需了解其真正的类:

Animal awesomeAnimal = catFactory.createAnimal();
System.out.println(awesomeAnimal.foo());

输出将是“喵”。这是可能的,因为所有产品都是通用接口的子类(Animal here)。

答案 2 :(得分:1)

在所有情况下,返回类型都是Object。我不知道你想要转换为什么,但如果它是一个String,则无法从字节数组转换为String。您将不得不使用String类的构造函数之一(“String result = new String(factory.actionProducer(”a“)。doA());”)。如果您正在调用“doB()”(从而将String作为对象),您可以通过强制转换它来将其转换为字符串(“String result =(String)factory.actionProducer(”a“)。doA() ;“)或通过调用返回Object的toString()方法(”String result = factory.actionProducer(“a”)。doB()。toString();“)。

这些方法的Javadoc会将每个方法描述为返回一个Object,因为这就是他们所做的。

简而言之,我会将“doA()”和“doB()”的返回类型更改为它们实际返回的内容(字符串或字节数组),但也许这不是您要尝试的选项做。一些额外的背景可能有助于提出更详细的答案。

编辑:抱歉,我没有意识到两个实现中的字符串和字节数组返回类型是相反的。在答案中,我将“doA()”描述为返回字节数组,并将“doB()”作为返回字符串,我相信这些在您的示例(Concrete1)中使用的实现中被翻转。然而,其他一切都非常重要。

答案 3 :(得分:0)

最简单的答案是将'result'声明为一个Object,然后强制执行一个强制转换,并希望你做对了:如果不这样做,你会在运行时遇到错误:

 Object obj = factory.actionProducer("a").doA();
 String str = (String) obj;

但是,在您的示例中,doA()返回String或byte [],具体取决于实现的选择,因此“b”将失败并且“a”成功。也许这是问题中的拼写错误?

对目标的定义稍微清楚一点,使用泛型类型可能会有所帮助,但如果没有更多信息,很难说。