排序和管理众多变量

时间:2012-06-13 23:00:28

标签: arrays actionscript-3 variables constants

我的项目有不可避免地包含数百个变量的类,我总是要保持这些变量。例如,我总是要跟踪类中发生的一组重复“项”的特定类型的变量,将这些变量放在多个类之间会引起很多混淆。

如何更好地对变量进行排序以避免发疯,尤其是在保存数据时?

2 个答案:

答案 0 :(得分:1)

我错过了什么吗? Actionscript是一种面向对象的语言,所以你可能有数百个变量,但是除非你以某种方式将它当作一个抓包并将其全部放在一个地方,所以一切都应该随手。在不知道你所追踪的内容的情况下,很难给出具体的建议,但这是我正在开展的当前项目的一个例子,这是一个建立就业前评估的平台。

基本单位是一个问题。问题有一个词干,可以在状态栏中显示的文本,一组答案,以及我们正在跟踪用户在该特定类型的问题中所做的事情的一系列度量。

这些措施同样是他们自己的对象类型,有两种“风格”:一种用于跟踪时间限制,另一种不跟踪时间限制。度量有一个名称(所以我们知道在哪里写回数据库)和一个值(告诉我们什么)。定时的也有时间限制的财产。

当我们需要对问题进行计时时,我们将该度量值移交给另一个计算时间的对象和一个显示时间的单独对象(如果适用于该情况)。被称为干扰物的答案具有标签和值,它们可以根据用户选择赋予适当的度量。例如,如果用户选择“d”,则其值“4”将转移到存储用户选择的度量。

一旦用户提交了答案,我们就会遍历问题的所有度量并将其发送到数据库。如果那些不被视为一个集合(在这种情况下,一个Vector),我们必须确切地知道每个问题存储的具体措施,每个问题将有一个非常不同的结构,我们必须挖掘。因此,如果循环收集是您的问题,我认为您应该重新审视这个想法。它节省了大量代码,并且比“var1”,“var2”,“var3”更高效。

如果您认为部分是unweildy的部分是您必须做的类型检查,因为字面上任何东西都可能存在,那么只要您至少使用Flash Player 10,Vector就可以成为一个很好的解决方案。

因此,总结如下:

  1. 当你有很多相关的属性时,写一个Class,将所有相关的碎片保存在一起(比如我的问题)。
  2. 当对象具有全部相同或非常相似的0-n“事物”时,使用某种类型的集合(例如数组或向量),以允许您作为一组迭代它们并执行相同的操作对每个问题进行操作(例如,每个问题都是较大分组的一部分,允许依次呈现每个问题,每个问题都有一些干扰者和另一个措施。
  3. 这两个概念一起使用,应该有助于保持信息整洁有序。

答案 1 :(得分:0)

虽然我确信有很多种方法可以保持阵列直线,但我找到了一种适合我的方法。最重要的是,它将大量信息折叠到一些我可以解析为XML文件或其他存储方法的数组中。我将此方法称为“索引数组系统”。

实际上有多种方法可以做到这一点:创建少数一维数组,或创建二维(或更高)数组。两者都同样有效,所以选择最适合您代码的那个。我只会在这里展示一维方法。那些熟悉数组的人可能会想出如何重写它以使用更高维数组。

我使用的是Actionscript 3,但这种方法几乎适用于任何编程或脚本语言。

在这个例子中,我试图保持不同“活动”的各种“属性”。在这种情况下,我们会说这些属性是Level,High Score和Play Count。我们将活动称为弹球,单词搜索,迷宫和记忆。

此方法涉及创建多个数组,每个属性一个,并创建包含用于每个活动的整数“key”的常量。

我们将从整数创建常量开始。常量适用于此,因为我们在编译后永远不会更改它们。我们放入每个常量的值是索引,相应的数据将始终存储在数组中。

const pinball:int = 0;
const wordsearch:int = 1;
const maze:int = 2;
const memory:int = 3;

现在,我们创建数组。请记住,数组从零开始计数。由于我们希望能够修改值,因此应该是常规变量。

注意,我正在将数组构造为我们需要的特定长度,并在每个插槽中使用所需数据类型的默认值。我在这里使用了所有整数,但你可以使用你需要的任何数据类型。

var highscore:Array = [0, 0, 0, 0];
var level:Array = [0, 0, 0, 0];
var playcount:Array = [0, 0, 0, 0];

因此,我们为每个属性提供了一致的“地址”,我们只需创建四个常量和三个数组,而不是12个变量。

现在我们需要创建使用该系统读取和写入数组的函数。这就是系统的真正美感所在。如果你想从这个类之外读/写数组,请确保这个函数是在公共范围内编写的。

要创建从数组中获取数据的函数,我们需要两个参数:活动的名称和属性的名称。我们还想设置此函数以返回任何类型的值。

  

GOTCHA警告:在Actionscript 3中,这不适用于静态类或函数,因为它依赖于“this”关键字。

public function fetchData(act:String, prop:String):*
{
    var r:*;
    r = this[prop][this[act]];
    return r;
}

奇怪的代码r = this[prop][this[act]],只是使用提供的字符串“act”和“prop”作为常量和数组的名称,并将结果值设置为r。因此,如果你给函数提供参数(“迷宫”,“高分”),那么代码基本上就像r = highscore[2]一样(记住,this[act]返回分配给它的整数值。)

写入方法的工作方式基本相同,只是我们需要一个额外的参数,即要写入的数据。这个论点需要能够接受任何

  

GOTCHA警告:使用严格类型语言的系统的一个重要缺点是您必须记住要写入的数组的数据类型。编译器无法捕获这些类型错误,因此如果尝试写入错误的值类型,程序将只会抛出致命错误。

     

一个聪明的方法是为不同的数据类型创建不同的函数,因此在参数中传递错误的数据类型将触发编译时错误。

public function writeData(act:String, prop:String, val:*):void
{
    this[prop][this[act]] = val;
}

现在,我们还有一个问题。如果我们传递不存在的活动或属性名称会发生​​什么?为了防止这种情况,我们只需要一个功能。

此函数将通过尝试访问它来验证提供的常量或变量键,并捕获导致的致命错误,而不是返回false。如果密钥有效,则返回true。

function validateName(ID:String):Boolean
{
    var checkthis:*
    var r:Boolean = true;

    try
    {
        checkthis = this[ID];
    }
    catch (error:ReferenceError)
    {
        r = false;
    }

    return r;
}

现在,我们只需要调整其他两个函数来利用它。我们将函数的代码包装在if语句中。

如果其中一个键无效,该函数将不执行任何操作 - 它将无提示失败。要解决这个问题,只需在else构造中添加一个跟踪(a.k.a.print)语句或非致命错误。

public function fetchData(act:String, prop:String):*
{
    var r:*;

    if(validateName(act) && validateName(prop))
    {
        r = this[prop][this[act]];
        return r;
    }
}

public function writeData(act:String, prop:String, val:*):void
{
    if(validateName(act) && validateName(prop))
    {
        this[prop][this[act]] = val;
    }   
}

现在,要使用这些功能,您只需要使用一行代码。例如,我们会说GUI中有一个显示高分的文本对象,称为txtHighScore。为了这个例子,我省略了必要的类型转换。

//Get the high score.
txtHighScore.text = fetchData("maze", "highscore");

//Write the new high score.
writeData("maze", "highscore", txtHighScore.text);

我希望您会发现本教程对排序和管理变量很有用。

(Afternote:你可以用字典或数据库做类似的事情,但我更喜欢这种方法的灵活性。)