重用Node.js模块中的代码

时间:2017-07-17 02:37:25

标签: javascript node.js express

我只是想知道你是否像我在这里一样重做代码重构代码。对不起,以下长期背景。 :)

我正在使用一个简单的Web应用程序学习Express.js并使用重置密码表单在登录页面上工作。此表单要求提供电子邮件,该电子邮件将根据数据库进行检查,然后在用户配置文件中设置令牌和1小时的到期时间,并将URL发送给用户。 URL类似http://mywebsite.com/account/reset/43aea78ba678fd8ed746b2b0b79c34da9380a5a6,所以当用户访问此URL时,我有几个路由器来处理密码重置:

  • 一个检查令牌:router.get( '/account/reset/:token', authController.reset ),它会重定向到一个新页面,并带有重置密码的表单。
  • 另一个更新新密码:router.post( '/account/reset/:token', authController.confirmedPasswords, authController.update )

这是模块(控制器),它具有处理这些任务的逻辑:

const mongoose = require( 'mongoose' )
const User = mongoose.model( 'User' )
const promisify = require( 'es6-promisify' )

const findUserByTokenAndDate = ( token, date ) => {
    return User.findOne( {
        resetPasswordToken: token,
        resetPasswordExpires: { $gt: date },
    } )
}

exports.reset = async ( req, res ) => {
    // const user = await User.findOne( {
    //     resetPasswordToken: req.params.token,
    //     resetPasswordExpires: { $gt: Date.now() },
    // } )
    const user = await findUserByTokenAndDate( req.params.token, Date.now() )

    if ( ! user )
    {
        req.flash( 'error', 'Password reset token is invalid or has expired' )
        return res.redirect( '/login' )
    }

    res.render( 'reset', { title: 'Reset your Password' } )
}

exports.confirmedPasswords = ( req, res, next ) => {
    if ( req.body.password === req.body['password-confirm'] )
    {
        return next()
    }

    req.flash( 'error', 'Passwords do not match!' )
    res.redirect( 'back' )
}

exports.update = async ( req, res ) => {
    // const user = await User.findOne( {
    //     resetPasswordToken: req.params.token,
    //     resetPasswordExpires: { $gt: Date.now() },
    // } )
    const user = await findUserByTokenAndDate( req.params.token, Date.now() )

    if ( ! user )
    {
        req.flash( 'error', 'Password reset is invalid or has expired' )
        return res.redirect( '/login' )
    }

    const setPassword = promisify( user.setPassword, user )
    await setPassword( req.body.password )

    user.resetPasswordToken = undefined
    user.resetPasswordExpires = undefined
    const updateUser = await user.save()
    await req.login( updateUser ) // This is to tell password.js which user to log in

    req.flash( 'success', 'Your password has been reset! You are now logged in' )
    res.redirect( '/' )
}

评论代码是我使用函数findUserByTokenAndDate重用的代码。

  • 这比其他解决方案更容易测试吗?
  • 您是否已创建新模块,仅用于保存函数findUserByTokenAndDate中的代码?
  • 这是一个好习惯吗?

请注意,这是一段非常简单的代码,可能甚至不值得重用,但我正在寻找更复杂或更大代码的良好实践。

谢谢!

1 个答案:

答案 0 :(得分:1)

  

这比其他解决方案更容易测试吗?

取决于你的要求。对我来说是对的,因为你在其他地方重复使用相同的逻辑,将它抽象出它自己的功能是有意义的。但是,如果它仅在两个地方使用,那么您不一定需要/需要提取它以避免重复。它节省了在那里查看代码逻辑的时间,而不必追踪它所在的模块。

  

您是否已创建新模块,仅用于保存函数findUserByTokenAndDate中的代码?

我会用findUserByTokenAndDate之类的任何/所有实用程序函数创建一个单独的模块。然后我可以只测试效用函数而不测试任何其他函数。

  

这是好习惯吗?

有人会说它是over-engineering