2016-07-21 8 views
7

私はFunctional Programming(FP)を読んで遊んできましたが、そのコンセプトは本当に好きですが、ほとんどのアプリケーションにどのように適用するかはわかりません。Functional Programming on App開発の使い方

もっと具体的には、iOSアプリケーションについて説明しましょう。私は、不変のデータ構造や高次関数のような概念のいくつかを使用する方法を見ていますが、FPの主要部分であると思われる副作用を避けるためだけに/ほとんど純粋な関数では動作しません。

ほとんどのアプリは、入力呼び出しの調整、データの表示、データの保存、ネットワーク要求の作成、ある画面から別の画面へのナビゲート、アニメーションの操作を感じています。入力コーディネート

  • すべてのものはFPの不純な機能になり、ボタンのタップ、それらを観察する私がコールするかを決定する必要があるすべての人のための通知、サーバソケットプッシュを、

  • データの表示:ローカルデータベースまたはサーバーからの読み取り(副作用)。
  • データを保存する:上記と同じですが、書き込みします。
  • ネットワークリクエストの作成:明らかです。ここでは、Instagramからリストイメージを取得する例を示します。
  • ナビゲーション:これは基本的に副作用であるView Controllerを提示しています。
  • アニメーション:画面上の何かを変える、副作用。

データを処理する場所はほとんどなく、ほとんどの場合、データベースからいくつかの構造体を取得し、複数の情報をView Controllerで使用される別の構造体に連結します(5あなたがビューに表示される5つのプロパティを必要とすると仮定します)。もちろん、money: Int = 20 to moneyString: String = "US$\(money).00"のような処理をする必要があるかもしれませんが、それだけです。

アプリ開発サイクルでFPを実装できないような気がします。どのように私はそれを達成することができます誰も明確にできますか?多分例を挙げるとよいでしょう。

ありがとうございます。

EDIT:は今、Clean Architectureアイデア以下、私は私のアーキテクチャとして、このようなものを持っている:

enter image description here

入力は、ボタンのクリックなど、彼らはに行く、Viewから来ることができますViewController誰がInteractorに電話するかを決定します。そのInteractorは、いくつかのデータを取得し、Presenter(デリゲートの形式)に渡される表現可能なデータに変換するために、必要なGatewayにアクセスします。最後にPresenterViewを更新して新しいデータを表示します。

さらに、入力はExternalソースから来ることができます。サーバーは、一部のデータが更新されたことを伝え、Viewを更新する必要があります。これは、前の例のようにチェインの残りの部分に続くInteractor(オブザーバーの形式)になります。

唯一のFP部はGatewayのデータを表現可能なデータに変換しています。すべての残りの副作用があります。私は何か間違ったことをしているように感じ、そのコードのいくつかを別々に編成して、より多くのコードを純粋な関数に移すことができるようにする必要があります。

+0

@ Sam Kuhmonen私の質問は、より具体的に更新されました。 –

+0

@ Paulw11質問をより具体的に更新しました。 –

+0

@dfri質問をより具体的に更新しました。 –

答えて

0

ツールボックスには常に複数のツールが存在する必要があります。 FPは、大部分の人が適用されるプログラムの部分に対して(たとえば、MVVCのビューコントローラを介してビュー上にモデルを提示する)大部分の人が持たなければならない優れたアプローチと規律です。

アプリケーション内のすべてに対してFPを使用しようとするのは、おそらく価値のある作業ではありません。データを保持したり、時間の経過を管理したりするとすぐに、状態を処理する必要があります。 「安らかな」サービス(概念的にはFPアプローチの良い候補者でも)は、純粋なFPではなく、何らかの国家の依存関係を持ちます。これはFP実装が不良であるためではなく、外部永続状態を管理する目的があるためです。格納されたデータを「入力」として表示することができますが、サービスのいずれかの側から、反対側は依然として副作用になります(読み取り専用操作を除く)。

MVVCが状態遷移の管理を担当し、コンポーネント間の非FP関係を可能にするという事実を浮かべると、それぞれに小規模なFPパラダイムを実装するのが容易になります。

たとえば、ビューコントローラには、モデル内のデータの変換バージョンを複製または保持する変数はありません。 MVVCコンポーネント間でデリゲートを使用すると、いくつかのケースではFPルールが破られますが、ビューコントローラの機能の範囲内では、それらは入力(状態ではありません)です。コーディングを開始する前にインタラクション図を計画(および描画)することで、懸念をより明確にし、コンポーネント内でFPを壊すような致命的な問題に陥ることはありません。

モデル自体の中で、計算されたプロパティは、FPを確実に遵守するために、長い道のりをとることができます。

