两个函数,或一个具有不同参数的函数?

时间:2009-05-07 22:06:55

标签: parameters function

这是一个非常通用的“最佳做法”问题,但这是一个例子。

假设我有一部电影编目应用。我想让我的用户有机会为IMDb或Metacritic指定其概要/评级信息。

我这样做:

if (preferredSupplier == "imdb"){
      getIMDbRating(movieName);
}else{
      getMetacriticRating(movieName);
}

或者这个:

getRating(movieName, preferredSupplier);

我更喜欢第二个,但这意味着函数必须遵循非常不同的逻辑,具体取决于第二个参数的值(例如,Metacritic可能需要屏幕抓取,其中IMDb可能有一个很好的API)。 / p>

或者我应该将它们结合起来?因为在getRating()中充当包装函数,并根据第二个参数的值调用getIMDbRating()或getMetacriticRating()。

11 个答案:

答案 0 :(得分:6)

第二个允许您随着时间的推移扩展首选供应商的数量,您仍然可以(内部)将这些作为两个单独的方法来实现。

如果这是我,我会看两个类(Imdb和Metacritic),它们都来自RatingProvider基类,并以不同方式实现getRating。

或者,如果我开始使用我的模板,我会看着Bridge模式。

只有你知道你的系统可能发生的变化,所以你知道你是否需要去城里,但是你可以通过一个API,你可以以统一的方式获得评分,无论他们实际来自哪里,我,是一个比你必须通过选择一种方法或另一种方法做出决定的更好的API。

答案 1 :(得分:4)

使用getRating方法获得RatingProvider类可能是个好主意。

您可以将不同的评级提供程序作为其子类,这些提供程序将自己实现如何获取/处理评级。

答案 2 :(得分:1)

两种解决方案都不理想。你真正应该做的是使用GetRating(字符串moviename)函数将preferredSupplier实现为接口或抽象类。

然后为类IMDBSupplier和MetaCriticSupplier实现接口,并让每个类都有自己的逻辑来获得评级。这使得getRating()函数完全独立于消耗它的任何代码,这是一种良好的,松散耦合的设计。

在您的类中消耗供应商,它并不关心它是哪种类型 - 它只是调用GetRating()。 GetRating()与供应商无关。

答案 3 :(得分:1)

我将使用名为getRating的抽象方法定义一个名为MovieDatabase的抽象类,然后提供为各种提供程序实现getRating方法的子类(如IMDb,Metacritic)。

通过此设置,您可以编写与提供程序无关的代码,即对特定提供程序一无所知。它只需要一个MovieDatabase实例并在其上调用getRating操作,而不必担心提供者或实现细节。

这种方法的优点是它更具可扩展性。如果要添加更多提供程序或操作,可以在一个位置(MovieDatabase类及其子类)执行此操作,其余代码应该可以正常工作。

答案 4 :(得分:0)

我会把它们结合起来。正如您所说,这两者可能需要完全不同的实现,并且将实现代码分成不同的函数,使事物更易读,更易于维护。但是拥有一个呼叫点也很不错。您可以考虑将其放在一个类中,将实现函数标记为私有,将包装器标记为public。这样包装器是唯一的接触点。通过明确表示包装器是这些函数的单个调用点,它将进一步提高可维护性。

答案 5 :(得分:0)

我的偏好是你最后的想法:同时使用两者。拥有一个以源为参数的功能,可以很容易地编写大量代码,通过简单的值更改(可能来自UI)从供应商切换到供应商。如果/当您打算与固定的已知供应商联系时,您还可以使用方便的单供应商功能进行呼叫。

答案 6 :(得分:0)

第二个选项是最好的(在TO中它是名为Factory的b.e.t.w.e.e.n)。给它一个默认行为,并在其中为每个提供者调用一个不同的函数,在所有那些ifsp>中没有任何一点

答案 7 :(得分:0)

我认为这取决于您使用方法的频率,代码的位置和方式。请记住,编写例程的主要原因是它们是 - 这是正确的 - 例程。也就是说,例程应包含您希望重用的代码,并且应该以易于重用的方式编写。

有了这个说,如果我面对你的例子(并且用C#编码),我可能最终会为不同类型的db搜索创建一个enum,然后有一个包装方法接受这样的{ {1}}作为参数,并从包装器方法调用不同的数据收集方法 - 类似于您在帖子末尾建议的内容,但不是字符串作为输入。

答案 8 :(得分:0)

难道不会取决于您使用它的频率吗?如果您在整个代码中反复进行基本检查,那么函数将避免重复该代码块。

但是,如果你在这里和那里只使用那个逻辑几次,那么第一种方式可能更清楚。

答案 9 :(得分:0)

如果你的函数返回相同类型的响应,那么在单个函数中重载是有意义的。

如果你的函数根据输入返回非常不同的东西,你应该使用两个函数来区分它们返回不同的东西。

例如,如果IMDB评级为5星级,而Metacritic评级为4星级,您需要明确表示应该以不同方式处理它们。

使用单独的类将有助于澄清,而不是将所有这些功能都放在那里。

答案 10 :(得分:0)

为什么你不能做像

这样的事情
public interface IRating{

  public Rating getRating();
}

public IMDBRating extends Rating

public MetacriticRating extends Rating