過去数年間で、私が使用したい言語はますます「機能的」になりつつあります。現在、C#、F#、Scalaなどの「ハイブリッド」言語を使用しています。ドメインオブジェクトに対応するクラスを使用してアプリケーションを設計し、これによりコーディングがより簡単に、より正確に、より安全になる機能機能を使用します(特にコレクションの操作時または関数の受け渡し時)。
ただし、パターンを設計する場合、2つの世界は「衝突」します。私が最近直面した具体的な例は、Observerパターンです。アイテムが作成または変更されたときに、プロデューサーに他のコード(「消費者/オブザーバー」、たとえばDBストレージ、ロガーなど)に通知してほしい。
私は最初に次のように「機能的に」それをしました:
producer.foo(item => { updateItemInDb(item); insertLog(item) })
// calls the function passed as argument as an item is processed
しかし、私は今、もっと「OO」アプローチを使用すべきかどうか疑問に思っています。
interface IItemObserver {
onNotify(Item)
}
class DBObserver : IItemObserver ...
class LogObserver: IItemObserver ...
producer.addObserver(new DBObserver)
producer.addObserver(new LogObserver)
producer.foo() //calls observer in a loop
2つのアプローチの長所と短所はどれですか?かつてFPの第一人者が、デザインパターンは言語の制限のためだけにあると言ったことを聞いたことがあり、それが関数型言語にはほとんどない理由です。たぶん、これはその例でしょうか?
編集:私の特定のシナリオでは、私はそれを必要としませんが、..機能的な方法で「観測者」の削除と追加をどのように実装しますか?(つまり、パターンのすべての機能をどのように実装しますか?)たとえば、新しい関数を渡すだけですか?