两个交互类的OOP设计方法

时间:2022-10-01 11:58:51

What are the relative advantages / disadvantages of chaining classes together (or rather; using the results of one class to generate another), compared to nesting classes?

与嵌套类相比,将类链接在一起(或者更确切地说,使用一个类的结果生成另一个类)的相对优点/缺点是什么?

I'm trying to restructure my user / authentication system and am wondering whether;

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

  • myAuthClass should act as a utility and if log-in is successful, simply create a new myUserClass object
  • myAuthClass应该充当实用程序,如果登录成功,只需创建一个新的myUserClass对象

  • or whether the myAuthClass should create the myUserClass internally (ie $this->user = new myUserClass)
  • 或者myAuthClass是否应该在内部创建myUserClass(即$ this-> user = new myUserClass)

  • or even if myUserClass should just call myAuthClass when necessary (ie when a user tries to log in) and update its internal structure (new emails, favourites, cart, etc) as necessary.
  • 或者甚至myUserClass应该在必要时调用myAuthClass(即当用户尝试登录时)并根据需要更新其内部结构(新电子邮件,收藏夹,购物车等)。

As you can tell I'm a bit of an OOP n00b. Concpetually I seem to be able to make a case for each of the methods, so I'm interested in hearing from other people regarding the +ves/-ves of the various approaches.

你可以告诉我有点OOP n00b。我似乎能够为每种方法提供一个案例,所以我有兴趣听取其他人关于各种方法的+ ves / -ves的意见。

Cheers.

3 个解决方案

#1


From an accademic perspective, all 3 options are incorrect in that they are programmed against concrete implementations and not against an abstract interface. As such they are directly coupled together, which limits reuse - you re-use them both or not at all.

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

You could generate IUserClass, or IAuthClass and implement this abstract interface into a concrete class and then I would go for a situation where the auth class implementation took an IUserClass when authenticating to populate, or the user class was given an implementation of IAuthClass to authenticate against.

你可以生成IUserClass或IAuthClass并将这个抽象接口实现到一个具体的类中,然后我会考虑这样一种情况,即auth类实现在进行身份验证时需要IUserClass,或者用户类被赋予IAuthClass的实现以进行身份​​验证。

In each scenario this allows the most flexability, in that the auth class can be reused and different versions of the UserClass can be generated, or the user class has the ability to use multiple different authentication mechanisms, as long as the inherit from IAuthClass.

在每个场景中,这允许最灵活性,因为可以重用auth类并且可以生成不同版本的UserClass,或者用户类能够使用多个不同的认证机制,只要从IAuthClass继承即可。

The latter approach of giving the user class an authentication object (that implements IAuthClass) would be my preference, in that authentication mechanisms differ, even with a single application, whilst the user class would change less. But to be correct, neither should be based on a concrete implementation.

后一种为用户类提供身份验证对象(实现IAuthClass)的方法将是我的首选,因为即使使用单个应用程序,身份验证机制也会有所不同,而用户类的更改会更少。但要正确,两者都不应基于具体实施。

This can however be seen as over the top, so it's a judgement call.

然而,这可以看作是在顶部,所以这是一个判断。

#2


First of all I suggest you to use the adapter pattern. You should have an abstract class that define the interface (the public methods) than you create a class that implements a particular type of authentication. For instance you can create a class/adapter for DB base authentication, one for LADP authentication.. etc...

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

The best thing instead of reinventing the wheel, you should use a ready made solution. I have used Zend_Auth, which implements the adapter pattern. By using Zend_Auth you can understand good OOP practicies, the adapter pattern, the use of interfaces and abstract classes, if you want to.

最好不要重新发明*,你应该使用现成的解决方案。我使用了Zend_Auth,它实现了适配器模式。通过使用Zend_Auth,您可以了解良好的OOP实践,适配器模式,接口和抽象类的使用(如果您愿意)。

Here you can see how I have used Zend_Auth for an intranet;

在这里你可以看到我如何使用Zend_Auth作为内部网;

        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.'
            );
        }
    }

#3


The main advantage of chaining classes is making them independant of one another, so modifying one has absolutely no (or alot less) effect on the other. For example, say you want to change the Authentification method, you won't need to change the user, and vice-versa.

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

Other small advantages come out for both methods, but this maintainability is the main one here

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

#1


From an accademic perspective, all 3 options are incorrect in that they are programmed against concrete implementations and not against an abstract interface. As such they are directly coupled together, which limits reuse - you re-use them both or not at all.

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

You could generate IUserClass, or IAuthClass and implement this abstract interface into a concrete class and then I would go for a situation where the auth class implementation took an IUserClass when authenticating to populate, or the user class was given an implementation of IAuthClass to authenticate against.

你可以生成IUserClass或IAuthClass并将这个抽象接口实现到一个具体的类中,然后我会考虑这样一种情况,即auth类实现在进行身份验证时需要IUserClass,或者用户类被赋予IAuthClass的实现以进行身份​​验证。

In each scenario this allows the most flexability, in that the auth class can be reused and different versions of the UserClass can be generated, or the user class has the ability to use multiple different authentication mechanisms, as long as the inherit from IAuthClass.

在每个场景中,这允许最灵活性,因为可以重用auth类并且可以生成不同版本的UserClass,或者用户类能够使用多个不同的认证机制,只要从IAuthClass继承即可。

The latter approach of giving the user class an authentication object (that implements IAuthClass) would be my preference, in that authentication mechanisms differ, even with a single application, whilst the user class would change less. But to be correct, neither should be based on a concrete implementation.

后一种为用户类提供身份验证对象(实现IAuthClass)的方法将是我的首选,因为即使使用单个应用程序,身份验证机制也会有所不同,而用户类的更改会更少。但要正确,两者都不应基于具体实施。

This can however be seen as over the top, so it's a judgement call.

然而,这可以看作是在顶部,所以这是一个判断。

#2


First of all I suggest you to use the adapter pattern. You should have an abstract class that define the interface (the public methods) than you create a class that implements a particular type of authentication. For instance you can create a class/adapter for DB base authentication, one for LADP authentication.. etc...

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

The best thing instead of reinventing the wheel, you should use a ready made solution. I have used Zend_Auth, which implements the adapter pattern. By using Zend_Auth you can understand good OOP practicies, the adapter pattern, the use of interfaces and abstract classes, if you want to.

最好不要重新发明*,你应该使用现成的解决方案。我使用了Zend_Auth,它实现了适配器模式。通过使用Zend_Auth,您可以了解良好的OOP实践,适配器模式,接口和抽象类的使用(如果您愿意)。

Here you can see how I have used Zend_Auth for an intranet;

在这里你可以看到我如何使用Zend_Auth作为内部网;

        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.'
            );
        }
    }

#3


The main advantage of chaining classes is making them independant of one another, so modifying one has absolutely no (or alot less) effect on the other. For example, say you want to change the Authentification method, you won't need to change the user, and vice-versa.

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

Other small advantages come out for both methods, but this maintainability is the main one here

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