Rubyによるデザインパターン その2
第3章Templete Methodを読む
本に出てくる例では何がうれしいのかよく分からなかったので、平行して結城さんの「Java言語で学ぶデザインパターン入門」も片手に読み進めることにする。
さらに残念ながらRuby脳ではないので、とりあえずPythonのコードに書き写しながら学んで行くという以上な遠回りスタイルとなっている。
非常に単純な話で、スーパークラス(本には基底クラスとあった)にロジックを記述し、具体的な処理は、そのクラスを継承したサブクラスで実現するという話。
いい例が思いつかないので、結城さんの本にもあった、文字と文字列を出力するような例を書いてみた。
Javaと比較して、RubyやPythonでデザインパターンを実現するためには若干クセがあることが判明。
その理由の一つが抽象クラスの存在である。
Javaではabstractとfinalを駆使していい感じにスーパークラスとサブクラスでロジックと実際の処理を切り分けられているのに対して、RubyやPythonには抽象クラス自体が多分ないので(適当)、スーパークラスのメソッドを呼び出したら例外を投げるようにすればいいらしい。
私たちにできるもっとも現実的な方法は、抽象メソッドを誰かが呼び出そうとしたときに例外を投げることです。
「Rubyによるデザインパターン」(P58)
class AbstractDisplay(): def open(self): raise Exception, "error" def out(self): raise Exception, "error" def close(self): raise Exception, "error" def display(self): self.open() for i in range(5): self.out() self.close() class CharDisplay(AbstractDisplay): def __init__(self, ch): self.ch = ch def open(self): print("<<") def out(self): print(self.ch) def close(self): print(">>") class StrDisplay(AbstractDisplay): def __init__(self, str): self.str = str self.length = len(self.str) def open(self): for i in range(self.length): print "*", print def out(self): print(self.str) def close(self): self.open() if __name__ == '__main__': a = CharDisplay("a") a.display() hello = StrDisplay("Hello") hello.display()
特徴というかポイント
スーパークラスにロジックを書いて、サブクラスで実際の処理を実現する。
このとき、スーパークラスの設計がポイントとなる。
スーパークラスでは詳細に記述するようにしておけば、それを継承するサブクラスでの実際の処理のための記述量は減るが同時に使い回せるシーンが限定される。
反対に、スーパークラスでは簡易な記述にとどめておけば、それを継承するサブクラスでの実際の処理のための記述量が増えるが同時に多くのシーンで使い回す事ができる。
今回の非常に簡単な例で言えば、openして5回outしてcloseするという一連の処理の記述にとどめているので、それに当てはまるようなものなら何でも継承して使い回す事ができる。
開会式して、5週は走って、閉会式して、とか
入社して、5日働いて、辞めて、とか
か。(適当すぎる)
ん〜、分かったような分からないような。
練習問題が掲載されていない本は表面的な理解はできるけど、なかなか身に付いたという気分には慣れないという罠。
ぼちぼち勉強して行きます。
増補改訂版Java言語で学ぶデザインパターン入門 | |
ソフトバンククリエイティブ 2004-06-19 売り上げランキング : 3121 おすすめ平均 実務でも役立つ、デザインパターンの良書 好評のため改訂増補しています。 初級者から中級者へ Amazonで詳しく見る by G-Tools |