プログラミングパラダイムの違いは、何を中心に整理するか、の違いです。
こんにちは!!
手続き、関数、オブジェクトが繋がっていることについては以前記事にまとめましたが、世の中ではいろんなパラダイムが提唱されているようです!
その中でもうん?と思ったContext Oriented Programmingについて考えてみました。
COPとは?
読みが同じでも、文脈によって意味が決定することがよくあります。
例えば、
「マック買おうぜ」
といった場合、お昼時か、Win機で黒い画面叩いてるときかで意味が異なります。
この例のように、呼び出し元の状況に応じて中の動作がかわるのがCOPです。
しかし、これは目新しい概念なのでしょうか?
オブジェクト指向プログラミングではStrategyパターン、関数型プログラミングではクロージャ。
このように、「外から中の動作を動的に変更する」方法は昔から存在します。
ですが、COPが特異なのは、オブジェクト(あるいは関数)を横断して振る舞いを変化させる点です。
たとえば、DBの参照先を動的に変えたい!
でもDAO層なんかないよ!!DatabaseオブジェクトにSQLぶっこんでるよ!!SQLぶっ込んでるコードは星のようにちらばってるよ!!という状況だと非常に欲しいですよね(突っ込みは無しで……)
先の方法が縦のカスタマイズなら、こちらは横のカスタマイズです。つまり、先のパラダイムを置き換える物ではなくて、組み合わせて使うことができるものなのです。
COPのメインコンポーネントはLayerと呼ばれる物です。これにContext(変化させたい実装)をまとめて詰め込んで、Activate(これから使うよという宣言)することによってScope内でのみ切り替えます。疑似言語で書くとこんな感じでしょうか。
activate お昼時
call マック買おうぜ
> おっいいね!!
activate Winの黒い画面と格闘中
call マック買おうぜ
> 高いよ!!
でもそれって…
Aspect Oriented Programmingを思い出しますよね(AspectJとか)
実際、AOPの系譜になるらしいです。
そして、COPの実装に必要な機能を言語レベルで提供しているものもあります。
AspectJ
adviceをプラガブルにするようにコードを書けば、可能なようです(run-time weaving)。
Common Lisp
普通はレキシカルスコープの言語ですが、必要に応じてダイナミックスコープも扱えます。さらにその実装はDeep Bindingのため、定義した部分のスコープを出ると前の値が見えます。上手く使えばCOPの実装に使えそうです。
他のダイナミックスコープ言語も可能かもしれません。
Ruby
2.1で入った例のあれです、Refinementです。モンキーパッチを飼いならす方法ですが、これはほとんどCOP実装と言っていいかもしれません。
JavaScript
prototypeベースの継承をしている場合限定ですが、prototypeを実行時にいじることで実現できます。でも多分v8さんが悲鳴を上げます。
動的にクラス定義をいじれる言語は、ライブラリレベルでCOPを実装可能でしょう。
以上です!!AndroidでAspectJ使ってみたくなってきました(使えるのかな?)よいプログラミングライフを!!!