【问题标题】:OOP design approach for two interacting classes两个交互类的 OOP 设计方法
【发布时间】:2009-07-23 21:53:28
【问题描述】:

与嵌套类相比,将类链接在一起(或者更确切地说,使用一个类的结果生成另一个类)有哪些相对优势/劣势?

我正在尝试重组我的用户/身份验证系统并且想知道是否;

  • myAuthClass 应该作为一个实用程序,如果登录成功,只需创建一个新的 myUserClass 对象
  • 或者 myAuthClass 是否应该在内部创建 myUserClass(即 $this->user = new myUserClass)
  • 或者即使 myUserClass 应该只在必要时调用 myAuthClass(即当用户尝试登录时)并根据需要更新其内部结构(新电子邮件、收藏夹、购物车等)。

如您所知,我有点像 OOP n00b。 Concpetually,我似乎能够为每种方法提供一个案例,所以我很想听听其他人关于各种方法的 +ves/-ves 的信息。

干杯。

【问题讨论】:

    标签: php design-patterns oop


    【解决方案1】:

    从学术角度来看,所有 3 个选项都是不正确的,因为它们是针对具体实现而不是针对抽象接口进行编程的。因此,它们直接耦合在一起,这限制了重用 - 您可以同时使用它们或根本不重用它们。

    您可以生成 IUserClass 或 IAuthClass 并将此抽象接口实现为具体类,然后我会遇到这样的情况,即身份验证类实现在验证填充时采用 IUserClass,或者为用户类提供了 IAuthClass 的实现进行身份验证。

    在每种情况下,这都允许最大的灵活性,因为可以重用 auth 类并且可以生成不同版本的 UserClass,或者用户类可以使用多种不同的身份验证机制,只要继承自IAuthClass。

    后一种为用户类提供身份验证对象(实现 IAuthClass)的方法是我的偏好,因为身份验证机制不同,即使对于单个应用程序也是如此,而用户类的变化较少。但要正确,两者都不应该基于具体的实现。

    然而,这可以被视为过于夸张,所以这是一个判断电话。

    【讨论】:

    • 非常好,与我的具体项目最相关,因为未来的开发可能会包括一个 OpenID 风格的身份验证系统。
    • 如果没有对具体实现的外部依赖,那么针对具体实现进行编程没有任何问题。也就是说,如果这些类只在同一个包中使用过——这个包是高度内聚的——没有接口也没有错。
    【解决方案2】:

    首先我建议你使用适配器模式。您应该有一个定义接口(公共方法)的抽象类,而不是创建一个实现特定类型身份验证的类。例如,您可以为 DB 基本身份验证创建一个类/适配器,一个用于 LADP 身份验证.. 等等...

    最好的办法是使用现成的解决方案,而不是重新发明轮子。我使用了 Zend_Auth,它实现了适配器模式。通过使用 Zend_Auth,您可以了解良好的 OOP 实践、适配器模式、接口和抽象类的使用,如果您愿意的话。

    在这里您可以看到我如何将 Zend_Auth 用于 Intranet;

            protected function Authentication() {
            $strEmail = trim($this->txtEmail->Text);
            $this->txtPassword->Text = trim($this->txtPassword->Text);
            // do the process of authentication, AD and then DB
            // Get a reference to the singleton instance of QAuth
            $auth = QAuth::getInstance();
            // Set up the authentication adapter
            $authAdapter = new QAuth_Adapter_WebService(__LOGIN_WS_URL__, 
                $strEmail, $this->txtPassword->Text
            );
    
            // Attempt authentication, saving the result
            $result = $auth->authenticate($authAdapter);
    
            if ($result->isValid()) {
                $objUser = User::LoadByEmail($strEmail);
    
                // if there is not a user's record create one
                if(!$objUser) {
                    $this->User_Create($strEmail);
                    $objUser = User::LoadByEmail($strEmail);
                }
    
                $crypt = new Encryption();
                $encr = $crypt->encrypt(__KEY__, $objUser->UserID);             
                $_SESSION['user_id'] = $encr;
                setcookie('user_id', $_SESSION['user_id'], time()+(3600*24*365*20));
                $this->Intranet1Integration($objUser->UserID);
                QApplication::Redirect('http://'.__URL__.'/index.php');     
            }
            else {
                QApplication::DisplayAlert(
                    'Log on failed. You must provide a Company email and a correct password.'
                );
            }
        }
    

    【讨论】:

    • +1 表示适配器模式和对 Zend 的引用;它的文档将成为非常有用的案例研究。
    【解决方案3】:

    链接类的主要优点是使它们彼此独立,因此修改一个对另一个绝对没有(或少得多)影响。例如,假设您要更改身份验证方法,则无需更改用户,反之亦然。

    这两种方法都有其他小优点,但这种可维护性是这里的主要优点

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-10
      • 1970-01-01
      相关资源
      最近更新 更多