Re[6]: serialize / deserialize
От: Angler Россия  
Дата: 07.12.05 09:24
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Это не прокатит, если условие более сложное, чем принадлежность диапазону.


Да, но чем плох тогда checkInvariant?
Re[5]: serialize / deserialize
От: Шахтер Интернет  
Дата: 07.12.05 09:32
Оценка:
Здравствуйте, Angler, Вы писали:

A>Здравствуйте, Шахтер, Вы писали:


Ш>>Как здесь обойтись одним общим методом (одно решение я знаю, но подсказывать не буду)?


A>
A>void ReadWrite(IStream *stream)
A>{
A>  stream->ReadWrite(counter);
A>  if(stream->IsReading())
A>  {
A>    checkInvariant();
A>  }
A>}

A>void checkInvariant()
A>{
A>  if(counter < MinCounter || counter > MaxCounter)
A>    throw std::range_error("class RepeatCounter : out of bound");        
A>}
A>

A>

Да. Но только вызов checkInvariant должен не в методе происходить, а делаться deserialization framework ом.

К сожалению, этот метод тоже не универсален.
Вот простейший пример.


class SomeClass
 {
   vector<int> data;
 
   ...

  public: 

   template <class Dev>
   void serialize(Dev &dev) const
    {
     size_t n=data.size();

     dev << n ;

     for(size_t i=0; i<n ;i++) dev << data[i] ;
    }

   template <class Dev>
   void deserialize(Dev &dev)
    {
     size_t n;

     dev >> n ;

     if( n>MaxDataSize )
       throw range_error("...");

     {
      vector<int> temp(n);

      swap(data,temp);    
     } 

     for(size_t i=0; i<n ;i++) dev >> data[i] ;
    }
 };
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[6]: serialize / deserialize
От: Angler Россия  
Дата: 07.12.05 10:00
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Здравствуйте, Angler, Вы писали:


A>>Здравствуйте, Шахтер, Вы писали:


Ш>>>Как здесь обойтись одним общим методом (одно решение я знаю, но подсказывать не буду)?


A>>
A>>void ReadWrite(IStream *stream)
A>>{
A>>  stream->ReadWrite(counter);
A>>  if(stream->IsReading())
A>>  {
A>>    checkInvariant();
A>>  }
A>>}

A>>void checkInvariant()
A>>{
A>>  if(counter < MinCounter || counter > MaxCounter)
A>>    throw std::range_error("class RepeatCounter : out of bound");        
A>>}
A>>

A>>

Ш>Да. Но только вызов checkInvariant должен не в методе происходить, а делаться deserialization framework ом.


Ш>К сожалению, этот метод тоже не универсален.

Ш>Вот простейший пример.


Ш>
Ш>class SomeClass
Ш> {
Ш>   vector<int> data;
 
Ш>   ...

Ш>  public: 

Ш>   template <class Dev>
Ш>   void serialize(Dev &dev) const
Ш>    {
Ш>     size_t n=data.size();

Ш>     dev << n ;

Ш>     for(size_t i=0; i<n ;i++) dev << data[i] ;
Ш>    }

Ш>   template <class Dev>
Ш>   void deserialize(Dev &dev)
Ш>    {
Ш>     size_t n;

Ш>     dev >> n ;

Ш>     if( n>MaxDataSize )
Ш>       throw range_error("...");

Ш>     {
Ш>      vector<int> temp(n);

Ш>      swap(data,temp);    
Ш>     } 

Ш>     for(size_t i=0; i<n ;i++) dev >> data[i] ;
Ш>    }
Ш> };
Ш>



для этого делаем адаптер для вектора, и SomeClass превращается в Composite:


template<typename T>
class PersistentVector : public std::vector<T>
{
public:
  void ReadWrite(IStream *stream)
  {
    ...
  }
};
 

class SomeClass
{
   PersistentVector<int> data;
public:
  void ReadWrite(IStream *stream)
  {
    data.ReadWrite(stream);
  }

};


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


class SomeClass
{
  void ReadWrite(IStream *stream)
  {

    //read-write data
    {
      size_t vectorSize = data.size();
      stream->ReadWrite(vectorSize);
      if(stream->IsReading()(
      {
        if(n > MaxDataSize)
          throw range_error("...");
        data.resize(vectorSize);
      } 
      stream->ReadWrite(vector.begin(), vector.end()); 
    }    

   }

};
Re[7]: serialize / deserialize
От: Шахтер Интернет  
Дата: 07.12.05 13:02
Оценка:
Здравствуйте, Angler, Вы писали:

A>остается подумать, как организовать интерфейсы SomeClass и PersistentVector для удобной проверки любых условий.


Неоправдано сложно. Проще реализовать в SomeClass раздельные методы для сериализации и десериализации.

A>Но я так и не понял, чем просто проверка на тип операции плоха?


Тем что её надо писать в каждом классе тогда. И тем что она динамическая, тогда как что мы делаем известно в compile-time. Если этот вызов вставить в реализацию десеариализации, то написать надо будет один раз, а классу останется просто реализовать метод.

A>
A>class SomeClass
A>{
A>  void ReadWrite(IStream *stream)
A>  {

A>    //read-write data
A>    {
A>      size_t vectorSize = data.size();
A>      stream->ReadWrite(vectorSize);
A>      if(stream->IsReading()(
A>      {
A>        if(n > MaxDataSize)
A>          throw range_error("...");
A>        data.resize(vectorSize);
A>      } 
A>      stream->ReadWrite(vector.begin(), vector.end()); 
A>    }    

A>   }

A>};
A>


Мне категорически не нравятся попытки слить два метода, делающие довольно-таки разную работу.

Если коротко резюмировать:

1) механизм сериализации/десериализации должен быть гибким, т.е.

если класс определяет два метода serialize и deserialize, то использовать
serialize для сериализации, а deserialize для десериализации

если класс определяет только один метод serialize, то использовать его и для
сериализации, и для десериализации

если класс определяет метод check_deserialized, то использовать его для
проверки корректности десериализации

2) Если класс простой, то можно использовать один метод, в сложных случаях,
когда десериализация значительно отличается от сериализации, лучше
использовать раздельные методы.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[8]: serialize / deserialize
От: Angler Россия  
Дата: 07.12.05 13:43
Оценка:
Здравствуйте, Шахтер, Вы писали:


Ш>Если коротко резюмировать:


В принципе я согласен, но хочу добавить, что имея два метода, проще сделать ошибку(например если перепутать порядок или забыть какое-то поле).
Re[9]: serialize / deserialize
От: Шахтер Интернет  
Дата: 08.12.05 07:26
Оценка:
Здравствуйте, Angler, Вы писали:

A>Здравствуйте, Шахтер, Вы писали:



Ш>>Если коротко резюмировать:


A>В принципе я согласен, но хочу добавить, что имея два метода, проще сделать ошибку(например если перепутать порядок или забыть какое-то поле).


Да, это минус.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.