这是我评论的扩展版本。我同意在数据库中放入 SQL/可执行代码通常是一个坏主意,我认为在这种情况下你可以避免这种情况。
我会这样做:
晋升
-------------------------------------------------- ----------
标识 (pk) | 短名称 (uniq) | 参数?| 序列化参数?
1 | 九月促销| ... |
2 | 长期住宿 | ... |
-------------------------------------------------- ----------
room_promotion
-------------------------------------------------- --
room_id (fk) | Promotion_id (fk) | 序列化参数
1 | 1 | {折扣=10;开始日期=x;结束日期=y }
2 | 2 | { 长度=14 }
-------------------------------------------------- --
这种方法为您可能想要运行的促销类型提供了最大的灵活性。由于每个促销活动都有许多取决于业务逻辑的参数,我建议在每个房间的情况下,您有一列序列化参数,因此该表中没有大量未使用的列。请记住,这确实打破了一些关系规则,但谨慎使用并意识到其局限性,这是一种有用的方法。
您同样可以针对每个促销行设置参数或序列化参数(例如,如果您知道“long_stay”促销的所有使用期限为 14 天)。
请注意,我已经安排了“room_promotion”表,以便可以将多个促销活动应用于一个房间。(room_id, promotion_id)
如果您确定一个主键始终只适用于一次,您可以创建一个主键。
好的,现在您有了一个可以应用“促销规则”的机制。但是,业务逻辑仍然属于您的代码。因此,查找短名称,驼峰式,然后使用 Ruby 中的动态查找机制来应用折扣。我不使用 Ruby,但在 PHP 草图形式中它可能看起来像这样:
获取对象 $Bill(在应用折扣之前)
$Discount = DiscountFactory::getInstance(
'september_promo',
反序列化($序列化)
);
$Bill->applyDiscount($Discount);
显示修改后的账单
在内部,我认为september_promo
会转换为SeptemberPromo
,因此这是一个类(对不起,再次是 PHP):
类九月促销扩展促销
{
// 这里添加抽象方法的具体实现
公共函数 executeDiscount($Bill) { ... }
}
反过来,Promotion 可以有一个抽象方法,用于根据applyDiscount()
每个房间的价值、每个促销的价值和账单的详细信息来确定要应用的折扣。
只要您保持折扣业务逻辑相当通用,您的酒店经理就可以使用序列化参数对其进行自定义,而不需要为每个新促销活动都需要新的 Ruby 代码(除非他们想要一个新的促销类型)。考虑到这一点,SeptemberPromo可能过于具体 - 也许MonthSpecial?
显然,您需要构建一个 UI 来让酒店经理存储新的promotion
和room_promotion
行,但这应该很容易。