web-dev-qa-db-ja.com

C ++設計:関数型プログラミングvs OOP

デザインの質問

最近、私はますますFP C++で、主に関数テンプレートとラムダの形で、そして単一の関数名の重いオーバーロードを実行しています。私は本当にFPは明確に定義された操作の一部ですが、注意深くないと、OOPと同様にスパゲッティコードのアンチパターンに簡単に陥る可能性があることにも気づきました(たとえば、循環依存関係は、状態ベースのコードの問題)。

私の質問は、新しい機能を追加することを考えるとき、FPパラダイムとOOPパラダイムのどちらを使用するかをどのように決めるのですか?

問題や設計で不変式を特定することに関係している可能性があると感じていますが、よくわかりません。

たとえば、OOPモデル/現実世界の簡略化なしでは、DogクラスまたはCatクラスが何であるか(その状態は何ですか?そのメソッドは何ですか?)) Otoh、FP POVから、Eat()関数は、動物が食べ物をうんちとエネルギーに変えることを許可するだけです。Eat()が他の何かであると想像するのは(少なくとも私にとっては)困難です。 。

C++の回答をもっと探していますが、この質問は、複数のパラダイムを処理できる任意の言語の任意のサブモジュールに適用できます。

6
kfmfe04

OOPは、気まぐれで破棄して再作成できないという状態がある場合、またはそれが悪いモデルである場合(たとえば、3Dレンダリングを検討する場合)に最適ですの場合、レンダラーの状態は簡単に破壊されて再作成されるわけではなく、パフォーマンスがフレームごとに実行されるのは自殺です。

C++では、ガベージコレクションがなく、多くのFPの手法は、リモートで許容されるパフォーマンスのためにそれに依存しているという事実を追加する必要があります。

Otoh、FP POVから、Eat()関数は、動物が食べ物をうんちとエネルギーに変えることを許可するだけです。Eat()が他の何かであると想像するのは(少なくとも私にとっては)困難です。 。

これは、OOPバリアントと完全に等価です。意味のある違いはありません。

struct Animal { ... };
std::Tuple<Poop, Energy> Eat(Animal*, Food);

そして

class Animal {
public:
    std::Tuple<Poop, Energy> Eat(Food);
};

機能的なバリエーションは、食べた新しい動物を返します。

通常、プログラムを再帰的に分割してモジュール/サブモジュール/クラス/関数とメンバー関数を取得し、可能な場合はそれらの関数またはメンバー関数を機能的に実装することを試みます。

3
DeadMG