Дерево классов PHP, где родитель содержит экземпляры подклассов


У меня есть мастер-класс: "а" с конструктором, который принимает необязательный логин и пароль для веб-службы. У меня есть подклассы A: A1, A2 и A3, которые имеют методы для других веб-сервисов от той же компании. Все они используют один и тот же логин и пароль, но используют их по-разному. Каждый из них имеет свой собственный набор методов.

Итак, если у меня уже есть экземпляр родительского класса (или любого из подклассов), как я могу создать другие подклассы без необходимости повторной проверки подлинности родительского класса класс?

Я хочу сделать вот что:

class A {

    protected static $authenticated_service_handle; //Takes a while to set up
    protected $instance_of_A1;

    function __construct($login = null, $password = null) {
        //Go do login and set up
        $authenticated_service_handle = $this->DoLogin($login, $password)

        //HELP HERE: How do I set up $this->instance_of_A1 without having to go through construction and login AGAIN??
        //So someone can call $instance_of_A->instance_of_A1->A1_Specific_function() ?
    }

}

class A1 extends A {

    function __construct($login = null, $password = null) {
        parent::__construct($login, $password);
    }

    public function A1_Specific_function() {
    }

}

//How I want to use it.
$my_A = new A('login', 'password');
$method_results = $my_A->instance_of_A1->A1_Specific_function();
$second_results = $ma_A->instance_of_A2->A2_Specific_function();

Есть идеи, как сделать это естественно? Это похоже на отступление от стандартной методологии OO, но мои вызывающие клиенты должны будут использовать методы A1, A2 и A3 одновременно, но количество методов и их организация поддаются разбиению на подклассы, основанные на функциональности.

1 3

1 ответ:

Если вещь, которую вы создаете в своем классе A, является соединением, которое может быть использовано всеми классами, которые его требуют, Вы можете использовать его как таковой:

class ServiceConnection
{
    private $_authenticated_service_handle; //Takes a while to set up

    function __construct($login = null, $password = null) {
        //Go do login and set up
        $_authenticated_service_handle = $this->DoLogin($login, $password)
    }

    public function DoSomething()
    {
        $_authenticated_service_handle->DoSomething();
    }

}

И передайте это соединение всем объектам, которые в нем нуждаются:

$connection = new ServiceConnection('login', 'password');

$my_A1 = new A1($connection);
$my_A2 = new A2($connection);
$my_A3 = new A3($connection);

$my_A1->A1_Specific_function();
$my_A2->A2_Specific_function();
$my_A3->A3_Specific_function();

Классы AN будут выглядеть следующим образом:

class A1 {

    private $_connection;

    function __construct($connection) {
        $_connection = $connection;
    }

    public function A1_Specific_function() {
        $_connection->doSomething();
    }

}