在PHP中引用基类内部的扩展类

时间:2016-05-26 15:55:39

标签: php class oop

对不起,也许不是最准确的标题。我无法弄清楚这甚至会被称为什么。

我对使用php的OOP有些新意,因为我的大部分时间花在了程序编程上。为了更好地学习这些概念,我正在使用现有的应用程序并使用OOP重写其中的一部分。下面的例子是我如何设置基类,然后我将基类扩展为几个较小的类,以便于维护。下面,您可以看到我如何扩展基类以创建用户类。 请注意,我的班级定义是在单独的文件中,但我有一个自动注册的自动加载器

class EventScheduler{
    function __construct(){
       // set up database connections here
    } 
}

class User extends EventScheduler{
    private function getUserProfile($username){
       // return an array here representing
       // details of passed username from database
    }

    public function getUserType($username){
        return $this->getUserProfile($username)['user_type'];
    }
}

喜欢能够做的是从基类中引用User类,如下所示:

$eventApp = new EventScheduler();
$userType = $eventApp->User->getUserProfile("nameHere");

我目前正在做的是:

$eventApp = new EventScheduler();
 //do some stuff here using the base class

$users = new User();
$userType = $users->getUserProfile("nameHere");

但是当我添加更多子类时,我不想像我在那里那样实例化每个扩展类,我希望将它们全部分组在基础对象下,而不是让每个扩展类都在其中自己的对象。

2 个答案:

答案 0 :(得分:0)

你想做的是

$users = new User();

//do some stuff here using the base class
// ie $users->someFunctionFromEventScheduler();

$userType = $users->getUserProfile("nameHere");

答案 1 :(得分:0)

这是开始阅读OOP中常见设计模式的一个很好的理由。这里有很多很好的资源,快速的谷歌搜索将产生大量的结果和例子,主要是在github上。

我认为您正在寻找的特定模式是中介模式(Mediator pattern example in PHP)。正如您在示例中所做的那样,不希望扩展类,当您希望类的实例能够访问许多其他可通过一个基类相互通信的类时,中介模式非常有用。前提是“一个好朋友比许多熟人好。”

一个例子:(接口在这里非常有用,因为它们定义了每个类中所需的特定特征)

/**
 * Interface Mediator
 */
interface Mediator {
    /**
     * @param string    $key
     * @param Mediated  $mediated
     * @return void
     */
    public function attach($key, Mediated $mediated);

    /**
     * @param $key
     * @return Mediated
     */
    public function getAttached($key);
}

/**
 * Interface Mediated
 */
interface Mediated {
    /**
     * @param Mediator $mediator
     * @return void
     */
    public function setMediator(Mediator $mediator);

    /**
     * @return Mediator
     */
    public function getMediator();
}

现在我们需要一个基础中介类,我将使用您的事件调度程序示例。请注意,它实现了Mediator接口,因此必须实现接口所需的方法。

/**
 * Class EventScheduler
 */
class EventScheduler implements Mediator {

    /**
     * A collection of mediated instances.
     *
     * @var array
     */
    protected $mediated = [];

    /**
     * @param string $key
     * @param Mediated $mediated
     * @return void
     */
    public function attach($key, Mediated $mediated)
    {
        // So upon attaching a mediated instance we can build the two
        // way binding in one place using the key as the identifier.
        // First we set $this on the mediated instance.
        $mediated->setMediator($this);

        // Then we add this instance to our mediated array inside this instance
        $this->mediated[$key] = $mediated;
    }

    /**
     * @param $key
     * @return Mediated
     */
    public function getAttached($key)
    {
        return $this->mediated[$key];
    }
}

现在我们可以设置一个中介实例。这可以附在调解员身上。请注意,它实现了Mediated接口。

/**
 * Class User
 */
class User implements Mediated {

    /**
     * @var Mediator
     */
    protected $mediator;

    /**
     * @param Mediator $mediator
     * @return void
     */
    public function setMediator(Mediator $mediator)
    {
        $this->mediator = $mediator;
    }

    /**
     * @return Mediator
     */
    public function getMediator()
    {
        return $this->mediator;
    }
}

您可以根据需要创建任意数量的中介实例,并将它们附加到Mediator实例。请记住,这不是特定的调解器,因为可以附加许多实例,在大多数情况下,最好明确指出哪些类可以附加,而不是允许通过密钥进行动态注册。

$scheduler = new EventScheduler();
$user = new User();

$scheduler->attach('user', $user);

// Now we know that we can get the mediator from the User class
$user->getMediator();

// We can also get the User from the mediator itself.
$scheduler->getAttached('user');

当您附加更多类时,您会注意到每个类都可以使用其中介来获取其他附加类的实例,这是一个好朋友的概念来自的地方。

这只是一个例子,并不是为了简洁而完全展现,但是应该让你知道为什么使用常见的设计模式会对你有很大帮助,如果你想养成良好的习惯,那么在学习OOP时这是一个非常好的起点。