当一个函数调用一个或多个其他函数,并且这些被调用的函数只被一个调用函数使用时,代码应该如何构造?
例如,如果您有funcB()并且funcC()仅由funcA()应该调用funcB()并且funcC()是匿名函数或嵌套函数,或者如果它们是类的一部分,它们是否应该简单地声明为私有或放置在内部类中?
我目前正在使用 JavaScript,但在使用 C++ 和 Java 等其他语言时遇到了同样的情况。
根据维基百科, JavaScript 确实有嵌套函数,虽然我从未见过它使用过?
当一个函数调用一个或多个其他函数,并且这些被调用的函数只被一个调用函数使用时,代码应该如何构造?
例如,如果您有funcB()并且funcC()仅由funcA()应该调用funcB()并且funcC()是匿名函数或嵌套函数,或者如果它们是类的一部分,它们是否应该简单地声明为私有或放置在内部类中?
我目前正在使用 JavaScript,但在使用 C++ 和 Java 等其他语言时遇到了同样的情况。
根据维基百科, JavaScript 确实有嵌套函数,虽然我从未见过它使用过?
如果funcB()并且funcC()在概念上没有意义,funcA()那么你不应该公开。
传统的 OOP 会说您应该将它们设为私有。
我认为几乎总是有另一个概念属于哪个funcB()概念funcC()。您应该将它们设为不同类的公共方法。任何持有者都funcA()持有该类的私有实例。
在抽象地谈论 A、B 和 C 时,很难为此提出令人信服的理由。但我想说,如果它们在概念上不属于,funcA()那么它们在概念上确实属于其他东西。如果你同意这个前提并且同意组合比继承更好,那么结论就是让它们在其他类上公开。
当我开始一个项目时,我倾向于避免封装功能,直到事情变得稳定。
正如 Dancrumb 指出的那样,函数调用不是免费的,因此您可能需要进行一些小的重构。但是,当您查看几个月未接触过的代码时,那个干净整洁的组织将对您的心理健康有益。当你在一个团队中工作时,这会成倍地真实:)
这里有很多方法。
Javascript 支持可以在代码中的任何位置定义和分配给变量的匿名函数。
因此,您可以编写:
function foo() {
var bar = function() { /* some code */ };
bar();
}
并且bar不会在其他任何地方可用。这对于封装功能可能很有用,但我认为这不是一个非常可扩展的开发模型。
有一种观点认为,任何只被调用一次的函数在未来都可能成为值得多次调用的东西。在这种情况下,您可以创建“私有”函数:
var Foo = (function() {
var Foo = function() {
/* some constructor code */
};
var private = function() { /* a private function */ };
Foo.prototype.public = function() {
private();
/* And some other stuff */
};
return Foo;
})();
var foo = new Foo();
foo.public(); /* Includes a call to the private method */
在这种情况下,您的private方法是真正私有的,因此您不必将内部工作原理暴露给世界。
但实际上,这更多的是关于如何实现访问修改的讨论。有很多信息可以回答这个问题。更大的设计问题是是否实现单独的功能,或者是否只是内联它们。
我的选择通常是将有凝聚力的功能块塞进……嗯,塞进函数中。函数调用的成本是非零的,但事后担心......如果您确定函数调用是性能瓶颈,那么您可以担心是否调用过多以及是否应该重构您的代码使用更少的调用。
在那之前,编写你的函数,调用它们并陶醉于清晰的代码。只要确保你使用好的方法名:)
如果 funcB 和 funcC 在您的类中创建为闭包,并且您没有将它们“公开”到接口,那么它们可以更改(被删除、添加、返回不同的值等)而不必担心它们如何已经在课堂之外实施。
一旦他们暴露出来,所有的赌注都被取消了,他们可能需要进行单元测试、支持等。这是一个众所周知的规则。
闭包只是在将要使用的范围内声明的函数。
方法A
function MyClass(){
function funcA(i){
funcB(i);
funcC(i);
}
function funcB(i){
//...
}
function funcC(i){
//...
}
return {funcA:funcA}
}
va mc = new MyClass()
for(var i = 0;i<100000;i++){
mc.funcA(i);
}
方法B:
function MyClass(){
function funcA(){
function funcB(){
}
function funcC(){
}
for(var i = 0;i<100000;i++){
funcB();
funcC();
}
// funcB, funcC are created before and then released after this
}
return {funcA:funcA}
}
va mc = new MyClass()
mc.funcA();
当 funcA 被多次调用时,方法 B 可能不太受欢迎,因为分配最昂贵。
考虑内存时,可能首选方法 B。虽然这值得商榷,因为 funcA 和 funcB 都驻留在 MyClass 和 MyClass.funcA 中。