「ラッパー」・「ラップする」・「ラッピング」とは?意味などを解説!

この記事ではプログラミングの分野でよく使う用語「ラッパー」・「ラップする」・「ラッピングについて、

  • 「ラッパー」・「ラップする」・「ラッピング」の意味
  • 「ラッパー」を用いるメリット

などを図を用いて分かりやすく説明するように心掛けています。ご参考になれば幸いです。

「ラッパー」・「ラップする」・「ラッピング」の意味

「ラッパー」・「ラップする」・「ラッピング」の意味

プログラミングの分野では、既存のコード(関数、クラス、ライブラリなど)を包んで、別の形で提供することがあります。この手法を「ラップする」とか「ラッピング(wrapping)」といい、ラップして作成した新しいクラスや関数を「ラッパー(wrapper)」といいます。

ラップした作成した新しいクラスは「ラッパークラス」、新しい関数は「ラッパー関数」や「ラップ関数」と呼んだりします。

「ラッパー(wrapper)」という用語は、「包むという意味のラップ(wrap)」と「行為者を示す接尾辞の-er」を組み合わせた言葉です。つまり、「ラッパー(wrapper)」は「ラッピングするもの」または「包むもの」という意味になります。

「ラッパー」を用いるメリット

「ラッパー」を用いる主なメリットを以下に示します。

「ラッパー」を用いるメリット

  • 仕様変更に対して強くする
  • 既存の関数を使いやすくする
    • 引数の数を変える
    • 既存の関数の戻り値を扱いやすい形に変更する
    • 既存の関数の名前を変える
  • 機能を追加する
    • 既存の関数の前後に処理を追加する

次に、各メリットについて説明します。

仕様変更に対して強くする

通常、関数に仕様変更があった場合、その関数を呼び出しているコードに影響が及びます。

例えば、functionAという関数が存在し、その名前がfunctionBに変わったとします。この場合、functionAを呼び出している全てのコードは、新たにfunctionBを呼び出すように変更する必要があります。また、仮にfunctionAからfunctionBに変わった際に、内部実装が変わり、引数や戻り値が変化した場合、それに対応した修正が必要になります。

ラッパーを使うことで、仕様変更による影響を最小限に抑えることができます。以下のJavaScriptのプログラム例では、functionAからfunctionBに切り替わったときも、ラッパー関数(wrapperFunction)を通じて機能を利用している限りは関数名を変える必要がありませんし、関数の内部実装が変わっている場合でも、ラッパー関数(wrapperFunction)でその影響を吸収すれば、仕様変更による影響を抑えることができます。

// 元の関数
function functionA() {
    return 10;
}
// ラッパー関数
function wrapperFunction() {
    // functionAを呼び出し、その結果を利用する。
    let number = functionA();
    return number;
}


// functionAの仕様が変更され、functionBという新しい関数になった。
function functionB() {
    return 5;
}
// ラッパー関数を更新して、関数が変わった際の影響を吸収する。
function wrapperFunction() {
    // functionAからfunctionBに変わったことの影響を吸収する処理を記述する。
    let number = functionB() * 2;
    return number;
}

// wrapperFunction関数を呼び出しているコードには影響がない。wrapperFunction()は常に10を返している。
wrapperFunction();

既存の関数を使いやすくする(引数の数を変える)

引数が多くて扱いにくい関数でも、デフォルトの引数をラッパー内に設定することで、呼び出し時の引数を減らすことができます。

例えば、4つの引数をとる関数complexFunctionがあったとします。このうちの3つの引数は、ほとんどの場合同じ値を取ると仮定しましょう。この場合、ラッパー関数(wrapperFunction)を用いてこれらの引数にデフォルト値を設定すれば、の呼び出し時には必要な1つの引数だけを指定すれば良いようにすることができます。

以下にJavaScriptのプログラム例を示します。

// 引数が多い関数
function complexFunction(a, b, c, d) {
    return a + b + c + d;
}

