我对OOP / OOD很陌生,我意识到我有很多需要学习的东西,所以我想问SO社区他们的意见。
基本上,我正在使用CakePHP的MVC框架,我正在构建的在线商店只使用2个模型,Category和Product,由以下CREATE语句描述:
CREATE TABLE `categories` (
`id` int(11) unsigned NOT NULL auto_increment,
`name` varchar(255) default NULL,
`parent_id` int(11) default NULL REFERENCES categories(`id`),
`lft` int(11) default NULL,
`rght` int(11) default NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `products` (
`id` int(11) unsigned NOT NULL auto_increment,
`name` varchar(255) default NULL,
`artist_id` int(11) default NULL REFERENCES artists(`id`),
`description` text default NULL,
`category_id` int(11) default NULL REFERENCES categories(`id`),
`status` enum('in stock', 'pre-order', 'out of stock') NOT NULL,
`price` decimal(6,2) default NULL,
`picture` varchar(255) default NULL,
`picture2` varchar(255) default NULL,
PRIMARY KEY (`id`)
);
在线商店将包含:
基本上,这是类别树的结构,但我们可能会在未来添加新类别。现在,所有产品都被视为产品类对象,其category_id是区分不同类型产品的唯一方法。在线商店也只是该网站的一部分。该网站的其余部分包含艺术家简历和唱片等信息;因此我也有模型/表格:艺术家,专辑,追踪。
这是一个好方法吗?或者我应该为继承自Product类的CD / T恤/ MP3 / ...创建单独的子类?我想将商店中的每张音乐CD与唱片目录条目相关联,以自动生成音轨列表和产品说明的其他信息。
如果这不是一个好的方法,你会怎么做呢?另外,我应该在Category / Product类中包含哪些方法/属性?我应该只在类别树的叶节点中列出产品吗?
编辑:
显然这种设计是不完整的。正如Cyril指出的那样,Product.price字段缺失了,并且仍然没有销售条款。我实际上还在努力弄清楚如何最好地设计&实现商店的这些方面。最有可能的是,我将只有另一个名为订单的模型,但实际上处理订单变得更加复杂,因为我们根据出货目的地和订单包含的内容应用不同的运费。
答案 0 :(得分:2)
我更喜欢配置+行为方法而不是子类。
这可以是类别级别的一些行为。根据具体情况,某些行为可能与单独的产品类型相关联,例如适用于某些产品的某些行为,而不管其类别如何。对于最后这篇文章,吸烟建议也很有意义,因为你可以将这些额外的行为与其他类别联系起来。这样,只要您处理已编码的行为,就可以添加新类别,指明它将支持哪些行为。
一个小变化,是与类别而不是位相关联的行为列表。
其他类将用于行为,而不必在产品类下混合使用。如果您需要为这些额外的事物关联UI,您可以将其与行为联系起来,而不管产品类型如何。
答案 1 :(得分:1)
是的,您可能应该为不同类型的产品创建单独的子类,特别是如果它们具有特定于类型的功能。就像你提到的自动生成曲目列表一样。
但即使没有这个,通过使用单独命名的产品类,您将在处理特定于产品类型的代码时使代码更具可读性和逻辑性。
您可能还想创建更具体的数据库模型。 像
表:产品 product_clothes
PROD_ID
......衣服特定的东西......
product_music
PROD_ID
......音乐特定的东西......
product_merch
PROD_ID
...商品特定的东西..
因为音乐的尺寸不是以英寸为单位,而且衣服没有比特率。
答案 2 :(得分:1)
您应跳过category_id列,并将关系建模为更像标签云。您需要将每个产品与一个或多个类别相关联。
您应该跳过artist_id列,并将关系建模为更像标签云。您最终希望将某个产品与多位艺术家联系起来。
类别已过时,您必须使用标签云。通常,您不应该使用引用语句创建表;除非表中的每一列都有一个引用声明。
答案 3 :(得分:1)
如果您使用polymorphic behavior,您仍然可以保留产品表并制作不同的“产品子类别”。这是将所有常用数据保存在一个地方(价格等)的简单方法。
或者,您可以在表 attributes 上使用相同的多态行为,并添加任何特定于产品的属性作为属性(name => value pairs)。这完全取决于你头脑中的想法和数据量。
如果您打算拥有一个大型数据库,那么第一个解决方案可能会更好。
答案 4 :(得分:0)
没有
除非你需要一些无法实现简单类别划分的mumbo-jumbo魔法(如自定义T恤徽标等),否则你绝对不应该创建单独的子类。即使在这种情况下,您也可以安全地在类别类中添加额外的标志字段(例如HasLogo)。
但设计并没有让我印象深刻。什么样的商店没有销售条款?价格领域怎么样?
为了灵活性,您还可以将图片放在单独的表格中。
你有什么用lft / rght?您可以使用简单的Inde属性在树中存储类别的位置,但请记住,每次删除/添加类别时都需要更新。