オブジェクト指向入門 ~クラスのメリットとは~

スポンサーリンク

対象読者

  • 手続き型プログラミングの経験しかない方
  • クラスの文法は把握したが、特にクラスを使うメリットを感じられない方

結論

手続き型プログラミングでは成し遂げられないクラスのメリットは以下である。

  1. グローバルなスコープを制限できる
  2. 名前の衝突を避けられ、短い名前にできる
  3. 引数を削減して、関数の呼び出しを簡素にできる
  4. たくさん作る

根拠

そもそも、今までのコーディングで何の問題もなかったし、クラス等のオブジェクト指向を敢えて取り入れるメリットが感じられない方もいるかもしれない。しかし、現在の主流はオブジェクト指向であり、オープンソースのライブラリやフレームワーク等もオブジェクト指向で書かれていることが多い。手続き型プログラミングには限界があるからだ

そこで、私がオブジェクト指向初心者の頃に感じたクラスのメリットを述べる。以下の説明は、手続き型プログラミングの延長で理解できる内容だ。オブジェクト指向でよくある説明の「猫クラス、犬クラス」がどうとか、ポリモーフィズムが何だとか、そういう解説に飽き飽きした方に、地に足のついたメリットを解説する。

1.グローバルなスコープを制限できる[1]

クラスによって、グローバルな変数や関数を分割して管理することができる。多数のファイルをフォルダに分けるのと同様のことだ。そうすることにより、一度に把握すべき情報量を削減でき、プログラムの把握を容易にできる。

クラスには値を持たせることができる(メンバ変数、インスタンス変数、プロパティなどと呼ばれるが、以後プロパティと呼ぶ)。プロパティは以下の意味で、グローバル変数とローカル変数の中間の変数だ。

  • クラス内の関数(以後、メソッドと呼ぶ)からはプロパティが自由に呼べるため、関数に対するグローバル変数みたいだ
  • クラスから生成した実体(インスタンス)を経由しない限り、外からプロパティを参照できないため、外部からのアクセスが制限されたという意味で、関数内のローカル変数みたいだ

手続き型の言語でも、モジュール化は可能であり、グローバル変数や関数をまとめることができる。しかし、そのモジュールを複数個importした場合、その制御プログラム内でモジュールの内容が全て展開されてしまうため、やはりプログラムの把握が困難になる。複数個のフォルダをマージすると、大量のファイルが1つのパスに集まり、雑多な感じがすることと同じだ。

一方、複数個のクラスをインスタンス化して呼び出しても、プロパティやメソッドはそのインスタンス内にあり、制御プログラム内でゴチャゴチャになることはない。

2.名前の衝突を避けられ、短い名前にできる

意味合い的に似たような処理(関数)が複数ある場合、手続き型プログラミングでは、どう区別するだろうか。prefixやsuffixを名前に付与するにより、区別する。しかし、クラスを用いれば、クラス名がprefixになるため、それらを区別でき、かつ、関数(メソッド)名が短くなって良い。

  • write_csv(list)  -> csv.write(list)
  • write_json(list) -> json.write(list)

3.引数を削減して、関数の呼び出しを簡素にできる

引数の数が4,5個を超えてくると、コードが読みにくくなる。一度に把握しなければならない情報が多くなるからだ。1.でも述べたように、プロパティはメソッド間で共有される。引数としてではなく、プロパティとして情報を与えることにより、引数の数を削減できる。

func_a(x, y, z, a, p)

func_b(x, y, z, b, q)

みたいに、複数の関数に同じ引数を与えるとする。

foo = new Foo(x, y, z)

foo.a(a, p)

foo.b(b, q)

こちらの方が読みやすい。

4.たくさんつくる[2]

グローバル変数はプログラム内に一意に存在する。故に、同じ意味のグローバル変数を複数個使いたい場合、その数だけ定義をしなければならない。しかし、クラスを用いれば、いちいちグローバル変数を定義しなくても済む。

ファイルオープンを同時に複数回行いたいとする。手続き型プログラミングの場合、複数個のファイル番号を変数で定義しなければならない。一方、ファイルIOのクラスにファイル番号のプロパティを持たせておけば、この問題を解決できる。クラスを実体化(インスタンス化)したときに、自動的にファイル番号を生成し、ファイル番号を個別に持たせることができるからだ。

以下に、fortran90 likeな疑似コードでの複数ファイルへの同時書き込みのコードを示す。

fileNo1 = 1
fileNo1 = 2
fileNo1 = 3

open(fileNo1, file=filename1)
open(fileNo2, file=filename2)
open(fileNo3, file=filename3)

write(fileNo1, *) "Hello1"
write(fileNo2, *) "Hello2"
write(fileNo3, *) "Hello3"

close(fileNo1)
close(fileNo2)
close(fileNo3)

一方で、クラスによる複数ファイルへの同時書き込みのコードを示す。

file1 = new File()
file2 = new File()
file3 = new File()

file1.write("Hello1")
file2.write("Hello2")
file3.write("Hello3")

file1.close()
file2.close()
file3.close()

ファイル数の増加に対して、より簡単に対処できるのはクラスによる表現である。

参考

  1. リーダブルコード [Dustion Boswell]
  2. オブジェクト指向でなぜつくるのか [平澤 章]

コメント

タイトルとURLをコピーしました