web-dev-qa-db-ja.com

reduxにOOPの場所はありますか?

私はオブジェクト指向プログラミングの手法を25年間使用し、過去5年間関数型プログラミングに移行しようとしていますが、複雑なことをしようとすると、常にOOPに頭を悩ませます。特にES6がまともなOOP構文をサポートするようになった今、それは私がものを構築するための自然な方法です。

私は今Reduxを学んでいて、(c.f。 Redux状態のオブジェクトにメソッドを配置する方法は? )クラスインスタンスをレデューサーに配置するのはノーノーであることを理解しています。プレーンなレデューサー状態に加えて計算するための推奨される方法は、セレクターを使用することです(たとえば、再選択を介して)。そしてもちろん、Reactは継承よりもコンポジションを推奨しています( https://facebook.github.io/react/docs/composition-vs-inheritance.htmlredux oopクラスに反応します )。

しかし、メソッドと継承を持つクラスオブジェクトのためのReact/Reduxエコシステムの場所はありますか?

私自身の質問に答えるために、OOPクラスは、同じ場所にデータのプロパティと操作を追加することを推奨します。これは読みやすさには優れていますが、純粋関数にはうまく適合しません。不変のデータ。

OOPを使用する場合、インスタンスを永続化して状態を一定時間維持するという考えを理解する必要がありますか?たとえば、使用するたびに、ストアデータからインスタンス化し、必要な方法を使用して破棄しますか?これにより、OOPクラスを使用するための多くの推進力がなくなる可能性があります。しかし、インスタンスを維持すると、ストアとの同期を維持するのに頭痛の種が発生します。

それで、メソッドを使用したいときは常にセレクターを使用し、継承を使用したいときは常にコンポジションを使用するという答えはありますか?具体的には、Reactコンポーネントで使用するためにReduxストアに保持されているデータを保存および操作する場合を意味します。そして、もしそうなら、それはどこに収まる必要がありますか?セレクターに接続しましたか?私が提案したようにすぐに使い捨てですか?


明確にするためにユースケースを追加する:私のデータは基本的に巨大なグラフです:多くのプロパティとオブジェクト間の多くの関係を持つ多くのオブジェクト。読み取り専用ですが、複雑です。私のオブジェクトは「コンセプト」と呼ばれています。

Reduxに移行する(おそらくばかげた)決定を下す前に、私はクラスを使用して、概念、概念のセット、および概念間の関係を構造化および表現しました。私のクラスには、概念セット、各概念に関する情報、および各概念が関連する他の概念に関する情報をフェッチするための非同期APIロジックが含まれていました。ユーザーがドリルダウンすることを選択した場合、クラスは新しい概念セットを再帰的にフェッチしてインスタンス化します。 Reduxのドキュメントでは、ネストされたデータに対してフラットで正規化された構造( http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html )を推奨しています。これはおそらくストレージに適していますが、私のOOPモデルは、グラフなどのセクションをトラバースするのに適していました。セレクターと不変の状態を使用して頭を悩ませるのに苦労しています。これには、ネストが含まれる可能性があり、サイクルが発生する可能性があります。

私はAPI関連のものに https://redux-observable.js.org/ を正常に使用しています。

たぶん@Sulthanの答えは正しいです:ReduxアプリケーションでOOPテクニックを自由に使用する必要があります。しかし、それでも奇妙に思えます。ストアが変更されると(たとえば、より多くのデータがフェッチされると)、オブジェクトが古くなる可能性があるため、オブジェクトを保持できません。オブジェクトがネストされているがストアが正規化されている場合は、必要なときに(セレクターから)オブジェクトをインスタンス化し、保持しないようにします...

19
Sigfried

自分の質問に、私がやったことを説明することで答えます。

まず、通常のES6クラス構文の代わりに、 stampit を使い始めました。これは、ES6クラスよりも醜いですが、はるかに柔軟性があります。

ただし、主に、私の複雑なオブジェクトは2つの形式で存在します。

  • ストアのプレーンJSオブジェクト
  • インスタンスメソッドを使用する利便性と能力のためのクラス(実際にはスタンプされた)インスタンス。

プレーンオブジェクトへのすべての参照の前に_underscoreを置くという規則を使用します。私の「解決策」は多くの理由で厄介で悪いですが、すべてにセレクターを使用しようとするともっと悪いと思います。興味があれば、プレーンストアオブジェクトをインスタンスに「膨らませる」コード内の場所は次のとおりです。 https://github.com/Sigfried/vocab-pop/blob/localstorage/src/ducks/ ConceptSet.js#L292

更新

Redux状態のPOJOをクラスインスタンス(通常またはスタンピット)に変えることはひどい考えであり、誰かがずっと前に私を止めるべきでした。

私はおそらく@markeriksonの答えを受け入れるべきであり、おそらくRedux-ORMのことは一見の価値がありますが、私がしたことをやらないでください。 (私はいつも、巧妙なハックで学んでいるテクノロジーの「ギャップ」をとても賢く埋めていると思います-そして、そのテクノロジーが私のハックを含まなかった理由を理解したら、混乱を片付けるのに苦痛な月を費やします最初の場所。)

別の更新

から ソフトウェアの作成:はじめに

私たちがやらないことは、関数型プログラミングはオブジェクト指向プログラミングよりも優れている、またはどちらか一方を選択する必要があるということです。 OOP vs FPは誤った二分法です。私が近年見たすべての実際のJavascriptアプリケーションは、FPと= OOP広範囲に。

FPとOOPの組み合わせについて考える良い方法があるようですが、間違いなく、多くの継承なしにいくつかの不変のクラスと構成を使用します。構成に関するこのシリーズは、私のように見えます。学ぶ必要がありました。

8
Sigfried

答えは、それは可能ですが、非常に落胆し、慣用的ではないということです。

Reactは、ライフサイクルを備えたステートフルコンポーネントを実装するために、クラスとReact.Componentの単一レベルの継承に依存していますが、コンポーネントでそれ以上のレベルの継承を行うことは公式には推奨されていません。

Reduxは関数型プログラミングの原則に基づいて構築されています。さまざまな理由から、状態をプレーンなJSオブジェクトおよび配列として保持し、プレーンな関数を使用してアクセス/操作することをお勧めします。

Reduxの上にOOPレイヤーを追加しようとした多くのライブラリー(メソッドがアクションクリエーターとリデューサーに変換されるクラスなど)を確かに見ました。それらworkですが、Reduxの全体的な精神に間違いなく反しています。

私は実際に Redux-ORM というライブラリを使用しています。これによりファサードとして機能するモデルクラスを定義できます。ストア内のプレーンなJSオブジェクト。しかし、私が見た他の多くのライブラリとは異なり、Reduxの動作を変更しようとするのではなく、withReduxで動作します。 Redux-ORMがどのように機能するか、どのように使用するか、そしてなぜそれがまだかなり慣用的であるかについて、ブログ投稿で説明しました 実用的なRedux、パート1:Redux-ORMの基本 および 実用的なRedux、パート2:Redux-ORMの概念と手法 。全体として、Reduxストアの関係と正規化されたデータの管理を支援するための優れたツールです。

最後に、私は現在、Reduxが必要とする実際の技術的制限(およびその理由)と、あなたがどのように意図されているかについて説明するブログ投稿に取り組んでいますReduxを使用するのに対し、Reduxを使用する方法可能性。私は来週かそこらでそれを上げることを望んでいます-目を離さないでください http://blog.isquaredsoftware.com

10
markerikson

この質問は少し意見に基づいていますが、コアポイントに集中しましょう。

関数型プログラミングとOOPの間に矛盾はありません。同じプログラミングパターンを使用する必要があります。関数型プログラミングでクラス(継承あり)を不変に保つ場合は、問題なく使用できます。

私の主張を証明するために、状態をreduxに保つために多くの人が使用する人気のあるライブラリ Immutable.js は、クラスで構成されています。 )。そして、それらのクラスには継承があります(例:OrderedSet extends Set)。

また、ほとんどのReactコンポーネントはクラスであり、継承も使用することに注意してください(... extends React.Component)。

1
Sulthan