Проблема C ++ Object Design: эффективно и безопасно создавать объекты и сохранять / загружать базу данных - PullRequest
2 голосов
/ 15 апреля 2010

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

Раньше я был программистом на Java, но использую C ++ более года. Меня всегда беспокоит одна вещь - стратегия создания бизнес-объектов из сети (например, через SNMP, веб-сервис или другие источники данных ...), сохранение их в базе данных и загрузка при запуске приложения. Обычно мой дизайн выглядит следующим образом:


class Object{
/* this is just a demonstration, in real code, there are all kinds of Object and has relationships*/
friend class DBConnection;
friend class SNMPConn
private:
    std::string& m_strName; 
    //... all kinds of properties
}

class DBConnection
{
   int load(Object& obj);
   int save(Object& obj);
   int modify(Object& obj);
   int loadAll(std::vector);
}

class SNMPConn
{
   int load(Object& obj);
   ...
}

Что меня не устраивает, так это строка "класс друга ...". Это нарушает инкапсуляцию. Я обнаружил некоторые фреймворки, например litesql (sourceforge.net/apps/trac/litesql) и другие коммерческие, но эти фреймворки сложно интегрировать с моим существующим кодом. Я пытаюсь сделать это вручную и пытаюсь найти общую стратегию для такого рода работы.

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

Ответы [ 2 ]

1 голос
/ 15 апреля 2010

Как я понимаю из этой проблемы (нарушение инкапсуляции во время чтения и записи в соединение с БД или SNMP), сначала вам нужен правильный дизайн для устранения этих «друзей». пожалуйста, определите абстрактный класс для соединений (т. е. IDBConnection) и постоянных объектов (т. е. IPersistent). Вы можете использовать шаблон «Абстрактная фабрика» для их создания. Кроме того, изолируйте методы загрузки и сохранения в другом классе и используйте «шаблон посетителя» для инициализации или сохранения ваших объектов из / в вашу БД.

Еще один момент: если вам нужна встроенная БД для вашего приложения, используйте SQLite , для этого есть множество хороших оболочек C ++. Надеюсь, это поможет

0 голосов
/ 15 апреля 2010

Вот как я могу сделать это в псевдокоде:

class Result { 
public: 
    int     getField(name); 
    string  getField(name); 
}

class Connection { 
public: 
    void save(list<pair<string, string>> properties); 
    Result query(); 
} 

class DBConnection { 
private: 
    class DBResult : public Result {  
    } 
public: 
    Result query() { 
        return ( DBResult ); 
    } 
    void save
}

class Object { 
public: 
    void load(Result); 
    void save(Connection) { 
        // make properties list 
        connection.save(properties); 
    } 
} 

Без рефлексии в стиле Java, вероятно, я бы так и сделал, не вступая в отношения "дружба". Тогда вы не будете тесно связывать знание логики соединений с классами соединений.

...

Вы также можете создать шаблонные функции, но вам все равно понадобятся отношения с друзьями.

class Object { 
public: 
    friend template<class Conn, class Obj> load(Conn c, Obj o);
    friend template<class Conn, class Obj> save(Conn c, Obj o);
} 

load<Connection, Object>(Connection c, Object o) { 
    //access o.private to load into c 
} 

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...