`

关于返回null值的问题(share)

OO 
阅读更多

转自http://www.aqee.net/returning-null/

我总感觉一个方法返回null值有问题。当读了Misko Hevery关于how to think about OO的博客文章后,又让我想起这个问题。

我感觉返回null值是有问题的,它大量的被使用在一个方法有不同的返回类型时。简单的用谷歌搜索一下“returning null”,你就会发现有建议把返回类型做成一个null对象。返回一个Null对象在某些情况下是合适的,但并不适合当你需要向客户端传送两种不同的东西的情形。用Misko重构的一段代码来说明这个问题。他重构的是一段登录代码(我非常喜欢他的过程),这段代码大概是这个样子:

  Cookie login(Ldap ldap) {
    if ( ldap.auth(user, password) )
      return new Cookie(user);
    return null;
  }

从这段代码,可以看出两种情况(从结构上讲)

  1. 如果认证通过,客户端会被通知验证成功,生成一个新的Cookie
  2. 如果认证失败,则通过返回的null值通知客户端

客户端的方法应该是什么样的?

  public void authenticateUser(User user) {
     Cookie userCookie = user.login(ldap);
     if (userCookie == null) {
           //notify someone that auth failed
     } eles {
           //register them as logged in
     }
  }

我们在两个地方做了相同的事情,只是在语法上有稍微的不同,每个地方,我们都要检查验证是否成功。如果我们使用IoC(反向控制)模式,或“Tell Don’t Ask”模式或“Hollywood原则”,会如何?

  Cookie login(Ldap ldap, AuthenticationRegistry authenticationRegistry) {
    if ( ldap.auth(user, password) )
      authenticationRegistry.authSucceeded(new Cookie(user));
    authenticationRegistry.authFailed(user);
  }

客户端:

  public void authenticateUser(User user) {
     user.login(ldap,this);
  }

  public void authSucceeded(Cookie cookie) {
     //register them as logged in
  }

  public void authFailed(User user) {
     //register them as auth failed
  }

新代码稍微有点复杂,但我感觉它很清晰,实现的更直接。现在我们的两个实体能够相互通信,我们定义了它们通信的方式。我喜欢Misko的重构,我只是更进了一步。好坏可以再讨论,但我想,如果你遇到了这种需要返回两种情况的方法时,IoC是你应该的选择。

分享到:
评论

相关推荐

    bash总结最新版

    - `dirname`命令用于获取路径中除最后一部分外的目录部分,如`dirname /usr/local/share/doc/foo/foo.txt` 返回 `/usr/local/share/doc/foo`。 - 这两个命令常用于处理文件路径,方便提取路径的组件。 这些知识点...

    invite

    生成被最小化,并且文件名包括哈希值。 您的应用已准备好进行部署! 有关更多信息,请参见关于的部分。 yarn eject 注意:这是单向操作。 eject ,您将无法返回! 如果您对构建工具和配置选择不满意,则可以随时...

    中文API支持库(1.0-0

    如lpReturnedString缓冲区不够大,不能容下全部信息,就返回nSize-1(若lpApplicationName或lpKeyName为NULL,则返回nSize-2)。 注解:如lpKeyName参数为NULL,那么lpReturnedString缓冲区会载入指定小节所有设置...

    第11章文件操作

    成功则返回非 NULL 值,失败返回 NULL 并设置 `errno`。 **关闭已打开的目录** ```c #include #include int closedir(DIR *dir); ``` 此函数用于关闭通过 `opendir()` 打开的目录。成功则返回 0,失败返回 -1 ...

    Laravel开发-laravel-helper

    - `array_only($array, $keys)`: 提取数组中指定键对应的值并返回新数组。 - `array_except($array, $keys)`: 移除数组中指定键对应的值并返回新数组。 2. **字符串助手**: - `str_slug($string, $separator)`:...

    (c)模式存储数据库中数据字典的表和视图

    4. 序列(Sequence)在Oracle中用于生成唯一的整数,`CURRVAL`返回序列当前值,`NEXTVAL`递增并返回新值 5. SQL别名(Alias)可以使用`AS`关键字创建,例如`SELECT ename, sal*12 AS "Annual Salary" FROM emp` 6....

    获取文件修改时间和文件大小

    HANDLE hFile = CreateFile("your_file_path", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { FILETIME creationTime, ...

    2021-2022计算机二级等级考试试题及答案No.11531.docx

    4. 主关键字:主关键字是表中的唯一标识符,不允许有NULL值和重复值。选项B错误,因为主关键字字段不应包含NULL值。 5. 数据结构:栈遵循“先进后出”(LIFO)原则,因此选项B正确。循环队列、队列和二叉树都有不同...

    系统编程中常用函数总结

    char *envp[] = {"PATH=/mnt/hgfs/share", NULL}; execle("/bin/ls", "ls", "-l", NULL, envp); ``` - **`int execv(const char *path, char *const argv[]):`** 与`execl`类似,但参数传递方式略有不同。 ...

    SQLServer 高级篇

    - 锁包括共享锁(Share Locks)和独占锁(Exclusive Locks)等。 3. **索引(Indexes)**: - 索引可以加速查询的速度。 - 包括聚集索引(Clustered Indexes)和非聚集索引(Nonclustered Indexes)。 4. **...

    用C++编写从文件中读取数据的程序

    - 如果成功读取文件,则返回非零值;否则返回零。 #### 五、程序流程 1. **打开文件**: - 使用`CreateFile`函数尝试打开文件`"c:\\mianhou.txt"`。 - 成功打开后输出“文件打开成功!”的信息,否则输出“文件...

    MFC调用win32窗口显示调试信息

    HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); ``` 3. **设置字体颜色**:使用`...

    Calling Win32 API Routines from HLA

    调用完成后,`hResult`将包含函数返回的值。 除了直接调用API函数,还需要处理错误。大多数Win32 API函数在失败时会返回一个错误代码,例如`NULL`或`FALSE`。你应该检查这些返回值,并根据需要进行错误处理。例如:...

    oracle中判断表是否被锁

    - **Null (1)**:无效值。 - **Row-S(SS) (2)**:共享行锁。 - **Row-X(SX) (3)**:排他行锁。 - **Share (4)**:共享对象锁。 - **S/Row-X(SSX) (5)**:共享加排他行锁。 - **Exclusive (6)**:排他对象锁。 ...

    取句柄对应全路径文件名.rar

    HANDLE hFile = CreateFile("C:\\example.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ``` 如果成功,`hFile`将包含有效的句柄;否则,它将为`INVALID_HANDLE_...

    CreateFile函数祥解.txt

    `CreateFile`函数是Windows API中的一个重要功能,主要用于创建或打开各种类型的文件和设备对象,并返回一个句柄,该句柄可用于后续对这些对象的操作。此函数可以用于操作多种类型的对象,包括但不限于文件、管道、...

    linux环境编程-ftok()函数详解.docx

    当 ftok 函数执行成功时,一个 key_t 值将被返回,否则返回 -1。 ftok 函数的作用是将文件的索引节点号取出,前面加上子序号得到 key_t 的返回值。例如,如果文件的索引节点号为 65538,换算成 16 进制为 0x010002...

    ORACLE常用問題1000問

    根据提供的文件信息,可以看出这是一份关于Oracle数据库常见问题解答的手册或文档的一部分。文档包含了多个与Oracle数据库管理和操作相关的具体问题及解答示例。接下来,我们将对文档中提到的关键知识点进行详细的...

    C# 算法汇总

    1. **函数定义**:`IsNumeric` 方法接收一个字符串 `str` 作为参数,并返回一个布尔值表示该字符串是否仅由数字组成。 2. **空检查**:首先检查传入的字符串是否为空或长度为零,如果是,则直接返回 `false`。 3. **...

    非标准USB命令-厂商自定义命令编程

    FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); ``` 2. **构建命令数据包**:接着定义自定义命令的结构体,填充必要的字段,如命令类型、值、方向等。 ```c VENDOR_OR_CLASS_REQUEST_CONTROL ...

Global site tag (gtag.js) - Google Analytics