【问题标题】:PHP object oriented hotel applicationPHP 面向对象的酒店应用程序
【发布时间】:2014-07-31 07:35:35
【问题描述】:

目前我正在编写一个面向对象的酒店应用程序来学习 OOP。 我之所以选择这个,是因为在我的书(O'Reilly 的 PHP 设计模式)中,他们编写了一家汽车租赁公司。 现在我已经完成了基本的业务逻辑,但我仍然有一些问题。

Hotel 类中有以下方法:

//All public functions, left it hhere cause of the length
checkOut( HotelRoom $room, DateTime $from, DateTime $to )
changeRoom( HotelRoom $oldRoom, HotelRoom $newRoom, HotelCustomer $customer, DateTime $from, DateTime $to)
checkOut( HotelRoom $room, DateTime $from, DateTime $to )

因此,对于我执行的每一步(预订、更改房间或结帐),我都必须将 HotelRoom 作为参数传递。每个房间都有一个ID和一个号码。 最好实现一个方法 addRoom(HotelRoom $room) 并将所有房间存储在受保护的属性 $rooms 数组中,然后只为方法传递 HotelRoom::$id 还是有更好的方法?

我对 OOP 比较陌生,现在只想知道什么是好的做法。

【问题讨论】:

  • 您为什么要这样做?它能解决什么问题?
  • @SergioTulentsev 我不认为有问题需要解决,只是增强代码 - 还是我看错了?
  • 最好不要使用受保护的数组,因为您将根据其 ID 搜索每个调用适当的 HotelRoom ...在我看来,直接传递对象是正确的方法
  • @hd.: 是的,我的意思是,为什么要为了更改而更改代码?显然必须有某种胜利。在这里我什么也没看到。
  • @SergioTulentsev 啊,好的。我现在明白你的逻辑了:)

标签: php oop object


【解决方案1】:

我不会让您的Hotel 班级负责您提到的三个功能。它们是非常具体的功能,而Hotel 是一个非常广泛的类。

考虑有一个RoomManager 和一个CustomerManager 类。将这些类注入Hotel 类,并让它们负责检索RoomCustomerRoomCustomer 类应包含您概述的特定功能:

class Hotel
{
    public $roomManager;
    public $customerManager;

    public function __construct(RoomManager $rm, CustomerManager $cm)
    {
        $this->roomManager = $rm;
        $this->customerManager = $cm;
    }

    // ...
}

class RoomManager
{
    public function getRoom($id)
    {
        // find room where Room->id == $id;
        return $room;
    }

    // some other stuff may become relevant in here
}

class CustomerManager
{
    public function getCustomer($id)
    {
        // find customer where Customer->id == $id;
        return $customer;
    }

    // some other stuff may become relevant in here
}

class Room
{
    public function checkout(DateTime $from, DateTime $to)
    {
        // ...
    }
}

class Customer
{
    private $room;

    public function setRoom(Room $hr)
    {
        $this->room = $hr;
    }
}

客户端代码类似于:

// instantiate a Hotel and inject its 2 dependencies
$hotel = new Hotel(new RoomManager, new CustomerManager);

// checkout Room 3
$hotel->roomManager->getRoom(3)->checkout();

// change Customer 2's Room from Room 3 to Room 4
$newRoom = $hotel->roomManager->getRoom(4);
$hotel->customerManager->getCustomer(2)->setRoom($newRoom);

请注意您的班级职责如何变得更加具体。 Hotel 类只是想管理特定的组件。

【讨论】:

    【解决方案2】:

    我会走以下路:

    添加对象 Booking,该对象具有酒店房间和客户的 from、to 和 reference 然后 changeRoom 成为一个预订方法,它只改变房间,不改变日期。 结帐也成为一种预订方法,因为提供结帐日期没有意义。 房间何时可用,何时不可用,并且应该为此提供方法。 酒店拥有所有房间,并且应该始终从酒店对象中获取房间

    Hotel
    getRoom($id)
    getAvailableRooms($from, $to)
    
    
    HotelRoom
    checkIn($from, $to) - proxy to reserve($from, $to) - sets the availability
    free($from, $to)
    
    Booking
    changeRoom($newRoom)
    changeDates($from, $to) // this might be tricky, as it may require changing the room as well
    checkOut() // sets the room from the current date to the end of the booking (in case of early checkout) as available
    

    【讨论】:

    • 你的意思是“保留”模式吗?
    • *代理 ---15 个字符
    【解决方案3】:

    您可以这样做,但您可以拥有一个函数 loadRooms(),而不是 addRoom(),它利用数据库访问对象来加载所有房间。在预订时,您只想加载免费房间,同样适用于更改房间。您不需要在 checkout() 中这样做。

    【讨论】:

      【解决方案4】:

      从技术上讲,这两种方法是相似的。根据干净的编码,最好传递房间对象而不是数字,因为您的代码更具可读性。任何使用您的班级的人都会知道他正在使用“房间”而不仅仅是一个数字。

      【讨论】:

        猜你喜欢
        • 2013-06-12
        • 2023-03-23
        • 1970-01-01
        • 2012-11-15
        • 2011-07-09
        • 1970-01-01
        • 2016-01-28
        • 1970-01-01
        • 2011-04-19
        相关资源
        最近更新 更多