// ラッパー関数
function wrapperFunction(a) {
    // complexFunction関数の引数b, c, dはほとんどの場合同じ値を取ると仮定して、それらの値をラッパー関数内で設定
    return complexFunction(a, 2, 3, 4);
}

// 呼び出し時は1つの引数だけでよい
let result = wrapperFunction(1);  // complexFunction(1, 2, 3, 4)と同等

既存の関数を使いやすくする(既存の関数の戻り値を扱いやすい形に変更する)

既存の関数が複雑なデータ構造や期待しない形式で結果を返す場合、その結果を扱いやすい形に変換するためにラッパーを作成することがあります。この手法は、特にライブラリなどのAPIが提供する結果を、自分のアプリケーションで使いやすい形に変換するのに役立ちます。

以下のJavaScriptのプログラム例では、元の関数originalFunctionはJSONデータを返しています。JSONデータではなくオブジェクトの戻り値が欲しいので、ラッパー関数(wrapperFunction)を作成して、JSONデータをオブジェクトに変換して返しています。このようにラッパーを使用すると、関数の戻り値をより扱いやすい形に変換することができます。

// JSONデータを返す関数
function originalFunction() {
    return '{"name":"Taro", "age":30, "city":"Japan"}';
}

// ラッパー関数:JSONデータの代わりにオブジェクトを返す
function wrapperFunction() {
    const jsonString = originalFunction();
    const jsonObject = JSON.parse(jsonString);
    return jsonObject;
}

// 呼び出し時はオブジェクトを受け取る
let result = wrapperFunction();  // {name: "Taro", age: 30, city: "Japan"}

既存の関数を使いやすくする(既存の関数の名前を変える)

「既存の関数名が他のコードと名前が衝突する」、「関数名が複雑で覚えにくい」、「関数名がその機能を適切に表現していない」などの理由で関数名を変えたい場合があります。

このような場合、ラッパーを用いて関数名を変更することが有用です。ラッパー関数を作成すれば、その関数の役割をより直感的に理解できる名前にすることができます。

以下にJavaScriptのプログラム例を示します。

// 複雑な名前の関数
function complicatedFunctionName(x, y) {
    return x + y;
}
// ラッパー関数:より理解しやすい名前にする
function add(x, y) {
    return complicatedFunctionName(x, y);
}
// 使用例:add関数は、complicatedFunctionNameと同じ機能を持つ
let result = add(10, 5);  // 15

機能を追加する(既存の関数の前後に処理を追加する)

ラッパー関数は、元の関数が実行される前後に処理を追加するためにも使用されます。これにより、関数の動作をカスタマイズしたり、ログを取る、エラーハンドリングを行う、関数の実行時間を計測するなどの機能を追加できます。

以下のJavaScriptのプログラム例では、ラッパー関数(wrapperFunction)が既存の関数(existingFunction)をラップしています。wrapperFunction内で、existingFunctionの実行前と実行後にログ出力を行うことで、関数が呼び出されたときの引数と、関数の結果を確認することができます。

// 既存の関数
function existingFunction(x) {
    return x * x;
}

// ラッパー関数
function wrapperFunction(x) {
    // 前処理(ここでは引数の値をログ出力)
    console.log("Function is called with x = " + x);

    // 既存の関数を実行
    var result = existingFunction(x);

    // 後処理(ここでは結果をログ出力)
    console.log("Function result is " + result);

    return result;
}

// 使用例:wrapperFunction関数は、existingFunctionの機能に加え、ログ出力の機能も持つ
let result = wrapperFunction(5); 

// ログ
// Function is called with x = 5
// Function result is 25

本記事のまとめ

この記事ではプログラミングの分野でよく使う用語「ラッパー」・「ラップする」・「ラッピングについて、以下の内容を説明しました。

  • 「ラッパー」・「ラップする」・「ラッピング」の意味
  • 「ラッパー」を用いるメリット

お読み頂きありがとうございました。