私のプロジェクトには、不可避的に何百もの変数を含むクラスがあり、それらを常にまっすぐにしておく必要があります。たとえば、クラス内で繰り返し発生する一連の「アイテム」について、特定の種類の変数を常に追跡する必要があります。これらの変数を複数のクラスに配置すると、多くの混乱が生じます。
特にデータを保存するときに、変数を適切に並べ替えて、おかしくならないようにするにはどうすればよいですか?
私のプロジェクトには、不可避的に何百もの変数を含むクラスがあり、それらを常にまっすぐにしておく必要があります。たとえば、クラス内で繰り返し発生する一連の「アイテム」について、特定の種類の変数を常に追跡する必要があります。これらの変数を複数のクラスに配置すると、多くの混乱が生じます。
特にデータを保存するときに、変数を適切に並べ替えて、おかしくならないようにするにはどうすればよいですか?
何か不足していますか?Actionscript はオブジェクト指向言語であるため、何百もの変数が存在する可能性があります。何を追跡しているのかわからないので、具体的なアドバイスをするのは難しいですが、私が取り組んでいる現在のプロジェクトの例を次に示します。これは、雇用前の評価を構築するためのプラットフォームです。
基本単位は質問です。質問には、ステム、ステータス バーに表示できるテキスト、回答のコレクション、特定のタイプの質問でユーザーが行ったことについて追跡している測定値のコレクションがあります。
測定値も独自のタイプのオブジェクトであり、時間制限を追跡するために使用されるものとそうでないものの 2 つの "フレーバー" があります。メジャーには名前 (データベースのどこに書き戻すかがわかります) と値 (何を書き戻すかがわかります) があります。時限のものには、時間制限のプロパティもあります。
質問の時間を計る必要がある場合は、時間をカウントする別のオブジェクトと、時間を表示する別のオブジェクト (状況に応じて適切な場合) にその測定値を渡します。ディストラクターと呼ばれる回答には、ユーザーの選択に基づいて適切な尺度に与えることができるラベルと値があります。たとえば、ユーザーが「d」を選択すると、その値「4」がユーザーの選択を格納するメジャーに転送されます。
ユーザーが回答を送信すると、質問のすべてのメジャーをループしてデータベースに送信します。それらがコレクション (この場合はベクトル) として扱われなかった場合、各質問に格納されている特定の測定値を正確に知る必要があり、各質問は非常に異なる構造を持っているため、掘り下げる必要があります。 . したがって、コレクションのループが問題である場合は、その考えを再検討する必要があると思います。多くのコードを節約し、「var1」、「var2」、「var3」よりもはるかに効率的です。
扱いにくいと思う部分が、文字通り何でもそこにある可能性があるために実行しなければならない型チェックである場合は、少なくとも Flash Player 10 を使用している限り、Vector が適切なソリューションになる可能性があります。
これら 2 つの概念を一緒に使用すると、情報を整理して整理するのに役立ちます。
配列をまっすぐに保つ方法はたくさんあると確信していますが、私にとってうまくいく方法を見つけました。何よりも、大量の情報をいくつかの配列にまとめて、XML ファイルまたはその他のストレージ メソッドに解析できるようにします。私はこの方法を「添字配列システム」と呼んでいます。
これを行うには、実際には複数の方法があります。一握りの 1 次元配列を作成するか、2 次元 (またはそれ以上) の配列を作成します。どちらも同じように機能するため、コードに最適な方を選択してください。ここでは 1 次元の方法のみを示します。配列に精通している人は、これを書き直してより高次元の配列を使用する方法をおそらく理解できるでしょう。
私は Actionscript 3 を使用していますが、このアプローチはほとんどすべてのプログラミング言語またはスクリプト言語で機能するはずです。
この例では、さまざまな「アクティビティ」のさまざまな「プロパティ」をそのまま維持しようとしています。この場合、これらのプロパティは、レベル、ハイ スコア、およびプレイ カウントであるとします。アクティビティをピンボール、単語検索、迷路、記憶と呼びます。
この方法では、プロパティごとに 1 つずつ、複数の配列を作成し、各アクティビティに使用される整数の「キー」を保持する定数を作成します。
定数を整数として作成することから始めます。コンパイル後に定数を変更することはないため、定数はこれで機能します。各定数に入れる値は、対応するデータが常に配列に格納されるインデックスです。
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 個の変数ではなく、4 つの定数と 3 つの配列を作成するだけで済みました。
次に、このシステムを使用して配列を読み書きする関数を作成する必要があります。これが、システムの真の美しさの出番です。このクラスの外部から配列を読み書きする場合は、この関数がパブリック スコープで記述されていることを確認してください。
配列からデータを取得する関数を作成するには、アクティビティの名前とプロパティの名前の 2 つの引数が必要です。また、この関数を設定して、任意の型の値を返すようにします。
注意事項: 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 に設定します。したがって、関数にパラメーター (「maze」、「highscore」) を入力すると、そのコードは基本的に次のように動作します (割り当てられた整数値r = highscore[2]
を返すことを思い出してください)。this[act]
書き込みメソッドは基本的に同じように機能しますが、1 つの追加の引数 (書き込むデータ) が必要です。この引数は、任意の引数を受け入れることができる必要があります
注意点: 厳密な型付け言語を使用するこのシステムの重大な欠点の 1 つは、書き込み先の配列のデータ型を覚えておく必要があることです。コンパイラはこれらの型エラーをキャッチできないため、間違った値の型を書き込もうとすると、プログラムは単に致命的なエラーをスローします。
これを回避する 1 つの巧妙な方法は、さまざまなデータ型に対してさまざまな関数を作成することです。そのため、引数に間違ったデータ型を渡すと、コンパイル時エラーが発生します。
public function writeData(act:String, prop:String, val:*):void
{
this[prop][this[act]] = val;
}
ここで、もう 1 つ問題があります。存在しないアクティビティまたはプロパティ名を渡すとどうなりますか? これを防ぐには、もう 1 つの関数が必要です。
この関数は、提供された定数または変数のキーにアクセスしようとすることで検証し、結果として生じる致命的なエラーをキャッチして、代わりに false を返します。キーが有効な場合、true を返します。
function validateName(ID:String):Boolean
{
var checkthis:*
var r:Boolean = true;
try
{
checkthis = this[ID];
}
catch (error:ReferenceError)
{
r = false;
}
return r;
}
これを利用するには、他の 2 つの関数を調整する必要があります。関数のコードを if ステートメント内にラップします。
キーの 1 つが無効な場合、関数は何もせず、黙って失敗します。これを回避するには、else コンストラクトに trace (別名 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;
}
}
これらの関数を使用するには、それぞれ 1 行のコードを使用するだけです。例として、txtHighScore というハイ スコアを示すテキスト オブジェクトが GUI にあるとします。例のために、必要な型キャストを省略しました。
//Get the high score.
txtHighScore.text = fetchData("maze", "highscore");
//Write the new high score.
writeData("maze", "highscore", txtHighScore.text);
このチュートリアルが、変数のソートと管理に役立つことを願っています。
(後注: おそらく辞書やデータベースでも同様のことができますが、私はこの方法の柔軟性を好みます。)