我有一个函数somefunction()
,它被称为很多,但它第一次被调用我希望它的行为有点不同。这是一个例子:
first_time = true;
somefunction(){
// bunch of code...
if (first_time)
{
first_time = false;
// do it this way...
}
else
{
// do it that way...
}
// bunch of code...
}
我想到了3种方法:
您可以按照上面的示例进行操作 你在哪里“第一次”的概念 是明确的。通常是“第一次” 因此,check只是一个布尔检查 它很便宜 - 但是,当你 在一个发射的计时器中这样做 每隔几百毫秒, 感觉很糟糕。
复制该函数,只需更改第一次调用时需要更改的几行代码,并在开始时调用一个函数,每隔一次调用另一个函数。特别是如果功能很大,这看起来真的很难看IMO。
您分解somefunction()
并为代码完全相同的位置创建单独的函数。然后,您将首次创建包装函数,并且每次使用这些较小的函数创建包装函数。我认为这种方法是最好的,也是我将在涉及计时器的情况下使用的方法。
思考?
答案 0 :(得分:0)
太一般了;我认为第一种和第三种方法在适当的情况下是可以的(#2不是 - 违反DRY)。而且,它并没有一次又一次地显示给我;我能想到的最常见的是单身人士模式。你能给出一个具体的例子吗?
答案 1 :(得分:0)
第一种方法似乎没问题。第二种方法是维护噩梦。第三种方法似乎会变得比你的描述要复杂得多。除非在这些特定点分解功能提供逻辑分组,否则您将创建一个甚至可能比两个更麻烦的解决方法。
我能想到的另一种方法是使用回调函数来运行支持函数作为第一类对象的语言的“第一次”代码。这是JavaScript中的一个示例。
function makeSpecialFunction = function(runOnlyFirstTime) {
return function() {
// code before
if(runOnlyFirstTime) {
runOnlyFirstTime();
runOnlyFirstTime = null;
}
// code after
};
};
我知道这并不是一项巨大的改进,但如果唯一让您someFunction
无法重复使用的话,那么这就是您的解决方案。
现在someFunction
可以使用两次不同的初始化代码。
var init = function() {
alert("first:init");
};
var init2 = function() {
alert("first:init2");
};
var someFunction = makeSpecialFunction(init);
var otherFunction = makeSpecialFunction(init2);
someFunction(); // alerts first:init
someFunction(); // doesn't alert anything
答案 2 :(得分:0)
在像C#这样的语言中你可以像这样使用委托(函数是公共可调用方法):
public delegate void FunctionSignature();
class FunctionContainer
{
public FunctionSignature Function;
public FunctionContainer()
{
Function = FirstTimeFunction;
}
private void FirstTimeFunction()
{
...
Function = FollowingTimesFunction;
}
private void FollowingTimesFunction()
{
...
}
}
只是一个想法,一个好奇心,如果你喜欢,但它可能对你有用: - )
答案 3 :(得分:0)
最容易和最易维护的一般情况IMO是选项1
我将first
参数传递给默认为false的函数:
function(first = false)
if first
... do something special
else
... optionally do something else special (if you want)
... do main stuff
我同意其他人的观点,即#2本质上是一个坏主意,#3可能有点过分。
这通常是函数的参数 - 对它们起作用并根据它们改变行为。 first
可以很容易last
,is_weekday
,am_i_feeling_lucky
等。
答案 4 :(得分:0)
C具有静态局部变量,其值从调用到调用持续存在。您可以将first_time声明为静态变量。它的值仅在第一次调用时初始化。后续调用将使用之前的值。因此,它成为一个标志,指示这是否是第一次调用。
void some_function()
{
static int first_time = 1;
if (first_time) {
// do stuff for first call only
first_time = 0;
}
// do stuff for every call
}
答案 5 :(得分:0)
在某些情况下,您可以使用Sentinel Value,但反过来:也就是说,传递一个特殊值来初始化函数。我认为这些情况很少见。
更好的可能是您的选项3的变体:将函数放入其自己的类中,并使初始化步骤不是函数的一部分,而是类构造函数的一部分。还有一些情况没有涉及 - 例如,初始化需要实际初始值,但我认为这涵盖了大多数情况并且是最干净的选择。即使需要初始值,您也可以将其传递给构造函数,然后您的条件逻辑移出调用者,这可能是一个坏主意。