機能的パイプライン例


メソッド連鎖(MC)対機能的パイプライン化(FP)



MC vs FPに関するノート


つのアプローチが非常に似ていることに注意してください.あなたがMCを起こすことができるならば、あなたはFP

MCコン

  • は組み込みメソッドのみを使用できます.
  • 抽象レベルを制御できません.
  • 非常にオブジェクト指向(データと行動を連動).
  • 弱くタイプされる
  • .
  • fp pros :


    すべてのカスタム機能を使用する
  • フルコントロール.
  • 抽象レベルを制御します.この例では、fp - funsはまだドメイン非正規であるが、より高いレベル、一般的に再利用された振舞いを実行します.FPファンの通知4は完全に抽象化されています.私がfilterNotStartsWithからexcludeCommentsまでそれらを要約することができるように、argsをとる2つの機能が、あります.また、replaceByRegexからreplaceNewlineWithDoubleAmpersandまで.私は、彼らが非常に人気の振舞いでないので、これをしませんでした、しかし、FPパイプラインはさらに流暢に読むでしょう.
  • 無料(非クラスバインド)静的関数を使用してデータと動作を分離します.
  • ランタイムは強くタイプされました.
  • ソースコード例


    ピペベ
    /*
    @func
    a non-typed pipe
    - that can dynamically handle sync or async funcs
    
    @usage
    this is a util func of the typed pipe funcs
    
    @param {...Function} fns - one or more funcs spread to an arr of funcs
    @return {(v: *) => *} - the first func in the pipe takes in any data, and the last func returns any data
    */
    export const pipeBase = (...fns) => v => {
      return fns.reduce((r, fn) => { // r = result or output of fn call
        if (isPromise(r)) {
          return r.then(fn);
        }
        return fn(r);
      }, v);
    };
    
    ピペスタルス
    /**
    @func
    a strongly-typed pipe that is invoked with a supplied str
    
    @clientcode
    const p1 = pipeStr(f1, f2, f3);
    p1("");
    
    @param {...Function} fns
    @return {(s: string) => *}
    */
    export const pipeStr = (...fns) => s => throwIfNotStr(s) || pipeBase(...fns)(s);
    
    1 .
    /**
    @func
    split by \n chars
    
    @notes
    use forceSingleNewline() beforehand if str contains multiple blank lines in a row
    
    @param {string} s
    @return {string[]}
    */
    export const splitByNewline = s => s.trim().split("\n");
    
    
    2 .
    /**
    @func
    trim each str in arr of strs
    
    @notes
    if the elem is a str, trim it
    - otherwise leave it as is
    
    @param {string[]} a
    @return {string[]}
    */
    export const mapTrim = a => a.map(s => isStr(s) ? s.trim() : s);
    
    3 .
    /**
    @func
    only remove empty str elems in an arr
    
    @notes
    applies trim() before comparing
    
    @param {string[]} a
    @return {string[]} arr with empty elems removed
    */
    export const filterOutEmptyStrs = a => a.filter(s => isNotEmptyStr(s));
    
    4 .
    /**
    @func complement
    from the supplied arr, remove the elems that start with the supplied str chunk
    
    @param {string} chunk
    @return {(a: string[]) => string[]}
    */
    export const filterNotStartsWith = chunk => a => fil(s => !s.startsWith(chunk), a);
    
    5 .
    /**
    @func
    make a single str where each elem is placed on a new line
    
    @param {string[]} a
    @return {string} concatentated
    */
    export const joinByNewLine = a => a.join("\n");
    
    6 .
    /*
    @func
    replace a substring with another substring in a haystack of text
    
    @cons
    use the g flag to remove all matches
    - otherwise it will just replace the first and return
    case sensitive
    
    @param {RegExp} n needleRegex
    @param {string} r replacement
    @return {(h: string) => string} // haystack -> a copy of the haystack with the needles replaced with the new values
    */
    export const replaceByRegex = (n, r) => h => h.replace(n, r);
    
    
    最終的なFPパイプライン使用
    /**
    @func util
    supply a template string of bash commands
    - and return the logged output
    
    @param {string} a line-separated chain of bash commands
    @return {string} chain of commands separated by &&
    */
    export const chainCmds = pipeStr(
      splitByNewline,
      mapTrim,
      filterOutEmptyStrs,
      filterNotStartsWith("//"), //exclude comments
      joinByNewLine,
      replaceByRegex(/\n/g, " && "), lStr,
    );
    
    例の特徴の使用
    lBashExecChain(`
    pwd
    git config -l --local
    git show-branch
    git status
    git stash list
    git stash --include-untracked
    git pull
    git stash pop
    lerna bootstrap
    `);
    

    最終ノート

  • すべてのコードがこのポストに存在しないので、これは完全に機能的な例でありません.このポストの焦点は、ソフトウェア設計に機能的アプローチを示すことです.
  • 非常に直感的な命名規則があります.ここではJavaScriptで使われている一般的な略語を挙げました.
  • ピーエス


    質問があれば知らせてください.