いずれにせよ、varステートメントを使用しない場合(これはいくつかの場所で挑戦的になるでしょう)、FP適合コードで終わる可能性があります。

+0

UITableViewControllerで複製された変換済みデータを削除するにはどうすればよいですか?私はそこにデータソースメソッドで使用する配列が必要です。 –

+0

私の質問を更新して、私のアーキテクチャのより具体的な例を追加しました。 –

0

機能プログラミングは、特定のプログラミング問題に取り組むのに適しています。 FPが並行/並列プログラミングに優れている場合は、並行プログラミングでHerb Sutterによって書かれた記事のいずれかを読んだら、良い並行/並列プログラミングと機能設計で重複が見えるようになります。

アランが言っていたように、あなたは州で働く必要があります。状態がどのように変更されるかについてFPデザインパターンを適用することはできますが、純粋なFPと揃っていない、ある点または別の点で状態を変更する必要はありません。

FPは、プログラミングパターンのツールチェストのツールですが、それだけではありません。

+1

私のビューレイヤー(ビューとViewControllers)に状態があるのは大丈夫ですが、アプリケーションのほとんどが情報を渡すだけなので、問題はデータベースからの読み込みのように副作用であるようです。私はViewControllerと同じ場所にいけないコードの一部を分割していませんか? –

+0

私の質問を更新して、私のアーキテクチャのより具体的な例を追加しました。 –

2

FPをしばらく置いておくと、マルチユーザーまたは時間依存モデルの問題は、プログラムの前のエンドユーザーがコントロールイベントの唯一のソースではないということです。

依存関係をきれいに保つために、外部トリガーをユーザー入力のフォーム(要請されていない)として表示し、同じパスで処理する必要があります。

エンドユーザーが何らかの形で新しいデータが利用可能であることを知っていたら、ボタンを押してプログラムが入手できるようにすることができました。その後、(プッシュ通知などの)後方制御フローは必要とされない。

その完璧な世界では、データを取得するためのユーザーの操作は、最初にビューレベルで取得され、次にレイヤーを持ち歩くはずです。

これは、通知がView Controllerによって処理される必要があること、または通知を受信するように設計されたビューコンポーネントによって処理される必要があることを示しています。しかし、そのような通知には、モデルのどの部分が無効にされたかを示す何らかの指標を除いて、いかなるデータも含まれないであろう。

FPに戻って、これはすべての関数呼び出しが潜在的に異なる結果を返すと考えれば、もちろん巨大な副作用です。しかし...

数学では、ある速度で移動距離を与えても時間パラメータを指定しない関数を定義すると、副作用の犠牲にはならず、入力値。

したがって、すべてのソフトウェア層が純粋な関数であるが、その時間が最初の入力で与えられた暗黙的なパラメータであると考えると、繰り返し呼び出しが任意の順序で関数にチェックされることでプログラムがFPに準拠することを検証できます時刻が固定されているときは常に同じ結果が返されます。

データベースがある時点で状態の100%完全なスナップショットのセットを保持できる場合、時間を凍結させるかパラメータとして使用することで、アプリケーションの純粋なFP適合を検証できます。

現実の世界に戻ると、そのような設計はパフォーマンス上の理由からしばしば実用的ではありません。それは、どんな形式のキャッシングもかなり排除します。

まだ、私はあなたのデザインに迷惑なユーザー入力として通知を分類することをお勧めします。私はそれがいくつかの難解を解決するのに役立つと信じています。

+0

基本的に 'Interactor'に通知を伝えるのではなく、私の' ViewController'(またはそれらの2つの中の別の 'Controller')は正しいでしょうか?もしそうなら、それは私の 'Interactor'が入力の一つのソースしか持たないことを意味します(呼び出されるいくつかの' execute'メソッド)、それから観測を削除します(しかし、それはあまり違いはありません。通知が到着したときに 'execute'メソッドを呼び出すので、' execute'メソッドは同じままです)。でも問題は残っていて、私の 'Interactor'は依然としてデータベースにアクセスしています。 –

+0

プレゼンターがVCやモデルの一部であると考えるのかどうかはわかりませんが、そこでは不快な立場にあります。私は通常、モデルレイヤにデータリモデリングを配置して、VCがすべてが常に存在する唯一の状態の宇宙を見て、宇宙のどこにいるのかを知るために必要な最小限の状態にします。あなたのデータが離れたサーバ上にある場合は、いくつかのパフォーマンス上の問題が生じる可能性がありますが、VCへのフェッチとキャッシングをすべて隠し、すべてのレイヤーで状態を最小限に抑えるデータの抽象化を作成できるはずです –

+0

私のVCがあまりにも大きくなり始めると発表者。しかし、UITableViewControllerを想像してください。どこでデータを保持していますか? –

関連する問題