【发布时间】:2012-02-26 21:15:49
【问题描述】:
我已经尝试学习 OOP 技术和设计模式有一段时间了,我的方法确实有所改进,但是当我们谈论不同类的对象交互时,我并没有完全点击。我主要在 PHP 中工作,但为了学习,我会接受一个一般性的答案。如果我用错了术语,请提前道歉,我是自学的。这是一个例子:
假设我想为开车四处走动的人建模。有 3 个类:
class Car {}
class Driver {}
class Road {}
我希望 Car 类有一个函数
public function Drive($time) {}
其中驾驶应根据道路的速度限制更新驾驶员的位置。我的问题是构建 Drive 以便 Car 与其他对象交互的最佳方式是什么。我能想到 3 种可能性:
public function Drive($time, $Driver, $Road) {}
这里的优点是函数本身告诉我我需要什么参数。缺点是,如果我有很多类似的操作、一路调用私有函数、添加乘客对象等,我最终可能会传递很多参数。
$Car->setDriver($Driver);
$Car->setRoad($Road);
$Car->Drive($time);
优点是我可以非常简单地调用 Drive,它可以访问它需要的任何东西。缺点是我要记得先设置司机和道路,因为函数定义没有告诉我。
class Car() {
public function Drive($time) {
$Driver = getDriver($this->DriverID);
$Road = getRoad($this->RoadID);
}
}
function getDriver($DriverID) {
static $DriverArray;
// check isset(), create object and place in array if not
return $DriverArray[$DriverID];
}
function getRoad($RoadID) {} // assume similar
优点是所有逻辑都是内部的,DriverID 和 RoadID 存在,因为它们是来自数据库的外键。 (或者它们可以预先手动设置,但这不会是内存问题,因为它是有意分配的。)缺点是所有 Driver 操作都必须通过相同的 getDriver 以免我最终得到单独的实例同一个驱动程序。
为了完整起见,我的第四种方法是SELECT <columns> FROM Car_tbl INNER JOIN Driver_tbl on DriverID INNER JOIN Road_tbl on RoadID,我很确定这是糟糕的 OO 设计,但我过去经常这样做,因为它执行的查询更少。
我倾向于方法 3,但怀疑我在很大程度上遗漏了一些东西。随意回答 PHP 特定的或通常如何考虑的。谢谢。
编辑:到目前为止,感谢您的回答,包括进一步阅读的链接。
与其让这个例子过于复杂,让我们现在假设最简单的 UseCase,但稍后假设最复杂的 UseCase。所以例如速度现在是getRoadSpeedLimit() 的函数,但后来受到getMaxCarSpeed() 和getMaxDriverSpeed() 以及汽车对汽油的需求和驾驶员对食物的需求的限制。如果我们有太多 Driver 对象使用同一条道路等,道路的速度限制会调整。
Gordon 和 UmlCat 似乎(可以这么说)都在使用封装类,对吗?
class RoadTrip_aka_Universe {
// Operates on instances of Car, Driver, Route (which may contain roads)
}
但这是否仍然存在问题,是否在构造函数中添加了 $Car、$Driver 和 $Route,由 setter 应用,从静态外部提取?无论我们决定哪个类应该有方法,它如何访问那些其他对象?
我的直觉反应是,如果一切都放在一个更大的类中,那么该类的内部是否开始类似于具有全局变量的大型无类结构?不要把它当作批评,我只是想理解,因为它感觉像是 OOP 的文字而不是它的精神。
再次感谢。
【问题讨论】:
-
我认为这应该问程序员但是,我喜欢选项 2,它读起来就像你给汽车一个司机,你把汽车放在路上,然后告诉它
drive一些时间,也就是说,虽然汽车可以有司机,但为什么汽车会有一条道路,可能是当前的道路或位置......所以在某种程度上,选项 1 更有意义“与 Y 司机在 A 路上行驶 X 时间”,但是这听起来有点必要,选项 3 不太明确,对我来说,汽车永远不会得到它的司机或道路,不幸的是,我觉得我的评论太抽象而无法成为答案,并期待听到其他人的意见 :)
标签: php oop class design-patterns object