お久しぶりです。白々です。
先日エンジニアの先輩にデザインパターンをご存知でない!?という冷静なツッコミを頂き、その後結城浩さんが書かれた「Java言語で学ぶデザインパターン入門」を渡されたので勉強することにしました。
ただ、本を一読しても覚えられないので覚書として記事にしようと思いました。
完走できるように頑張ります。
また、「Java言語で学ぶデザインパターン入門」には、サンプルプログラムも有りますが、著作権の都合上省かせて頂きます。御了承ください。
#そもそもデザインパターンって?
「Java言語で学ぶデザインパターン入門」では、
デザインパターンは、日々書いているプログラムを新しい観点から見直し、再利用しやすく、機能拡張しやすいソフトウェアを作るための有益な技法なのです。
と記載が有りました。
この記事を読んでいる皆さんは、プログラムをたくさん書いていると似たようなコードを書くことは有りませんか?私はあります。なので良く部分的にコピペしながらコードを書いています。
このようにプログラムでよく使われるパターンってたかだか23パターンしか無いよね?と言った4人の人がいて、the Gang of FourやGoFと呼ばれているそうです。
GoFは、23個のパターンに名前をつけてカタログと整理した本が「Design Patterns: Elements of Reusable Object-Oriented Software」だそうです。
該当の本について触れているリンクは以下です。
https://en.wikipedia.org/wiki/Design_Patterns
グダグダ書きましたが、再利用性と機能拡張しやすいプログラムを書くために、プログラムの書き方のパターンを覚えようねってことだと思います。
#第1部 デザインパターンに慣れる
##第1章 Iterator —1つ1つ数え上げる
for文やwhile文のように、順序をつけて繰り返し処理するプログラムがあります。
このように繰り返し処理していくパターンをIteratorパターンと言うそうです。
###なんでこんなパターンが必要なの?
「Java言語で学ぶデザインパターン入門」にも記載が有りましたが、配列を使って処理するようなものは、for文を使えばいいという意見もあると思います。
結論を言えば、順に実行するようなものでも抽象化しておけば、実行対象のデータ構造が変わった場合でも、順に実行するメソッドは変更しないで済むということです。
以下は、私が考えた例です。ただし、IteratorインタフェースとAggregateインタフェースは、「Java言語で学ぶデザインパターン入門」に記載があったものを使用しています。
例えば、大学で学生を管理しているとします。
「次を探すメソッド」と「次のオブジェクトを取得するメソッド」を宣言しているIteratorのインタフェースがあるとします。
また、このIteratorのインタフェースを宣言している、Aggregateインタフェースがあるものとします。
1つの学科には複数人の学生がいて、学生は、名前と学籍番号を持っているとします。
学生の学籍番号と名前を管理する学生クラスがあるとし、学科に所属している学生をList型で管理している学科クラスがあるとします。
学科クラスは、Aggregateインタフェースを実装したものとします。
学科クラスの中には、「List型の変数に入っている学生を取得するメソッド」と、「何人の学生がいるのかを取得できるメソッド」と、「学生を追加するメソッド」と、後述の「Iteratorクラスのインスタンスを返しているメソッド」があるものとします。
学科内の学生を学籍番号順に取得する学科Iteratorクラスがあるとします。
この学科Iteratorクラスは、Iteratorのインタフェースを実装したものとします。
この学科Iteratorクラスには、現在どこまで検索したかを管理する整数型の変数aと、「次の学籍番号を持っている学生がいるかどうかを判断するメソッド」と、「学生を取得し、変数aの値にプラス1するメソッド」があるものとします。
この学科Iteratorクラスが、まだ学生がいるかどうか判断するために、学科クラスが持っている「何人の学生がいるかを取得できるメソッド」の値と学科Iteratorクラスの変数aを比較して、変数aの値の方が小さいときまだ学生がいるものとします。
また、学科Iteratorクラスが、学生を取得するときは、学科クラスの「List型の変数に入っている学生を取得するメソッド」を使用するものとします。
このとき、学科クラスで学生の管理方法をList型からArrayList型に変えたとしても、学科Iteratorクラスの実装には影響が無いため、影響範囲が学科クラス内のみとなります。
このようなときにIteratorのデザインは必要とされています。
「Java言語で学ぶデザインパターン入門」には、
>抽象クラスやインターフェースを使ってプログラミングをする考え方を頭の隅に置いておいてください。
という記載が有ったので、忘れないようにします。
###クラス図
例の内容をクラス図で現したものは以下のようになります。
このクラス図は、PlantUMLというもので記載しています。
私が、書いたPlantUMLのコードは以下のGitHubに記載がありますのでReadMeを読んでお使いください。
該当ファイル名は、iterator.txtです。
https://github.com/sirajirasajiki/design_pattern_uml/blob/master/iterator/iterator.txt
PlantUMLのインストール方法と使い方に関しては、後述のappendixに記載しています。
###クラス図を元にPythonで実装
以下に実装したコードを公開しています。Python 3.7で実装しました。
https://github.com/sirajirasajiki/design_pattern_python/tree/master/Iterator
ReadMeは、以下のページにあります。
https://github.com/sirajirasajiki/design_pattern_python/blob/master/README.md
Pythonでのクラスとインターフェースの実装に関しては、後述のappendixに記載しています。
###イテレータの種類
順序つけて繰り返し処理するものは、最初から順に処理する以外にも以下のような種類があります。
- 逆順
- 双方向
- 途中から最後まで処理する
#まとめ
集合体をひとつづつ数えるパターンをIteratorというということが分かりました。
##第1章感想
簡単な処理でも抽象化しておくことで、変更箇所が少なくて済むので楽だなと思いました。
また、クラスを日本語で表現しようと頑張りましたが、割と簡単な概念なのにすごく難しかったので、プログラムって偉大だなと思いました。
後、クラス図は、頭で思い浮かべながら作成するとすごくしんどかったので、紙に書きながらやって行きたいと思います。
後日Pythonでそれっぽく書きます。
Pythonでそれっぽく書きました。
#最後に
何か間違っているところがあれば、ご指摘いただけると嬉しいです!
#appendix
##PlantUMLに関するサイト
PlantUMLのインストールの時にお世話になったサイトは以下です。
https://qiita.com/kohashi/items/1d2c6e859eeac72ed926
PlantUMLを書くときにお世話になっているサイトは以下です。
https://qiita.com/ogomr/items/0b5c4de7f38fd1482a48
##Pythonでインターフェースとそのインターフェースを継承したクラスの作成時に参考にしたサイト
https://qiita.com/ukisoft/items/b7c410b96dde1922a2d0#comments
https://qiita.com/baikichiz/items/7c3fdb721bb72644f638
https://qiita.com/ttsubo/items/97d7dd23e8f939c81d78
##次回の記事
https://qiita.com/sirajirasajiki/items/0d58a3b9fe9bdb460d0d
#更新履歴
2020/2/22 クラス図の項目を追加
2020/2/24 クラス図を元にPythonにて実装、Pythonのメソッドの命名規則に合わせてクラス図の修正を行った。
2020/2/25 appendixの追加。
2020/2/27 クラス図に記載しているGitのリンクの変更