[オリジナル]浅談非主流多態


もっと読む
従来のOOPモデルに基づいていないいくつかのプログラミング言語では、クラスとオブジェクトとの関係がないかまたは強調されていないため、多状態を実現する方法はクラス間の継承またはインターフェースによって実現することができない.このような状況では、手紙式プログラミングとメタプログラミングの思想が我々にヒントを与えるかもしれません.本論文では、クラスもインタフェースもないJavaScriptを用例として表現しています.実例コードには最も基本的な論理しか含まれていません.あまりにも多くのフォールトトレランス処理は含まれていません.コードはNode.jsで実行されます.
 
最大値最小値
まず一番簡単な問題から着手できます.一山の数字の中の最大値と最小値を探します.ここでは、一連の整数を配列の中に置いて、リングアルゴリズムで実現すると仮定しますが、実は最大値と最小値の2つの動作を検索する他の部分論理は同じで、唯一の違いは2つの値の大きさを比較する論理です.最大値を探す時、私達は新しい値が大きいかどうかを判断します.最小値を求める時は逆です.
 
コードを先に見ます
var numbers = [2,3,1,5,4];

var maximum = function(max, current) {
    return max > current ? max : current;
};
var minimum = function(min, current) {
    return min < current ? min : current;
};

console.log(numbers.reduce(maximum));
console.log(numbers.reduce(minimum));
console.log(numbers);
 
以上のコード出力結果:
5
1
[2,3,1,5,4]
 
私たちはmaxinumとmininumの二つの関数を定義しました.それらは二つの値を受け入れます.これまでの最大値と、まだ比較していない新しい値です.その後、比較論理を実行し、より大きな論理またはより小さい論理を返します.
 
ES 5標準におけるAray.prototype.reduce関数を用いて、整数グループを逓減演算し、最大値または最小値を計算するための関数をパラメータとしてreduceに伝えました.reduceが実行を開始すると、前回のreduceの値を関数として最初のパラメータに送り、現在処理中の値を第二のパラメータに伝えます.毎回reduce実行時には、maximumまたはmininumを用いて結果を得るように設定されていますので、実際には、私たちの操作は1ラウンドごとに大きな数を選んで、行列の中から次の数と比較して、このように類推します.
 
reduceの詳細については、下記を参照してください.https://developer.mozilla.org/en/JavaScript/Reference/Global_Object/Aray/Reduce
 
並べ替え
また、順序付け問題も基本的に同じで、昇順と降順の論理もほとんど同じで、ただ二つの数の大きさの部分を比較するだけで違っています.
 
コードを先に見ます
var numbers = [2,3,1,5,4];

var ascendant = function(left, right) {
    if (left == right) return 0;
    return left > right ? 1 : -1;
};
var descendant = function(left, right) {
    if (left == right) return 0;
    return left < right ? 1 : -1;
};

console.log(numbers.concat().sort(ascendant));
console.log(numbers.concat().sort(descendant));
console.log(numbers);
 
以上のコードの出力結果:
[1,2,3,4,5]
[5,4,3,2,1]
[2,3,1,5,4]
 
コードにはascedantとdescendantの2つの関数が定義されており、それらはいずれも2つのパラメータを受け入れることができ、着信する2つの数の大きさに応じて、それぞれの0、−1または1を返します.この二つの関数は現在はデジタルタイプだけを扱っています.複合データを次のセクションでどう処理するかを説明します.
 
ES 3において、配列を並べ替えるためにAray.prototype.sort関数が定義されています.この関数は他のコントラスト関数をその最初のパラメータとして受け入れ、このコントラスト関数に隣接する2つの値を伝えます.このコントラスト関数によって、2つの数の大きさを比較する論理が実行されます.最後の戻り値は0に等しいかどうか、0以上または0未満の3つの場合、配列の並べ替え方法を決定します.
 
sortを呼び出す前にもconcatを1回実行しています.これはコピー配列に使いますが、怠けたい時に使うテクニックです.ソトは配列を呼び出す順番を変えますので、元の配列が変更されないようにコピーします.これは関数の戻り結果に対する外部状態と可変配列の影響を回避するための函式プログラミングの思想の一つである.
 
ソトの詳細については、以下を参照してください.https://developer.mozilla.org/en/JavaScript/Reference/Global_Object/Aray/sort
 
複合データの種類の並べ替え
実装アプリケーションでは、しばしば、オブジェクト配列のような複合データタイプからなる配列に遭遇する.この場合は、各オブジェクトの値に従って並べ替えを行う必要があります.下記のコードの中にいくつかのプレイヤープレイヤーのプレイヤープレイヤーがいるように、攻撃力ofensiveを昇順に並べ、防御力defensiveを降順に並べます.
 
コードは以下の通りです
var players = [
    {offensive: 2, defensive: 5},
    {offensive: 1, defensive: 1},
    {offensive: 3, defensive: 3},
    {offensive: 5, defensive: 2},
    {offensive: 4, defensive: 4},
];

var sortBy = function(fieldName, orderDirection) {
    var field = fieldName;
    var order = orderDirection < 0 ? -1 : 1;
    return function(left, right) {
        if (left[field] == right[field]) return 0;
        return (left[field] > right[field] ? 1 : -1) * order;
    };
};

console.log(players.concat().sort(sortBy("offensive", 1)));
console.log(players.concat().sort(sortBy("defensive", -1)));
console.log(players);
 
以上のコード出力結果:
[{offnsive:1,defensive:1}
{offnsive:2,defensive:5}
{offnsive:3,defensive:3}
{offnsive:4,defensive:4}
{offnsive:5,defensive:2}
[{offnsive:2,defensive:5}
{offnsive:4,defensive:4}
{offnsive:3,defensive:3}
{offnsive:5,defensive:2}
{offnsive:1,defensive:1}
[{offnsive:2,defensive:5}
{offnsive:1,defensive:1}
{offnsive:3,defensive:3}
{offnsive:5,defensive:2}
{offnsive:4,defensive:4}
 
sortByという関数は、導入された2つのパラメータに従って、順序付けのための属性と、昇順1または降順−1と、ソト関数に提供される2つのオブジェクトを比較するための関数を動的に生成することができる.
 
この例では、関数をデータとして、動作中に動的に生成し、転送するために、函式プログラミングとメタプログラミングの思想を同時に使用している.このように動的脚本の柔軟性を利用して、多状態を実現する目的を達成していると同時に、従来のOOPではあまりにも精巧で複雑なクラスとインターフェースの設計を使用する必要がない.
 
皆様のご指導と交流を歓迎します.