# - No Cyclic(Circular) Dependency


プログラミング言語F#の簡単な紹介が含まれています.

😈 悪魔の甘言


現代のプログラミング言語の多くは、事前に宣言されていないモジュール(パッケージ)を参照することをサポートしています.これにより、コードを記述する順序を考慮することなく、プログラムを容易に記述することができる.

ソース:https://www.jetbrains.com/help/idea/auto-completing-code.html#smart_type_matching_completion
加えて、プログラムを作成する際に必要な関数があれば、IDEは直ちにどのモジュールの関数を検索し、importに自動的に宣言するので、モジュールをどのように設計するか心配しなくても、プログラムを完了するのは難しくありません.IDEでは、モジュールやパッケージを何回かクリックして作成することもできますが、プロジェクトが進むにつれてファイル、モジュール、パッケージの数が増え、どのような考えでこのクラス、この関数をこのモジュールに入れたのか覚えていません.最終種目はやはり山へ...

📦 錯乱したモジュール

// foo.js
import { doRandomJob } from './bar.js';

export function alsoRandomJob() {
  // ...
}

// ...
doRandomJob();
// ...
// bar.js

import { alsoRandomJob } from './foo.js';
export function doRandomJob() {
  // ...
  alsoRandomJob();
  // ...
}
このようにして,プログラムが正常に構築されず,ますます膨大になり,すでによく見られることとなっている.この場合,モジュール単位で絡み合うという言い方も恥ずかしいが,関数間のクラス間のクラス間で絡み合い,パスタコードとなりながら行くそば冷麺コードとなる.

ソース:https://programmingideaswithjake.wordpress.com/2018/11/27/converting-a-cyclic-dependency-into-a-directed-dependency/
したがって、上述したように、AはBのコードを呼び出し、BはCのコードを呼び出し、CはDのコードを呼び出し、Dは再びAのコードを呼び出す.自分が完全に存在するコードはありません.さらに悪いことに、このような状況に気づくのは難しい.
どうせ起動したプログラムだから大丈夫でしょうか?
これは間違った答えではない.実用主義の観点から,このコードが完璧に動作すれば,修正に乗り出す必要はない.しかし、多くの場合、私たちが作成したコードは本当に完璧なコードではなく、本当に必要な事項をカバーできるコードです.最終的に、コードを変更する必要がある場合は無条件です.
ただし、すべてのコードは互いに依存するため、一部を修正するためには、すべての依存コードを修正する必要があります.それに、もしこのコードが私が書いたのではないなら?コードをよく検討する必要がある場合は?😡 Googleでhow to structure a node app?またはhow to eliminate circular dependencyを検索すると、参考になる記事がたくさん出てきます.みんな苦しんでいるようです.構造を設計するのは容易なことではない.
参照可能なドキュメント
  • Eliminate Circular Dependencies from Your JavaScript Project
  • Bulletproof node.js project architecture
  • 👍 F#:必要な原則を捨てない


    便利さにだまされ、モジュールを再整理する悪夢を経験したことがあるかもしれません.あるいはモジュールがごちゃごちゃになって、ある日来る悪夢を待っている......
    このような問題に真剣に対処すれば、F#は魅力的な選択になるだろう.F#は事前に宣言しないと使えないという原則を堅持しています.したがって,依存関係では,まず上司の内容を記入しなければならない.したがって,プログラムにおける重要な論理ほど,他のモジュールに依存しない理想的な設計が自然に導出される.プログラミング環境は開発者のプログラミング能力と同様に大きな影響を及ぼす.どんなに速い競走選手でも汽車で旅行する人より遠くまで行くわけにはいかない.

    にF#の依存関係を管理する方法

    // Program.fs
    
    module Program
    
    open Application
    
    [<EntryPoint>]
    let main argv =
        createApp ()
        |> storeAddResultOf 5 3
    
        0
    // Application.fs
    
    module Application
    
    open Core.Calc
    
    type InMemoryApp () =
        let calcResults = ResizeArray<int>()
        
        member _.Store x = calcResults.Add x
        member _.Read () = calcResults
    
    let createApp () = InMemoryApp()
    
    let storeAddResultOf x y (store : InMemoryApp) =
        add x y
        |> store.Store
    
    // Core.fs
    
    module Core
    
    module Calc =
        let add x y = x + y
        
        let sub x y = x - y
        
        let mul x y = x * y
        
        let tryDiv x y =
            if y = 0  then None
            else Some (x / y)
    例を挙げる.ソースファイルは3つあります.よく見ると.
  • プログラムの主な関数は、アプリケーションで定義された関数を使用します.
  • アプリケーションモジュールは、コアで定義された関数を使用します.
  • したがって、プログラムはアプリケーションに依存し、アプリケーションはコアに依存し、コアは何にも依存しません.したがって、コアが変更されると、アプリケーションに影響します.アプリケーションが変更されると、プログラムの構造に影響します.

    したがって,上記の順序でしかコードを記述できない.他の順序は存在しません.ソースコードの順番が変わったらどうなりますか?F#プロジェクト設定ファイルで依存関係を設定できます.
      <ItemGroup>
        <Compile Include="Core.fs" />
        <Compile Include="Application.fs" />
        <Compile Include="Program.fs" />
      </ItemGroup>
      
      // 아래로 수정해보자
    
      <ItemGroup>
        <Compile Include="Program.fs" />
        <Compile Include="Application.fs" />
        <Compile Include="Core.fs" />
      </ItemGroup>
    どうなるんだろう.
    error FS0039: The namespace or module 'Application' is not defined.
    error FS0039: The value or constructor 'createApp' is not defined.
    error FS0039: The value or constructor 'storeAddResultOf' is not defined.
    error FS0039: The namespace 'Calc' is not defined.
    error FS0039: The value or constructor 'add' is not defined.
    事前に宣言しないと使用できない原則はコンパイルされません.これにより,F#を用いてプログラムを記述すると,モジュール間の絡み合い,ソースコード間の依存性の絡み合い,再パッケージングを余儀なくされることなどを予防しやすい.Visual StudioまたはRiderを使用すると、ソースコードの順序を簡単に変更できますので、あまり複雑ではありません.

    📝 の最後の部分


    F#は、プロジェクト構造をシームレスに管理できます.プロジェクトが長期的に運営されると思う場合は、F#のこれらの機能が大きなメリットになります.ソフトウェアの複雑さをさらに低減し、プログラム構造の理解を助けることができるからです.コードがどこで間違っているのか考えているなら、F#を考えてみてください.
    もしコンパイラが私が今「間違った」プログラムを書いているので間違っていたら、感謝することはありません.