一般编码最佳实践 - 我应该使用更多代码还是更多变量? (Flash AS3,或一般)

时间:2011-04-07 01:52:48

标签: flash actionscript-3 coding-style

所有

我是一名自学成才的程序员 - 而不是CS毕业生 - 因此我可能会定期忽略数百种编码最佳实践。

无论如何,这是一个普遍的问题......

编码时,使用更多代码或更多变量(或数组,散列等)来实现逻辑是否更好?

这是一个模糊的问题,但这是一个特定的“例如......”

我正在为RIA构建UI;其中一个可供选择的是一行中的一系列小点 - 每个点都是可点击的,并且用作导航,允许用户选择不同的屏幕。

(想想iPhone中主屏幕底部的点可让您切换屏幕,或者在此页面上显示图像切换器导航:http://www.apple.com/ipad/

无论如何,我已经将这个“点导航控件”实现为自定义的Sprite子类。当用户单击一个点时,该类将一个自定义事件调度到包含与所点击的点对应的索引值(uint)的侦听器(例如,“0”是第一个点,“n-1”是第n个点)。

现在,在监听器中,我需要采取行动 - 将用户导航到相应的页面。所以,一个明显的选择:

private function dotClicked(e:customDotEvent):void {
    // e.target.index contains the index of the dot clicked
    switch (e.target.index) {
        case 0:
            // navigate the user to the screen that corresponds to dot 0
            loadScreen("home");
            ....
            break;
        case 1:
            // navigate the user to the screen that corresponds to dot 1
            loadScreen("about");
            ....
            break;
        ....
        case n:
            // navigate the user to the screen that corresponds to dot n
            loadScreen("etc");
            ....
            break;
    }

在这个例子中 - 我有一个相当详细的开关功能,可以完成工作。

一个不那么详细的选项:

private function dotClicked(e:customDotEvent):void {
    var screens:Array = ["home","about","blog",...,"etc"];
    // e.target.index contains the index of the dot clicked
    loadScreen(screens[e.target.index]);
}

在第二个选项中 - 我显然得到了更少的代码,但是需要额外的内存来存储“屏幕”数组(尽管只是在函数的持续时间内)。

(显然,可能还有很多更好的选择,但希望这说明了我的问题......)。

所以,一般来说,什么对性能更好,减少应用程序的整体内存占用量等?

在这个简单的例子中,差异可能是微不足道的。但它可以在大型应用程序中加起来吗?

Flash(或其他平台)更好地处理更多代码或更多变量吗?

这值得担心,还是我应该担心编写更易于维护和调试的代码?

非常感谢提前!

5 个答案:

答案 0 :(得分:5)

我认为您首先要担心的是,首先要制作一个更易于维护和调试的代码。如果你的应用程序变慢,那么进行优化。我的策略是只优化代码,这将运行很多。按钮的事件监听器可以在0.001秒或0.01秒内执行,这没关系。但是如果复杂的代码在每一帧中运行,那么优化它 使用actionscript代码执行速度甚至更少,因为渲染使用的CPU周期比通常的算法多得多(除非你编写一些应用程序,只进行大量的数学计算)。例如:

for (var i:int=0;i<500;i++){
    Math.sin(Math.random());
}

的资源密集程度低于

graphics.lineTo(300,300);   

因此,如果您想进行优化,请从图形开始。

答案 1 :(得分:4)

我不得不考虑一下你所得到的东西 - 我知道你来自哪里,但在这种情况下的表现是微不足道的。

(注意:“性能微不足道”是那些狡猾的陈述之一......但是现在就放手吧,相信我。在我们解决了大事之后,我们可以担心性能和内存占用。)< / p>

在这种情况下,您可能不必担心内存或计算速度。这不仅是因为您处理的是小数据,还因为您需要担心可能需要扩展代码。如果你有数百页,甚至数千页,你真的想要为每一页添加一个switch case语句吗?不。但是......你真的想要为每个新的迭代添加一个元素,一串所有东西到一个数组吗?否。

在这种情况下,我会考虑性能或内存占用的代码可维护性,因为它是微不足道的。 (又一次。)这是微不足道的,因为在你牺牲代码可维护性来处理这个问题之前,你需要担心更大的性能命中。你的第二个例子比第一个更好,因为你没有重用代码,这很好。但是,你可以更进一步;而不是在数组中定义您的位置(“home”等),并使用Dot类中的索引来引用包含该位置的数组键,为什么不将该位置定义为Dot类本身中的变量?这将您的对象与DotClicked函数分离,打开更多选项,从长远来看,使代码更易于维护。你可以用这样的东西来称呼它:

private function dotClicked(e:customDotEvent):void {
    // e.target.location contains the target location of the dot clicked, e.g. "home", "about", "etc"
    loadScreen(e.target.location);
}

使用此方法,每次调用函数时都不会创建新数组(这应该可以防止垃圾收集器运行),而且您也不必遍历switch-case语句(即每次进行更改时都必须进行编辑,并且您不必担心将索引转换为字符串等等,并且在此过程中,您将获得更好的代码。

那是非常漫长的,如果你已经走到这一步,我会为你鼓掌(并道歉)。简而言之,我的答案是“使用更多代码或更多变量(或数组,散列等)来实现逻辑是更好的做法”就是这样 - 如果你可以管理它,可能更好的做法是使用更少的两者。

祝你好运。

答案 2 :(得分:2)

较不详细的版本绝对是可取的,因为它更易于维护和管理。担心按钮的性能有点傻,但担心调试和维护的简便性很重要。

虽然并非总是这样,但大多数情况下,代码行数和管理它需要做多少工作之间存在很好的相关性。如此简洁以至于难以阅读代码是很愚蠢的,但只有当你达到从14个字符到13个字符的水平时,这才真正成为一个问题。

对于它的价值,在你的例子中,你不必每次都创建一个新的“屏幕”数组。由于该数组始终相同,因此只需将其定义为代码顶部的常量即可。

答案 3 :(得分:1)

对于您的示例,您是正确的,它不会在几个屏幕上产生任何性能差异。如果您有许多可能的屏幕排列方式来映射点,那么为它们提供常量整数ID而不是字符串来节省内存,并采用第二种方法(数组或向量)是有意义的。我相信AS3编译器会将switch语句变成一大堆条件(if,如果是cascade),所以这对性能来说并不理想,并且也没有太多的大小节省。

为了更广泛地回答您的问题,“尺寸与速度”是典型的软件工程权衡。对于几乎每个软件问题,使用更多计算但内存更少的事情有一种更慢的方法,而且使用更多内存但计算量更少的更快方法。大多数编译语言(如C ++)的编译器都具有速度或大小的优化预设。优化速度通常会为您的应用程序在光盘上提供更大的占用空间(因为它可以实现优化,如循环展开,冗余函数内置)以及更多的运行时内存使用(更多缓存和事物预先计算到查找表中)。优化大小会导致运行速度较慢的较小代码(例如,循环和函数不会扩展,并且具有通常的开销)并且缓存和预计算较少。没有正确的答案,您可以根据应用程序的需求和可用的资源来决定大小与速度的关系。

答案 4 :(得分:1)

你这样做的方式很好。我要添加的唯一真实内容是引入常量。使用常量意味着您的代码不容易出错,并使其更易于阅读。

例如,如果您有Locations这样的类:

public class Locations
{
    public static const HOME:int = 0;
    public static const ABOUT:int = 1;
    public static const ETC:int = 2;
    ...
}

现在您的switch变为:

switch (e.target.index) 
{
    case Locations.HOME:
        // navigate the user to the screen that corresponds to dot 0
        loadScreen("home");
        ....
        break;
    case Locations.ABOUT:
        // navigate the user to the screen that corresponds to dot 1
        loadScreen("about");
        ....
        break;
    ....
}

更容易阅读,如果你想改变它,你可以在一个区域(Locations.as)而不是整个代码中完成所有这些