2009-05-28 27 views
4

基本上我想要的是,具有稍微不同的返回值的公共方法调用相同的方法来执行任何所需的工作。它们都返回私有方法的返回值,但私有方法将知道如何根据调用它的公共方法返回正确的值。根据调用方法更改返回类型

实施例的方法:

public Map<Type1, Type3> doSomething1(); 
public Map<Type2, Type3> doSomething2(); 

private Map<Type1/Type2, Type3> doSomething(); 

因此,在上述例子中,doSomething的()返回任一类型1类型2或作为地图的键型,这取决于哪个公共方法调用它。它将能够执行简单的检查,并使用正确类型的对象填充地图。

也许这可以通过一些聪明的Java反射来完成?我不确定。这一切似乎都非常狡猾,所以如果有更好的方法可以做到这一点,我就会全神贯注。

回答

8

我强烈建议在这里避免反射魔咒。一个功能必须完成一件事,而不能依赖谁来称呼它。

更好的方法是将doSomething()重构为更小的函数,创建两个名为doS​​omethingFor1()和doSomethingFor2()的新函数。这两个函数都可以重用旧doSomething()的重构部分。

现在有doSomething1()调用并使用doSomethingFor1()。

同样,doSomething2()应该使用doSomethingFor2()。

干杯,

jrh。

+0

是的,这也是我想出来的。我同意一种方法不应该对调用者有依赖性。 但是,如果doSomethingFor1()和doSomethingFor2()共享完全相同的代码,唯一的区别是它们添加哪个对象作为映射的键?这不会是一个重复的代码? – 2009-05-28 05:59:31

+2

重复必须通过适当地重构函数并将重复代码放置在常用函数/方法中来抵消。 – jrharshath 2009-05-28 06:37:12

+0

@ The Dissonant:使用一个参数来指示添加哪个键。不要从谁打电话给你。 – 2009-05-28 06:39:25

1

如果一切都失败了,让private方法返回Object并在公共方法中使用强制转换。

0

你绝对可以通过使用反射来分析堆栈。不过,我会尽量避免它和:

  • 返回基本类型(或对象),并在主叫方,你将不得不反正做正确丢
  • 参数传递给私有方法表明在某种程度上是什么做和回
1

第一个问题是为什么你需要这个确切的结构。

但安全的方式是使其返回

public Map<Object, Type3> doSomething(); 

如果有一个Type1和Type2没有共同的超类型。如果你有一个普通的超类型,你可以使用它来代替对象。

这将是最好的重构代码,这不是必需的。

+0

我在想,如何将doSomething()知道哪个子类的对象(即Type1或Type2)添加为Map键?它需要能够执行检查。 – 2009-05-28 06:04:11

1

我需要一点点信息的是从你的问题缺失,例如type1和2型是如何被实例化,因为你不能直接从任意类型参数的实例。现在,我们假设有一些常用数据用于实例化type1和type2。否则,没有理由对这两种方法使用一种方法。在后一种情况下,这意味着一个函数会根据类型执行两个单独的事情,这是糟糕的编程。如果你要有直接基于调用方法的逻辑,只需要两个私有方法并重构常用的东西。

如果你只实例化不同,根据一些数据,要做到这一点最简单的方法是将声明一个私有内部接口:

private interface Instantiator<T> { 

    T getNew(Data data);   

} 

现在,假设你可以实例化你的类型,你实际上可以使用:

private <T> Map<T,Type3> doSomething(Instantiator<T> instantiator) {...} 

作为一个方法签名,并有公共方法调用它与适当的Instantiator实现。

3

请注意:我错误地理解了这个问题,所以这个答案与问题所要求的是相反的。我将把它留作社区维基的参考,但这并不能回答原来的问题。

如果有一个常见的亚型,以Type1Type2称为SuperType,然后说,第一类是? extends SuperType会工作。

下面是一个使用IntegerDouble为两种类型一个小例子,他们共同的祖先为Number

private Map<Integer, String> doSomethingForInteger() { 
    HashMap<Integer, String> map = new HashMap<Integer, String>(); 
    map.put(10, "Hello"); 
    return map; 
} 

private Map<Double, String> doSomethingForDouble() { 
    HashMap<Double, String> map = new HashMap<Double, String>(); 
    map.put(3.14, "Apple"); 
    return map; 
} 

public Map<? extends Number, String> doSomething(boolean b) { 
    if (b) 
    return doSomethingForInteger(); 
    else 
    return doSomethingForDouble(); 
} 

这里,doSomething方法将根据boolean即返回两种类型的HashMap小号通过.方法返回HashMap<Integer, String>HashMap<Double, String>

实际上调用doSomethingboolean可以完成这样的:

Map<? extends Number, String> map1 = doSomething(true); 
Map<? extends Number, String> map2 = doSomething(false); 

map1将结束与Hashmap<Integer, String>,而map2会得到Hashmap<Double, String>

+0

我很欣赏答案,但你有错误的方法。我不希望超类型方法成为公共方法,并且我希望所有的地图瞬时化/操纵方法只能在一个私有方法中完成(即不要重复)。 – 2009-05-28 06:22:29

+0

哎呀,对不起,我弄混了... – coobird 2009-05-28 06:26:27

0

你可以模拟一个封闭的想法:

interface MappingClosure { 
    public void map(Map, MapProvider); 
} 


class Caller implements MappingClosure { 
    public void map(final Map MAP, final MapProvider CALLEE) { 
     this.MAP = specialise(MAP); 
     // CALLEE USED AS KEY 
    } 
} 


class MapProvider { 
    public Map getMap(final MappingClosure CALLER) { 
     return CALLER.map(mapInstance, this); 
    } 
} 

然后修改以适应需求不同的对象数据使用ob的方法需要它的项目。

相关问题