기능적 파이프라인 예

메서드 체이닝(MC) 대 기능적 파이프라이닝(FP)





MC 대 FP에 대한 참고 사항



두 접근 방식은 매우 유사합니다. MC를 더듬을 수 있다면 FP 접근도 더듬을 수 있습니다.

MC 단점:


  • 은 기본 제공 메서드만 사용할 수 있습니다.
  • 추상화 수준을 제어할 수 없습니다.
  • 매우 객체 지향적입니다(데이터와 동작이 혼합됨).
  • 약한 유형입니다.

  • FP 전문가:


  • 모든 사용자 정의 기능을 사용할 수 있는 모든 권한.
  • 추상화 수준을 제어합니다. 이 예에서 FP 기능은 여전히 ​​도메인에 구애받지 않지만 더 높은 수준의 일반적으로 재사용되는 동작을 수행합니다. 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);
    };
    

    파이프Str

    /**
    @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);
    

    삼.

    /**
    @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에서 사용되는 일반적인 약어를 여기에 나열했습니다.

  • 추신



    질문이 있으시면 알려주세요.

    좋은 웹페이지 즐겨찾기