これが私のコメントの拡張版です。データベースにSQL/実行可能コードを入れることは一般的に悪い考えであることに同意します。この場合、それを避けることができると思います。
私はこのようにします:
昇進
-------------------------------------------------- ----------
ID (pk) | 短い名前 (一意) | パラメータ?| | serialized_params?
1 | september_promo | ... |
2 | 長期滞在 | ... |
-------------------------------------------------- ----------
room_promotion
-------------------------------------------------- --
room_id (fk) | プロモーション_id (fk) | serialized_params
1 | 1 | {割引=10; 開始日=x; end_date=y }
2 | 2 | { 長さ=14 }
-------------------------------------------------- --
このアプローチにより、実行したいプロモーションの種類に最大限の柔軟性が得られます。各プロモーションには、ビジネス ロジックに応じて多数のパラメーターがあるため、部屋ごとのケースでは、シリアル化されたパラメーターの列を用意して、このテーブルに未使用の列を多数持たないようにすることをお勧めします。これはいくつかのリレーショナル ルールに違反することに留意してください。
同様に、各プロモーション行に対してパラメーターまたはシリアル化されたパラメーターを使用することもできます (たとえば、'long_stay' プロモーションのすべての使用が 14 日間であることがわかっている場合)。
複数のプロモーションを部屋に適用できるように「room_promotion」テーブルを配置したことに注意してください。常に一度にしか適用できない(room_id, promotion_id)
ことが確実な場合は、主キーを作成できます。
これで、「プロモーション ルール」を適用できるメカニズムができました。ただし、ビジネス ロジックは引き続きコードに属します。そのため、短縮名を検索してキャメルケースにし、Ruby の動的検索メカニズムを使用して割引を適用します。Ruby は使用しませんが、PHP のスケッチ形式では次のようになります。
オブジェクト $Bill の取得 (割引が適用される前)
$ディスカウント = ディスカウントファクトリー::getInstance(
'september_promo',
unserialize($serialized)
);
$Bill->applyDiscount($Discount);
変更された請求書の表示
内部的には、クラスであるseptember_promo
に変換されるSeptemberPromo
と思います (申し訳ありませんが、PHP が再び):
クラス SeptemberPromo は Promotion を拡張します
{
// ここに抽象メソッドの具体的な実装を追加します
public function executeDiscount($Bill) { ... }
}
applyDiscount()
次に、プロモーションは、部屋ごとの値、プロモーションごとの値、および請求書の詳細を考慮して、適用する割引を決定するために使用される抽象メソッドを持つことができます。
ディスカウント ビジネス ロジックをかなり一般的なものにしておく限り、ホテル マネージャーは、新しいプロモーションごとに新しい Ruby コードを必要とするのではなく、シリアル化されたパラメーターを使用してそれをカスタマイズできます (新しいプロモーションタイプが必要な場合を除く)。そのことを念頭に置いて、SeptemberPromoはおそらく具体的すぎるでしょう。
もちろん、ホテルの支配人が新しい行を格納できるように UI を構築する必要がありますpromotion
がroom_promotion
、それは非常に簡単なはずです。