这可能是一个非常基本的问题,答案非常明显,但我很难搞清楚这一点。
如何知道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();
答案 0 :(得分:6)
您不必显式测试工厂方法的返回值的动态类型。静态类型应该告诉您需要知道的所有内容。这意味着返回类型应该是特定的,以告诉您可以对该对象做什么。例如,制作不同实现的地图的工厂方法应返回Map
:
public interface MapFactory {
public Map makeMap();
...
}
Map
是HashMap
还是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”成功。也许这是问题中的拼写错误?
对目标的定义稍微清楚一点,使用泛型类型可能会有所帮助,但如果没有更多信息,很难说。