1

我在想出我正在构建的一个小型 php 应用程序的 OOP 设计时遇到了一点困难。我在数据库中有餐厅的信息,分为一个restaurant表和一个locations表。两个表都有一些共同的列,例如phonewebsitelogo urllocations显然和之间的关系restaurants是多对一的。

所以问题来了:我想创建一个Restaurant包含与全球餐厅信息相关的所有信息的类,例如名称、电话、网站、徽标等。然后我想创建一个Location包含特定位置信息的类,例如地址、电话、网站、标志等

我遇到的问题是我希望能够实例化这两种对象类型,但Location如果它本身不存在,还希望让类回退到父数据上。通常,您可以编写如下内容(缩写):

class Restaurant {

    protected $phone;

    function __construct($restaurant_id) {
        // Perform db call here and set class attributes
    }

    public function getPhone() {
        return $this->phone;
    }
}

class Location extends Restaurant {

    function __construct($location_id) {
        // Perform db call here and set class attributes

        // $restaurant_id would be loaded from the DB above
        parent::__construct($restaurant_id)
    }
}

$location = new Location(123);
echo $location->getPhone();

$restaurant = new Restaurant(456);
echo $restaurant->getPhone();

但就像我说的,我希望 getPhone() 方法首先检查 $this->phone,如果它不存在,则回退到父级。这样的事情会是正确的方法吗?

class Restaurant {

    private $phone;

    function __construct($restaurant_id) {
        // Perform db call here and set class attributes
    }

    public getPhone() {
        return $this->phone;
    }
}

class Location extends Restaurant {

    private $phone;

    function __construct($location_id) {
        // Perform db call here and set class attributes

        // $restaurant_id would be loaded from the DB above
        parent::__construct($restaurant_id)
    }

    public function getPhone() {
        if(!empty($this->phone)) {
            return $this->phone;
        }
        return parent::getPhone();
    }
}

$location = new Location(123);
echo $location->getPhone();

我觉得上面的代码真的很hacky,可能有更好的方法来完成这个。Location由于两者具有共同的属性,类扩展Restaurant而是Restaurant为“父”对象保存一个类型的变量会更好吗?那么在Location::getPhone()方法中,是否进行了类似的if(empty())检查呢?

4

1 回答 1

2

Location不应扩展Restaurant,因为它本身不是餐厅;这是那家餐厅的众多地点之一。

class Location {
    private $restaurant;
    private $phone;

    public function getPhone() {
        return $this->phone ?: $restaurant->getPhone();
    }
}

现在,由于这两个类之间有很多共同的字段,您可能想要定义一个它们各自扩展的公共基类,例如CompanyInfoHolder包含网站、电话和徽标的类。在这种情况下,将完全按照上面的Location方式覆盖。getPhone

于 2012-06-14T02:59:52.977 回答