Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проектирование классов, Нужна помощь по проектировке 
:(
    Опции темы
azesmcar
Дата 22.12.2005, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Здравствуйте...

есть класс
Код

class CSession
{
public:
   CSession();
   ~CSession();
   bool LoadSession();
   bool AddVariable(const CString& VarName, const CString& VarValue);
   bool SaveSession();
protected:
private:
   std::map<CString, CString> m_SessionVariables;
}


и класс

Код

class CParams
{
public:
   CParams();
   ~CParams();
   const CString& operator [] (CString& ParamName) const;
protected:
private:
   std::map<CString, CString> m_Params;
}


И еще один

Код

class CPage
{
public:
   CPage()
   {
       m_pSession = 0;
   };
   ~CPage()
   {
       if ( m_pSession )
          m_pSession->SaveSession();       
       delete m_pSession;
   }
   CSession* InitSession() {
       if ( !m_pSession )
       {
          m_pSession = new CSession;
          m_pSession->LoadSession();
       }
       return pSession;
   }
private:
   CSession* m_pSession;
}


В классе CPage можно только добавлять в сессию переменные, а читать их нужно из CParams.
примерно так
Код

void OnSomething(const CParams& Params)
{
   //Params["ID"] не существует
   InitSession()->AddVariable("ID", "1");
   //Params["ID"] должен быть равен 1
}

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

Думаю сделать класс CParams другом CSession чтобы он мог использовать map из CSession. Но тогда встает другой вопрос, откуда он получит указатель на CSession? Можно CParams -у при инициализации передать указатель на CPage но криво как то получается...
Есть идеи?
Добавлено @ 14:25
Или же пихать InitSession в CParams, это на первый взгляд самый легкий способ, но он логически туда не подходит..

Это сообщение отредактировал(а) azesmcar - 22.12.2005, 14:28
PM   Вверх
pablo
Дата 22.12.2005, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 320
Регистрация: 12.2.2005
Где: Вильнюс, Литва

Репутация: 4
Всего: 6



Как вариант, могу предложить такой:

В класс CSession допиши метод который принимает как параметры CParams. В методе AddVariable передаёш параметп ниже в СSession. Только чёто непойму, какая то странная инициализация.
Очень похожа на синглтон, но не то.


--------------------
Первый блин всегда похож на сферу, иногда бывает и куб.
PM MAIL ICQ   Вверх
azesmcar
Дата 22.12.2005, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Это не кусок моего кода, только что написал, для примера...идея заключается в этом...
Передавать как аргумент CParams мне не очень нравится, это все должно автоматически происходить в классе CPage, кто-то другой наследует свой класс от CPage и он не должен иметь дело со всем этим. Ему подаются готовые параметры классом CParams на тарелочке.

Это HTTP сессия, для CGI
Добавлено @ 15:08
Только что прошло в мыслях что то вроде этого...
Сделать CSession в CPage статической переменной, при создании CParams -а передать ему ссылку на CSession.

class CPage;

Код

class CParams
{
public:
   CParams(const CPage& Page)
   {
      m_pPageRef = &Page;
   };
   ~CParams();
   const CString& operator [] (CString& ParamName) const
   {
      return m_pPage->m_pSession->m_SessionVariables[ParamName];
   };
protected:
private:
   std::map<CString, CString> m_Params;
   CPage *m_pPage;
}



В этом случае operator [] будет читать из m_pPage->m_pSession->m_SessionVariables а CParams -а сделать другом CSession.

Но все равно не очень нравится, наверняка можно придумать что нибудь поэлегантнее..
PM   Вверх
Romikgy
Дата 22.12.2005, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 8
Всего: 146



А что мешает создать переменую типа CParams в классе CSession?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
azesmcar
Дата 22.12.2005, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата
А что мешает создать переменую типа CParams в классе CSession?


То что CParams связан не только с сессией, он читает множество параметров из разных мест, и один из этих место сессия..опять таки логически не подходит..т.е. событие
OnSomething получает не CParams а CSession в которой хранятся множество параметров в том числе и сессия...
PM   Вверх
Romikgy
Дата 22.12.2005, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 8
Всего: 146



но он должен где то создаваться
Цитата(azesmcar @ 22.12.2005, 14:35)
CParams

где smile
Цитата(azesmcar @ 22.12.2005, 14:35)
OnSomething получает не CParams а CSession


Цитата(azesmcar @ 22.12.2005, 13:24)
void OnSomething(const CParams& Params)

smile


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
azesmcar
Дата 22.12.2005, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



В функции main()
Код

int main()
{
  CParams params;
  params.ReadParameters(ReadParams_GET|ReadParams_POST|ReadParams_SESSION);
  CPage *pPage = new CMyPage;
  pPage->InitPage( params );
  return 0;
}


Добавлено @ 15:55
Код

void CMyPage::InitPage(const CParams& params)
{
   if ( params["SOMETHING"] == "1" )
   {
       OnSomething(params);
   }
}


Ну например так
Добавлено @ 15:57
Код

class CPage
{
public:
  //Отпускаем детали
  virtual void InitPage(const CParams& params) = 0;
}

class CMyPage: public CPage
{
public:
  virtual void InitPage(const CParams& params)
}

PM   Вверх
Earnest
Дата 22.12.2005, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Я понимаю, что тебе не нравится - слишком много связей - все знают почти обо всех.
Может, можно убрать связь Session-Page? Т.е. пусть страница знает про параметры, а параметры - про сессию.
Собственно, ты похоже так и сделал - в последнем пимере, да?
А дружить никого ни с кем не надо, просто объяви
typedef map<CString,CString> CVariables;
в public-части класса Params (по-моему, самое логичное место), и сделай методы для чтения.



--------------------
...
PM   Вверх
Romikgy
Дата 22.12.2005, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 8
Всего: 146



Цитата(azesmcar @ 22.12.2005, 14:54)
OnSomething(params);

'это отдельная ф-ция или чейто метод?
ЗЫ если честно я чет основного вопроса не понял (уже) !!!


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
azesmcar
Дата 23.12.2005, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата
OnSomething(params);
это функция метод класса CMyPage

Цитата
Может, можно убрать связь Session-Page? Т.е. пусть страница знает про параметры, а параметры - про сессию.


Собственно вчера вечером я так и сделал, подружил сессию и параметры. После чего параметры читают данные напрямую из map<CString, CString> класса сессии..
Сессия обьявлены static. Она на всех одна. Используется примерно так..
Код

void CMyPage::InitPage(const CParams& params)
{
   CSession *pSess = params.InitSession();
   pSess->AddVariable("Login", params["LOGIN"]);
}


в любое время можно вызвать.
Код

params.GetSession()->DestroySession();

Earnest Ну если никаких добавок по этому поводу нет тогда наверное так и оставлю..
PM   Вверх
Earnest
Дата 23.12.2005, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(azesmcar @ 23.12.2005, 08:59)
Сессия обьявлены static. Она на всех одна

Тогда реализуй ее как синглетон. Ибо тогда выражение params.GetSession() как-то бессмысленно выглядит (вроде как у каждого экземпляра параметров может быть своя сессия).



--------------------
...
PM   Вверх
azesmcar
Дата 23.12.2005, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата
Тогда реализуй ее как синглетон. Ибо тогда выражение params.GetSession() как-то бессмысленно выглядит (вроде как у каждого экземпляра параметров может быть своя сессия).


Ну можно заменить GetSession() на что то вроде GetSessionPtr()

А что такое синглетон..не встречал что-то такого...если не сложно пример приведи...

PM   Вверх
Earnest
Дата 23.12.2005, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(azesmcar @ 23.12.2005, 17:54)
Ну можно заменить GetSession() на что то вроде GetSessionPtr()

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

Синглетон - это паттерн проектирования, одиночка то есть. По сути, все как у тебя, только более ясно выражено + принимаются меры, чтобы объект действительно был один.
Я обычно пользуюсь следующей парой макросов, чтобы код ручками не писать:
(Знаю-знаю, отцы макросы использовать не велят, но я привыкла, мне так кажется удобнее smile ).

Код

// singleton.h: все, кто хочет быть синглетоном, его включают 

// это используем внутри определения класса
#define DECLARE_SINGLETON(Class) \
private: \
   Class (); \
public:       \
   ~Class(); \
   static Class& Instance();

// а это - в файле реализации класса
#define IMPLEMENT_SINGLETON(Class) \
   Class& Class::Instance() \
   { \
      static Class theInst;  \
      return theInst;          \
   }                                                     


Использование:
Код

// session.h

#include "singleton.h"
class CSession
{
   DECLARE_SINGLETON(CSession);
public:
   // конструктор-деструктор уже объявлены в DECLARE_SINGLETON 
   .....
};

// ну и еще один макрос, чтобы покороче и редактор подсвечивал
#define   theSession   CSession::Instance()


Код

// sesion.cpp
#include "session.h"

// это нам функцию Instance нарисовали
IMPLEMENT_SINGLETON(CSession)

CSession()
{
   ...
}

~CSession()
{
   ...
}

...и прочая


Далее, везде, где нам нужен объект-сессия, пишем:
Код

theSession.ДайЧегоНибудь();


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


--------------------
...
PM   Вверх
azesmcar
Дата 23.12.2005, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата
Да какая разница, я и не думала, что ты объект по значению возвращаешь.

Не по значению возврашаю smile я в том смысле чтобы функция как бы говорила вот вам указатель на сессию...а не вот вам моя сессия..возвращять она будет все равно тоже самое... CSession *

Я просто кое чего не понял..на кой черт все это нужно...ну макросами так макросами...я и сам правила дядюшки Страуструпа иногда нарушаю...только зачем все это??
Есть класс...
Код

class CParams
{
public:
   static CSession *Session;
}

Код

void OnSomething(const CParams& Params)
{
   Params.Session->RegisterVariable(...);
}

Знаю, опять не подходит...верно, пишем макрос
Код

#define Session CParams::Session


PM   Вверх
blackofe
Дата 23.12.2005, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 29.11.2005

Репутация: 4
Всего: 4



Earnest, smile

обожаю изящные и удобные конструкции (решения).

off: жаль, не могу репутацию добавить. не дорос ишо ;)

Это сообщение отредактировал(а) blackofe - 23.12.2005, 19:17
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1580 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.