記憶に残るコードを書く！心理学×脳科学がもたらす抽象化プログラミング

![abstraction.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633992/06323452-3fa8-138f-2aad-49083b686b40.jpeg)

エスプリフォートではただ言語を学ぶだけでなく、積極的に新しい事を取り入れ、保守性、可読性なども考慮したプログラミングを心がけています。
これら磨きあげた技術力が、お客様に高いクオリティでシステムを提供する一助になっています。

# はじめに
今回は「人に優しいプログラミング」をテーマに書いていきます。

プログラムは、コンピュータに理解できる命令を記述したものです｡
そのため、プログラムは極めて具体的なものになります｡

このような特性を持つプログラムは、はたして常に、「人に優しい（分かりやすい）」ものになるでしょうか？
もちろん、そうなるとは限りません｡

以下のプログラム例を元に、考えてみたいと思います｡
プログラム言語はC#を使用します。

## プログラム例（仕様）
商品A、商品B、商品C（全て外税10%）の商品毎の商品名、値段、税込値段、及び合計値段（税込み）を算出して表示する｡

```Program.cs
static void Main(string[] args)
{
    // 商品のリスト
    Dictionary<String, double> items = new Dictionary<String, double>();
    items.Add("商品A", 300d);
    items.Add("商品B", 500d);
    items.Add("商品C", 250d);

    // 商品毎の商品名、値段、税込値段、及び合計値段（税込み）を求める
    double summaryPriceOutTax = 0d;
    for (int i = 0; i < items.Count; i++)
    {
        string itemName = items.ElementAt(i).Key;
        double itemPrice = items.ElementAt(i).Value;
        double itemPriceOutTax = ((items.ElementAt(i).Value) * (1 + 0.1));
        Console.WriteLine("商品名 : " + itemName + ", 値段 : " + itemPrice + ",税込値段 : " + itemPriceOutTax);
        summaryPriceOutTax += itemPriceOutTax;
    }
    Console.WriteLine("合計値段（税込み） : " + summaryPriceOutTax);
}
```

## ...分かりやすい...!?
このプログラムは仕様を満たしており、想定通りに動作します｡

ですが、いかがでしょうか？
パッと見て、分かりやすいプログラム、といえるでしょうか？

プログラムを一通り上から下まで見通しながら処理の流れを追い、何を行っているかを確認する必要がありそうです。

# 人は一度に多くのことを覚えられない
ところで、「マジックナンバー7」というキーワードを聞いたことはありますでしょうか？

これは、アメリカの心理学者ジョージ・ミラーが提唱した、心理学や脳科学の分野として人間の短期記憶の容量に関する理論で、「人が短期記憶で記憶できる情報の塊（チャンク）の数」が5～9(7プラスマイナス2)ぐらいである、ということのようです。[^1]
これは年齢や知能の高さなどによらない普遍的な数字であり、いくら訓練をしても短期記憶の容量を増やすことはできないそうです。

つまりどんなに努力をしても「人は一度に多くのことを覚えられない」ということです。
もし多くのことを覚えるためには、「情報をグループ（塊）として整理しないと多くを覚えていられない」ということです。

## であるならば...
この「人は一度に多くのことを覚えられない」、「情報をグループ（塊）として整理しないと多くを覚えていられない」という観点から考えると、プログラムは、その特性である「極めて具体的な記述」の数が多くなれば多くなるほど、「人にとって分かりやすい」ものからはかけ離れていく、ということになります。

今回の仕様はまだ短いプログラムですが、これが「お客様業務で扱う業務」となると、分かりやすさからさらにかけ離れていくことは明白です｡

## ではどうするか？
では、どうすれば「少しでも人に優しい『記憶に残る』プログラム」を書くことができるでしょうか。

その解決策の１つは「抽象化」です。

# 抽象化とは
「抽象化」とは、ある事象に対して大きく俯瞰的に捉えることを言います。

「抽象化」により、詳細を過度に気にすることなく、全体的に物事を把握することができるようになります｡

# プログラムにおける抽象化とは
以下のプログラム技法が「抽象化」の一例です｡
* メソッドにまとめる
* クラスにまとめる
* ラムダ式を使用する

具体的に見ていきましょう｡

## メソッドにまとめる
メソッドを使用することにより、ある処理（の論理的なかたまり）の中にまとめられるとともに詳細が隠され、処理の流れが分かりやすくなり、結果、「人に優しいプログラム」になります｡

## クラスにまとめる
さらにクラスを使用することにより、お互いに関連するかたまりの中にまとめられる為、プログラムの構造がスッキリし、論理的なグループ（塊）として認識しやすくなります｡

## ラムダ式を使用する
ラムダ式を使用することにより、複雑な処理をまとめると共に、副作用（ある値の変更が他の処理に影響を与えること）を無くす（または減らす）事ができます。

メソッドとクラス、ラムダ式を使用して、先程のプログラムを改善してみます。

```（改善後）Program.cs
static void Main(string[] args)
{
    // 商品クラスを作成し、商品を追加
    Items items = new Items();
    items.Add("商品A", 300d);
    items.Add("商品B", 500d);
    items.Add("商品C", 250d);

    // 商品毎の商品名、値段、税込値段、及び合計値段（税込み）を求めて出力
    items.summaryPriceWithOutTax();
}

// 商品クラス
public class Items
{
    // 商品のリスト
    Dictionary<String, double> items = new Dictionary<String, double>();

    // 商品を追加する
    public void Add(string itemName, double price)
    {
        items.Add(itemName, price);
    }

    // 商品毎の商品名、値段、税込値段、及び合計値段（税込み）を求める
    public void summaryPriceWithOutTax()
    {
        foreach (var item in items)
        {
            Console.WriteLine("商品名 : " + item.Key + ", 値段 : " + item.Value +
                        ",税込値段 : " + tax(item.Value));
        }
        Console.WriteLine("合計値段（税込み） : " + items.Sum(item => tax(item.Value)));
    }

    // 消費税額を算出する
    private double tax(double price)
    {
        return price * (1 + 0.1);
    }
}
```

プログラム全体としては少し長くなってしまいますが、これで分かりやすさは改善され、記憶に残やすくなったと思いますが、いかがでしょうか。

# まとめ
複雑になりがちなプログラムであっても、「抽象化」の技法を使用することで、「人に優しく『記憶に残る』」プログラムにすることは可能です｡

そして「抽象化」の技法は、今回ご紹介した「メソッド」や「クラス」以外にも、数多くあります。

少しでも「人に優しく『記憶に残る』」プログラムを作れるように、日々研鑽を重ねていきましょう。

[^1]: 最近では、「7（±2）」ではなく「4（±1）」という説もあるようです。

https://www.esprit-fort.co.jp/

https://www.esprit-fort.co.jp/recruit/