为了好玩,我正在设计一个简单的系统来存储唱片(黑胶唱片)数据和其他一些与唱片相关的一般项目(袖子、唱片清洁器等)。
由于 90% 的数据将是黑胶唱片和其他 10% 的其他项目,我考虑将它们分为两类:唱片和项目。请记住,尽管最终不同,但两者都是具有某些共同点的产品,例如价格、数量等。
我怀疑是否应该创建一个抽象类,比如 Item,以及两个扩展 Item 的类:Records 和 NonMusicalProducts。像这样的东西:
abstract class Item {
static function getItemPrice($itemId, $type='record'){
$result = 0;
// query record table if type is record, otherwise query nonmusicalproduct table
return $result;
}
abstract function getItemDetails();
}
而记录:
class Record extends Item {
static function getItemDetails($id) {
// query DB and return record details
}
}
和NMProduct
class NMProduct extends Item {
static function getItemDetails($id) {
// query DB and return NMProduct details
}
}
将 NMProduct 和 Record 中的两个方法都定义为静态是否可以?我并不总是会从对象访问该方法。
另一种选择是只有一个 Item 类和一个从 item 继承的 Record 类,但我已经到了一个似乎不正确的地步,尤其是在尝试获取详细信息时:
class Item {
function getItemDetails($id, $type){
if ($type == 'record') {
// query record table using id
}
if ($type == 'nmproduct'){
// query nmproduct table
}
}
感觉不对,因为我认为去记录类获取记录详细信息更合适,因为列与nmproduct中的列不同。在一个父类中这样做感觉违背了面向对象的目的。
或者我能想到的最后一个选项是一个类项目:
class Item {
function getItemPrice($id, $type) {
// if type is record then query the record table
// if type is nmproduct then query the nmproduct table
}
function getItemDetails($id, $type) {
// if type is record then query the record table
// if type is nmproduct then query the nmproduct table
}
}
同样,最后一个选项感觉不对,因为太多不相关的东西会被浓缩到一个类中。记录属性(即artist_id、number_of_discs 等)与nmproduct 不同。
解决这个问题的最佳方法是什么?
最佳答案
我会创建 2 个具有不同 getDetails
和 getPrice
实现的类:
interface Detailable {
public function getDetails($id);
public function getPrice($id);
}
class Record implements Detailable{
public function getDetails($id) {
// custom Record Details
}
public function getPrice($id) {
// custom Record price
}
}
class NMProduct implements Detailable{
public function getDetails($id) {
// custom NM Product Details
}
public function getPrice($id) {
// custom NMProduct price
}
}
接下来将
NMProduct
或 Record
实例传递给 Item
的构造函数:class Item {
protected $_type;
constructor(Detailable $type) {
$this->_type = $type;
}
function getItemPrice($id) {
return $this->_type->getPrice($id);
}
function getItemDetails($id) {
return $this->_type->getDetails($id);
}
}
所以,真正的db查询是delegated,从
Item
到具体实现,NMProduct
和Record
是不同的。关于面向对象设计 : Abstract class design vs Regular Inheritance,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50246290/