簡體   English   中英

功能編程和局部功能狀態分配

[英]Functional programming and local function state assignments

我最近將代碼轉換為我認為至少部分是功能性javascript。 這是一個Web表單驗證過程。 在流程的每個步驟中,功能都會執行自己的驗證層,並在將數據傳遞給下一個功能之前對其進行修改。

1)我的第一個問題是...下面的代碼可以至少被認為是“部分”功能嗎?

您會注意到,在requiredFields中,我創建了兩個Assign ...狀態。 它們是該函數的局部函數,並且該函數沒有外部副作用。

2)在函數式編程范式的背景下,這種本地分配是不好的做法嗎? 這被認為是“局部副作用”嗎?

這是模型:

function linkmodel() {
    return {
        title: { 
            content: undefined,
            validation: {
                type: "string",
                required: true,
                minLength: 1,
                maxLength: 3,
                validationErrorMessage: "Your title must be a valid string between 1 and 35 characters"
            }
        },

        email: {
            content: undefined,
            validation: {
                type: "email",
                required: true,
                minLength: 1,
                maxLength: 60,
                validationErrorMessage: "Your email must be between 1 and 50 characters"
            }
        },


        link: {
            content: undefined,
            validation: {
                type: "url",
                required: true,
                minLength: 1,
                maxLength: 500,
                validationErrorMessage: "Your link name must be a valid email between 1 and 50 characters"
            }
        },

        description: {
            content: undefined
        }
    }
}


export default linkmodel

這是驗證系統:

app.post( "/", function( req, res ) {
  let form = new forms.IncomingForm()

  form.parse( req, function( err, fields, files ) {

    // Lodash launching the function flow
    let errorMessageBag = _.flow( objectWithFieldsToValidate,
                                  requiredFields,
                                  stringLengthValidationCheck,
                                  emailValidation )

    let result = errorMessageBag(fields, linkmodel()) // That's the end result
    console.log( "result", result ) 
  })



  // Return object containing all fields to validate and their criterias
  function objectWithFieldsToValidate( fields, model ) {
    // Remove all model fields that have no validation criteria in model. Description is one of those.
    let modelFieldsToValidate = _.pickBy( model, function( value, key ) { return value.validation !== undefined })

    // Remove from form field any entry that doesn't have a corresponding key in model
    let formFieldsToValidate = _.pick( fields, Object.keys( modelFieldsToValidate ) )
    _.forOwn( modelFieldsToValidate, function( value1, key1 ) {
      _.forOwn( formFieldsToValidate, function( value, key ) {
        if ( key1 === key ) {
          modelFieldsToValidate[ key ].content = value
        }

      })
    })
    return modelFieldsToValidate
  }

  // Take care of required fields
  function requiredFields( objectWithFieldsToValidate ) {
    let okField = {}
    let errors = {}

    // error: field required but empty: add it to errors literal object
    _.forOwn( objectWithFieldsToValidate, function( value, key ) {
      if ( objectWithFieldsToValidate[ key ].validation.required === true && objectWithFieldsToValidate[ key ].content === "" ) {
        errors[ key ] = objectWithFieldsToValidate[ key ].validation.validationErrorMessage
      } else {
        // no error: add field to litteral okField
        okField[ key ] = value

      }
    })
    return ( { "okField": okField, "errors": errors })
  }


  function stringLengthValidationCheck( requiredFields ) {
    let validatedFields = requiredFields
    _.forOwn( validatedFields.okField, function( value, key ) {
      // Error: field length is not valid
      if ( !validator.isLength( value[ "content" ],
        { min: value[ "validation" ].minLength, max: value[ "validation" ].maxLength }
      ) ) {
        // Add error message to errors errors literal object
        validatedFields[ "errors" ][ key ] = value[ "validation" ].validationErrorMessage
        // Remove problematic field from okFields
        delete validatedFields[ "okField" ][ key ]
      }
    })

    return validatedFields
  }


  function emailValidation( stringLengthValidationCheck ) {
    let validatedFields = stringLengthValidationCheck
    _.forOwn( validatedFields.okField, function( value, key ) {
      // Error
      if ( value["validation"]["type"] === "email" && !validator.isEmail( value[ "content" ])) {
        // Add error message to errors
        validatedFields[ "errors" ][ key ] = value[ "validation" ].validationErrorMessage
        // Remove problematic field from okFields
        delete validatedFields[ "okField" ][ key ]
      }
    })

    return validatedFields
  }

3)如果您看到改進此代碼的方法,我將不勝感激地看到仍然可以使用lodash可以提供更好的功能重構。

就像上面的評論所建議的那樣,特定的代碼審查可能不是SO的主題,而是要回答您問題的一般部分:是的,從外部看,沒有外部可見副作用的功能可以視為“功能”-說“行為功能”-即使它內部使用分配。

這里可能的問題是如何驗證副作用確實僅是內部的,而從外部看不到。

另一個從理論上講有趣的事實是,存在一些具有行為功能的功能,但只能通過(內部)分配來實現。 請參閱該論文以獲取更多詳細信息(如果您無法訪問ACM數字圖書館中的論文,請嘗試在網上搜索該論文的標題和/或作者)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM