Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript:在请求对象„的情况下,使用模式Null对象模式、RORO、undefined等作为Get函数的返回参数;未找到“;_Javascript_Oop_Null Object Pattern - Fatal编程技术网

Javascript:在请求对象„的情况下,使用模式Null对象模式、RORO、undefined等作为Get函数的返回参数;未找到“;

Javascript:在请求对象„的情况下,使用模式Null对象模式、RORO、undefined等作为Get函数的返回参数;未找到“;,javascript,oop,null-object-pattern,Javascript,Oop,Null Object Pattern,首先,我不确定这个话题是否属于StackOverflow。然而,我发现了一些关于其他编程语言的讨论,这些语言涉及StackOverflow主题,但不涉及Javascript。所以,我要把我的问题放到拳击场上: 处理Javascript中假设的GetUserByUsername函数中可能出现的“未找到”情况的最佳方式/模式是什么。 我为什么这么问?我想在整个项目中遵循一定的编码标准 我的更具体的场景如下所示: 我有一个类用户 我有一个用户列表,其中包含 类用户 我查找某个用户,但该用户不查找 存

首先,我不确定这个话题是否属于StackOverflow。然而,我发现了一些关于其他编程语言的讨论,这些语言涉及StackOverflow主题,但不涉及Javascript。所以,我要把我的问题放到拳击场上:

处理Javascript中假设的GetUserByUsername函数中可能出现的“未找到”情况的最佳方式/模式是什么。

我为什么这么问?我想在整个项目中遵循一定的编码标准

我的更具体的场景如下所示:

  • 我有一个类用户
  • 我有一个用户列表,其中包含 类用户
  • 我查找某个用户,但该用户不查找 存在于列表中
我应该如何处理我的功能中的“未找到”情况

我发现了以下方法:

  • 返回未定义
  • RORO(接收对象,返回对象)
  • 空对象模式
  • 抛出自定义错误
那么我的确切意思是什么呢?以下面的示例类User为例

module.exports = class User {
  constructor() {   
    this.userName = null,
    this.name = null,
    this.age = null
  }
  ...
  getName() {
    console.log(this.name);
  }
}
在我的代码中,我有一个函数,它提供了从用户列表中按用户名返回某个用户的功能。该列表是一个数组,由类user的实例组成

module.exports = class User {
  constructor() {   
    this.userName = null,
    this.name = null,
    this.age = null
  }
  ...
  getName() {
    console.log(this.name);
  }
}
一个简单的实现可能是这样的:

{
  ...

  getUserByUsername(pUserName) {
    /* listOfUsers array with objects of the class User */
    var lUser = this.listOfUsers.find(user => user.userName === pUserName);
    return lUser;
  }
  ...
}
在某些情况下,传递的用户名可能不属于某个用户。因此找不到任何用户

我怎么办

1.)返回undefined-与示例代码一样

/* We expect "Unknown" is not a user name in that list*/
var lRequestedUser = getUserByUsername("Unknown");

/* Check if requested user is undefined. Note: I'm using lodash for staff like that */
if(_.undefined(lRequestedUser)) {
  //Handling 
}

lRequestedUser.getName();
2.)RORO(接收对象,返回对象) 我将一个对象传递给我的函数,并返回一个对象作为结果。在我返回的对象中,我有一个指示器,显示操作是否成功

getUserByUsername(pParams) {
  if(_.undefined(pParams.userName)) {
    //Throw custom error 
  }

  var lReturnObject = {
    isSuccessfull: false,
    data: null
  }

  /* listOfUsers array with objects of the class User */
  var lUser = this.listOfUsers.find(user => user.userName === pParams.userName);

  if(!(_.undefined(lUser))) {
    lReturnObject.isSuccessfull = true;
    lReturnObject.data = lUser
  }
  return lUser;
}
...
}

/* 
Building a object which is passed to the function. Username is a member of that object
 */
var lRequest = {
  userName: "Unknown"
}

/* We expect "Unknown" is not a user name in that list*/
var lRequestedUser = getUserByUsername(lRequest);

if(!(lRequestedUser.isSuccessfull)) {
//Handling 
}

lRequestedUser.data.getName();
3.)空对象模式 我不喜欢这个解决方案的一点是,如果主类得到一个附加函数,我总是必须增强空对象的类

  module.exports = class NullUser {
      constructor() {   
        this.userName = null,
        this.name = null,
        this.age = null
      }
      ...
      getName() {
        console.log(this.name);
      }
    }


{
  ...

  getUserByUsername(pUserName) {
    /* listOfUsers array with objects of the class User */
    var lUser = this.listOfUsers.find(user => user.userName === pUserName);

    if(_.undefined(lUser)) {
      return new NullUser();
    }

    return lUser;
  }
  ...
}


/* We expect "Unknown" is not a user name in that list*/
var lRequestedUser = getUserByUsername("Unknown");
lRequestedUser.getName();
4.)抛出自定义错误

{
  ...
  getUserByUsername(pUserName) {
    /* listOfUsers array with objects of the class User */
    var lUser = this.listOfUsers.find(user => user.userName === pUserName);

    if(_.undefined(lUser)) {
      throw new CustomError(...);
    }

    return lUser;
  }
  ...
}

/* We expect "Unknown" is not a user name in that list*/
try {
  var lRequestedUser = getUserByUsername("Unknown");
  lRequestedUser.getName();
} catch (e) {
  if (e instanceof CustomError) {
      //Handling
  }
}
就我个人而言,我更喜欢返回包含指示符的对象的选项,以及抛出自定义错误的选项。该示例是同步的。在我的项目中,我也有异步代码。我正在为此使用承诺


那么,有什么想法是“最好”的解决方案,或者我更喜欢的方式吗?

答案是,在我看来,这取决于你的想法! 您提到的所有方法都有特定的用例,每个用例都占主导地位。让我们逐一进行讨论。(最后还有一位评论家)

带有回调的异步应用程序

尽管回调被视为陈旧而不流行,但它们给了我们所谓的“多重返回值”的灵活性

  • 在这里,抛出错误将无法按预期工作。也就是说,您不能用try-catch捕捉抛出的错误。当然,您可以“返回”自定义错误。但这似乎毫无意义,因为您可以单独返回“状态”
  • 使用附加的
    状态
    参数返回空对象或RORO没有意义。不过,您可能更愿意放弃
    状态
    ,而选择空对象或RORO

带承诺的异步应用程序/async wait

在这里,抛出错误将起作用。如果您使用async Wait,则try-catch的捕获将获得错误。或者,如果您按原样使用承诺,则承诺链的捕获将获得错误

同步应用程序

抛出错误和使用try-catch的效果与预期一样。然而,在使用任何第三方服务的实际应用程序中,这将是一种罕见的情况

然而使用异常毕竟存在一个问题。是否将“无数据”场景视为错误取决于业务逻辑

  • 如果您只想告诉最终用户,没有这样的用户,那么使用异常将是有意义的
  • 如果您想继续创建新用户,那么可能没有意义。您需要明确区分错误是由于“无数据”,还是由于“驱动程序错误”、“超时”等。根据我的经验,使用此类异常很容易引入错误
  • 因此,该问题的解决方案将是使用自定义错误。然后,被调用方和调用方中会有太多的锅炉板代码。这甚至可能导致逻辑语义混乱。另一方面,过多使用自定义错误可能会导致不一致问题,并可能导致难以维护的应用程序er时间。(这完全取决于应用程序的发展。例如,如果开发人员经常更换,不同的人会对这些自定义错误有不同的看法)


    固执己见的回答

    在看到了良好的应用程序和高度不可维护的巨石之后,我会给出我个人的偏好。但请记住,这可能不是最终的解决方案

    注:此(自以为是的)解决方案基于以下事实:

  • 所需样板代码的数量
  • 代码的语义
  • 新开发人员很容易开始使用该应用程序
  • 维修性
  • 不要使用错误来处理无数据情况。相反,请明确检查“空”数据,并单独处理该情况。 我将在这里介绍RORO模式,略有不同。我确实返回了一个对象,但接收的是参数而不是对象。这取决于参数的数量。如果参数的数量太多,那么接收对象可能是有意义的。但在我看来,这可能是一个坏的业务/架构决策的指示

    考虑以下用户登录的示例<
    // Controller code
    async signIn(name, email) {
      try {
        let user = await userDao.getUserByUserName(name);
        if (!user.exists) { 
           user = await userDao.createUser(name, email);
        }
        return user; 
      } catch(e) {
        // handle error
      }
    }
    
        // Controller code
    async signIn(name, email) {
      try {
        let result = await userDao.getUserByUserName(name);
        if (!result.user) { 
           result = await userDao.createUser(name, email);
        }
        return result.user; 
      } catch(e) {
        // handle error
      }
    }