Как я могу моделировать сложные ролевые отношения, в которых только определенные группы лиц могут принимать участие в роли? - PullRequest
5 голосов
/ 28 февраля 2009

Допустим, мне нужно смоделировать блюда закусочной.

Еда может состоять из нескольких «компонентов»:

  1. (картофель фри или рис или дольки)
  2. И (Один из шести разных напитков)
  3. И (Один или два из семи разных соусов ИЛИ ни одного)

Другая еда может состоять из:

  1. (салат или рис)
  2. И (Чеснок ИЛИ не чеснок)

Дальнейшее питание может состоять из:

  1. Просто картошка

  2. Просто напиток

  3. Просто ...

Как я могу смоделировать это? (UML, отношение сущности, код, ... все, что вы можете объяснить лучше)

Возможно, это поможет, если вы знаете некоторые задачи, которые я хочу выполнить, поэтому:

  • Разрешение клиенту сначала выбрать еду и отобразить все оставшиеся «дополнения».
  • Обнаружение еды из списка компонентов. Например, если клиент заказал картофель фри, соус и напиток, то можно будет обнаружить блюдо из первого примера.

Я думал о том, чтобы разделить все компоненты на статьи, а затем добавить какое-то ролевое отображение, чтобы пометить «картофель фри» как дополнение к «чизбургеру», «шницелю», «...», но потом я удивился, как я мог моделирование нескольких надстроек, необязательных надстроек, надстроек n-out-of-m ...

Надеюсь, вы мне поможете ...

Ответы [ 5 ]

1 голос
/ 28 февраля 2009

Если это домашнее задание, это может не иметь значения ... Но - если это будет использоваться в реальном приложении, я настоятельно рекомендую не использовать конкретные классы для каждого элемента питания, т.е. Класс кокса, класс салата, класс риса и т. Д., Как рекомендовано выше. Это верный способ сделать ваше приложение негибким.

Было бы намного лучше иметь класс продуктов питания и класс напитков с именным свойством или чем-то подобным.

Представьте, что вам нужно пересобрать все ваше приложение только потому, что теперь есть новый особый или продуктовый продукт ... не круто;).

Я думаю, что в других ответах отсутствует идея группы. Каждый продукт питания может принадлежать к группе вместе с другими продуктами или сам по себе.

Скажем, картофель фри, рис и дольки относятся к группе А. Напитки относятся к группе В. Тогда вы можете смоделировать комбо как список групп - т.е. 1 элемент группы A и 1 элемент группы B или два элемента группы A и 1 элемент группы B.

Вы также можете сделать продукты питания принадлежащими к нескольким группам одновременно ... чтобы сделать варианты более гибкими.

Модель БД может усложнить определение всех отношений, но я думаю, что это необходимо.

Возможно, что-то вроде этого:

group(id, name, desc) - группа похожих предметов - закуски, закуски, напитки ... или что-нибудь еще

foodItem(id, name, desc) - представляет собой единое целое - картофель фри, рис и т. Д.

foodItem_group(foodIgem_Id, group_Id) - сопоставляет продукты с их группой - многие ко многим

combo(id, name, desc) - описывает комбо

combo_group(combo_Id, group_Id) - отображает группы в комбинации - многие ко многим

Я думаю, что это подойдет для представления базовой требуемой модели - вы можете захотеть, чтобы дополнительные таблицы хранили то, что заказал клиент на самом деле ... и, конечно, обнаружение того, соответствует ли заказ клиента комбо, остается за вашей бизнес-логикой.

1 голос
/ 28 февраля 2009
  1. Кажется, что заказ может состоять из блюд, компонентов или их комбинации, поэтому я бы сказал, что класс Order имеет список Component с и Meal с. Meal должен либо подкласс Component, либо они должны реализовывать тот же интерфейс.
  2. A Meal состоит из нескольких «слотов», которые могут быть заполнены некоторым набором Component с. Meal s должен знать, сколько у них слотов и какие Component s могут их заполнить.
  3. Вопрос "обнаружение Meal из списка Component s" сложен. Вдобавок ко всему, лучший способ, о котором я могу думать, это дать каждому Meal метод, который принимает список Component с и возвращает true, если из них можно сделать Meal (или, возможно, подмножество Component с, которые составляют это Meal). Order просмотрел бы список Meal s, о которых он знает, и выяснил, можно ли из них сделать Component в текущем Order. Возможно, есть лучший способ сделать это.

Надеюсь, это поможет!

1 голос
/ 28 февраля 2009

Создать Компонент класс и подклассы (или объекты) для всех возможных типов Компонентов.

Создать абстрактный класс Еда и подклассы для всех возможных типов Еды. Еда может проверить, соответствует ли определенный список Компонентов (для обнаружения еды из списка компонентов). А еда может предоставить клиенту все варианты компонентов для этого блюда.

Я согласен с Амандой, что Еда должна быть построена из " Слотов ". Каждый слот представляет один из вариантов выбора компонента питания, например, Картофель фри или рис или дольки. Слот также может моделировать опцию m-outof-n.

Класс питания:

class Meal
{
    class MealSlot
    {
        Add(Component);
        bool DoesItMatch(vector<Component> ComponentsVector)
        {
            //Check if this Slot is filled by some element(s)
            // of ComponentsVector 
        }
        PrintSlotOptions();
        vector<Component> Options;

        // for m-of-n option, if multiple items can be chosen in this slot
        int HowManyNeededToFillIt; 
    };

    bool DoesItMatch(vector<Component> ComponentsVector)
    {
        //Check if all Slots are filled by ComponentsVector elements,
        //using Slot::DoesItMatch function
    }
    void PresentChoices()
    {
        for(i=0; i < Slots.size(); i++)
             Slots[i].PrintSlotOptions;
    }
    vector<Slot> Slots;
};

Одно из конкретных блюд: (салат или рис) и (чеснок или нет чеснока)

class MealType2 : public Meal
{
    MealType2()
    {
        Slots[0].Add(Salad);
        Slots[0].Add(Rice);
        Slots[1].Add(Garlic);
        Slots[1].Add(NOTHING);
    }    
};

Создайте класс Order , который будет содержать имя Meal и список компонентов. Если еда заказана, вызовите Meal.PresentChoices (). И если указан список компонентов, просмотрите все блюда и вызовите Meal.DoesItMatch.

0 голосов
/ 28 февраля 2009

похоже, что вы едите, может быть почти любой коллекцией продуктов, поэтому начните с одного абстрактного базового класса (или интерфейса) для Пищи. сделать множество конкретных подклассов, по одному на каждую еду: кокс, чай, стейк, курица, картофель, рис, макароны, суп, салат и т. д.

Создайте интерфейсы ваших компонентов: закуска, обед, белок, крахмал, десерт, напиток и т. Д.

преобразовать ваши конкретные классы в ту иерархию, в которую они, кажется, хотят войти, когда вы пишете код и тесты.

посыпать компоненты интерфейсов там, где они имеют смысл.

0 голосов
/ 28 февраля 2009

Я предполагаю, что это в конечном итоге будет сохранено в базе данных. Предлагаю создать две таблицы:

  1. Будет хранить компоненты (картофель фри, салат, чеснок и т. Д.)
  2. Будет иметь: ID1, ID2, отношения. Отношения существо:
    • принадлежит
    • идет с

На основе отношения «принадлежит» вы можете определить, принадлежат ли все компоненты к определенной еде. Может быть, тогда иди и выбери все компоненты, которые относятся к этой еде, и предложи еду, если выбранные компоненты составляют 50% или больше еды.

На основе отношения «идет с» вы можете предложить дополнения к еде или к выбранным компонентам.

...