Связывание объектов многие-ко-многим
От: Аноним  
Дата: 11.12.10 20:54
Оценка:
Собсно сабж: есть наборы объектов двух типов. Нужно связать их между собой, чтобы по связям можно было вытащить соответственные наборы объектов. В базах данных обычно используют создание дополнительной связующей сущности. Как это грамотно реализовать в стиле ООП?
Re: Связывание объектов многие-ко-многим
От: Павел Сумароков Россия http://aldigit.com/
Дата: 12.12.10 08:42
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Собсно сабж: есть наборы объектов двух типов. Нужно связать их между собой, чтобы по связям можно было вытащить соответственные наборы объектов. В базах данных обычно используют создание дополнительной связующей сущности. Как это грамотно реализовать в стиле ООП?


Создать третий класс агрегирующий объекты первых двух типов. Если нужно отношение многие ко многим, то новый класс будет содержать два списка. Один ко многим — ссылка и список, и т.д.

Главное не создавайте двунаправленных зависимостей без лишней необходимости. Это повышает связность кода.

Keep it simple =)
Re[2]: Связывание объектов многие-ко-многим
От: Павел Сумароков Россия http://aldigit.com/
Дата: 12.12.10 08:51
Оценка:
ПС>Создать третий класс агрегирующий объекты первых двух типов. Если нужно отношение многие ко многим, то новый класс будет содержать два списка. Один ко многим — ссылка и список, и т.д.

ПС>Главное не создавайте двунаправленных зависимостей без лишней необходимости. Это повышает связность кода.


Возможно совет не для всех задач подойдёт. Посмотрите как эту проблему решает JPA или любой другой ORM framework.

Т.е. нужная вам схема таблиц представляется классами. Google: jpa many to many

В примерах с Hibernate всё-таки bidirectional dependency.
Re[2]: Связывание объектов многие-ко-многим
От: _AHoHuM  
Дата: 13.12.10 00:08
Оценка:
Здравствуйте, Павел Сумароков, Вы писали:

ПС>Создать третий класс агрегирующий объекты первых двух типов. Если нужно отношение многие ко многим, то новый класс будет содержать два списка. Один ко многим — ссылка и список, и т.д.


ПС>Главное не создавайте двунаправленных зависимостей без лишней необходимости. Это повышает связность кода.


ПС>Keep it simple =)


Ясно. Спасибо =)
Re[2]: Связывание объектов многие-ко-многим
От: sokel Россия  
Дата: 13.12.10 08:27
Оценка:
Здравствуйте, Павел Сумароков, Вы писали:

ПС>Создать третий класс агрегирующий объекты первых двух типов. Если нужно отношение многие ко многим, то новый класс будет содержать два списка. Один ко многим — ссылка и список, и т.д.


Можно ещё объект связи интрузивно включить в связываемые объекты:

#include <iostream>
#include <boost/intrusive/list.hpp>
using namespace boost::intrusive;

struct foo;
struct bar;

typedef list_base_hook< tag<foo> > foo_hook;
typedef list_base_hook< tag<bar> > bar_hook;
// тип связи
struct foo_bar : foo_hook, bar_hook
{
    foo_bar(foo& f, bar& b);
    foo& f_;
    bar& b_;
    void print();
    void release();
};

struct foo
{
    foo() { static int id = 0; id_ = id++; } 
    ~foo() { while(!bar_.empty()) bar_.front().release(); }
    int id_;
    list<foo_bar, base_hook<foo_hook> > bar_;
    void print() { std::for_each(bar_.begin(), bar_.end(), std::mem_fun_ref(&foo_bar::print)); }
};

struct bar
{
    bar() { static int id = 0; id_ = id++;  } 
    ~bar() { while(!foo_.empty()) foo_.front().release(); }
    int id_;
    list<foo_bar, base_hook<bar_hook> > foo_;
    void print() { std::for_each(foo_.begin(), foo_.end(), std::mem_fun_ref(&foo_bar::print)); }
};

foo_bar::foo_bar(foo& f, bar& b)
: f_(f)
, b_(b)
{
    f.bar_.push_back(*this);
    b.foo_.push_back(*this);
}
void foo_bar::print() { std::cout << "foo[" << f_.id_ << "] -> bar[" << b_.id_ << "]" << std::endl; }
void foo_bar::release() {  f_.bar_.erase(f_.bar_.iterator_to(*this)); b_.foo_.erase(b_.foo_.iterator_to(*this)); delete this; }


int main()
{
    int i;
    foo f[5];
    bar b[5];
    for(i=0; i<5; ++i)
    {
        new foo_bar(f[i], b[i]);
        new foo_bar(f[i], b[(i==4)?0:i+1]);
    }
    std::cout << "foo links:" <<std::endl;
    std::for_each(&f[0], &f[5], std::mem_fun_ref(&foo::print));
    std::cout << "bar links:" <<std::endl;
    std::for_each(&b[0], &b[5], std::mem_fun_ref(&bar::print));

    return 0;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.