From: Scot T Brennecke on
I find it stunning how often you declare something as "unusable" or "worthless" or "needlessly complex", when that very thing you
criticize is something I have been using successfully for years. I think you quite often judge quickly and give up too easily.

Joseph M. Newcomer wrote:
> It wouldn't make sense to serialize a dialog. Nor does it make much sense to have a
> dialog class created by a template. If you need some kind of templating, it most likely
> applies to data *within* the dialog, and therefore you should create a templated class to
> hold your data.
>
> I do not believe you can derive a template class from CObject, because of how the macros
> work. You did not say which version of VS you are using.
>
> Generally, MFC serialization is among the worst possible ways to implement persistent
> memory of information. It is needlessly complex (in spite of the claims otherwise)
> because it is exceptionally fragile under what is known as "schema migration". Change
> anything in the class, such as adding or deleting a member variable, or changing its type,
> and all existing files are rendered unreadable. I would suggest avoiding it entirely. I
> tend to use either simple text files or XML files if I have complex structured data. I
> have studiously avoided using MFC serialization for 15 years (we had implemented the
> equivalent of MFC serialization in 1977 and knew exactly what was wrong with it, and when
> I saw MFC serialization, all I could do was shake my head and say "how could they DO
> something this bad when we knew almost 20 years ago [I looked at this in 1996] that it
> cannot work". Our sollution, by the way, was to have an XML file we wrote out, along with
> the binary. If the binary file had a different version than the program could read, we
> ignored the binary form of the file and read the XML form [yes, I helped invent XML in
> 1977; it looked much better than the current XML, was more powerful, and the second
> generation, done ca. 1980, and known as IDL, was even better. But it was not yet time to
> build steam engines, so our work was ignored and then badly reinvented by the XML
> designers. We documented our work in a 1989 book].
> joe
>
> On Fri, 4 Sep 2009 02:06:01 -0700, Elizabeta <Elizabeta(a)discussions.microsoft.com> wrote:
>
>> Hello
>>
>> How can I serialize Mfc template dialog class , I can't use DECLARE_SERIAL
>> and IMPLEMENT_SERIAL for this . I noticed that IMPLEMENT_SERIAL_T macro
>> exist, but it is not documented and there is no corresponding
>> DECLARE_SERAIL_T.
>>
>> Thanks
> Joseph M. Newcomer [MVP]
> email: newcomer(a)flounder.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
Being used for years is not the same as "being usable". In all cases where I have seen
MFC serialization used, there have either been serious problems or amazing complexity. In
neither case would I have referred to any of the solutions I have seen as the consequence
of a "usable" mechanism.

I know people who say that "synchronous sockets" are "usable". Then you start talking to
them and discover that they have huge problems with them, that they wouldn't have with
asynchronous sockets. Serialization works well in trivial cases, and small incremental
chnages are easy, but complex structures are hard to maintain long-term, particularly when
there is massive schema evolution (or, read, "We changed the fundamental data
structures"). This is why, even before XML was a tool to use, I was using XML-like data
structures (as far back as Win16 in 1992). Or I would use tagged-binary representations,
which are XML-like. Cleaner growth mechanisms.

I look at something, look at its implications, look at how hard it is to do something with
it, and either use it or dimiss it. Then, for the things I dismiss, I see people
struggling with the same problems I anticipated, because they hadn't. So I try to
discourage others from going down the same garden path as those who have already
encountered problems. Note that sometimes I went down the same garden path, and got hit
by the same problems, but backtracked and adopted a cleaner solution. I do not offer
these opinions off-the-cuff, but based on experience, both mine and that of my clients.
joe

On Mon, 07 Sep 2009 04:02:47 -0500, Scot T Brennecke <ScotB(a)Spamhater.MVPs.org> wrote:

>I find it stunning how often you declare something as "unusable" or "worthless" or "needlessly complex", when that very thing you
>criticize is something I have been using successfully for years. I think you quite often judge quickly and give up too easily.
>
>Joseph M. Newcomer wrote:
>> It wouldn't make sense to serialize a dialog. Nor does it make much sense to have a
>> dialog class created by a template. If you need some kind of templating, it most likely
>> applies to data *within* the dialog, and therefore you should create a templated class to
>> hold your data.
>>
>> I do not believe you can derive a template class from CObject, because of how the macros
>> work. You did not say which version of VS you are using.
>>
>> Generally, MFC serialization is among the worst possible ways to implement persistent
>> memory of information. It is needlessly complex (in spite of the claims otherwise)
>> because it is exceptionally fragile under what is known as "schema migration". Change
>> anything in the class, such as adding or deleting a member variable, or changing its type,
>> and all existing files are rendered unreadable. I would suggest avoiding it entirely. I
>> tend to use either simple text files or XML files if I have complex structured data. I
>> have studiously avoided using MFC serialization for 15 years (we had implemented the
>> equivalent of MFC serialization in 1977 and knew exactly what was wrong with it, and when
>> I saw MFC serialization, all I could do was shake my head and say "how could they DO
>> something this bad when we knew almost 20 years ago [I looked at this in 1996] that it
>> cannot work". Our sollution, by the way, was to have an XML file we wrote out, along with
>> the binary. If the binary file had a different version than the program could read, we
>> ignored the binary form of the file and read the XML form [yes, I helped invent XML in
>> 1977; it looked much better than the current XML, was more powerful, and the second
>> generation, done ca. 1980, and known as IDL, was even better. But it was not yet time to
>> build steam engines, so our work was ignored and then badly reinvented by the XML
>> designers. We documented our work in a 1989 book].
>> joe
>>
>> On Fri, 4 Sep 2009 02:06:01 -0700, Elizabeta <Elizabeta(a)discussions.microsoft.com> wrote:
>>
>>> Hello
>>>
>>> How can I serialize Mfc template dialog class , I can't use DECLARE_SERIAL
>>> and IMPLEMENT_SERIAL for this . I noticed that IMPLEMENT_SERIAL_T macro
>>> exist, but it is not documented and there is no corresponding
>>> DECLARE_SERAIL_T.
>>>
>>> Thanks
>> Joseph M. Newcomer [MVP]
>> email: newcomer(a)flounder.com
>> Web: http://www.flounder.com
>> MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Goran on
On Sep 7, 5:48 pm, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
> Serialization works well in trivial cases, and small incremental
> chnages are easy, but complex structures are hard to maintain long-term, particularly when
> there is massive schema evolution (or, read, "We changed the fundamental data
> structures").

I beg to disagree about complex structures being hard to maintain long
term. I think I've shown how that's done more or less easily.

Massive schema change is more difficult, but it goes for rewrites
only, so it's hopefully rare. Also, I'd wager that more often you will
find yourself wanting to replace a particular __piece__ of the whole
structure with another.

Anyhow, you still can migrate like so:

1. in "global" version BOOM-1 you have your usual serialization
2. in version BOOM, you drop all of what you want replaced --except
class definitions and Serialize functions--
3. upon loading, if "global" version is BOOM-1 and less, load obsolete
data, then "convert" to new data model
4. continue saving new model.
....
X. you decide that you don't need to support versions BOOM-1 and less
and drop corresponding classes from the code.

Goran.
From: Joseph M. Newcomer on
Now do this with data structures that are very rich and which have been modified for ten
years. It is rare that you are lucky enough that your code is readable after ten years of
evolution. I find a lot of "It must be usable because..." and the story usually ends up
being "...and therefore I am the exception that proves it is usable". Yet I more often
find, with a lot of the things I call "unusable", that if I advise a client *against*
using whatever the feature is, and they ignore me and use it anyway, that about three
years down the line I am able to say "...but didn't I warn you this would happen?"
Sometimes I'm lucky and get paid to rewrite the code. Sometimes I'm very unlucky, and get
paid to rewrite the code. Mostly, they grimace and say "We should have listened, but now
we're stuck with this..." And sometimes they scrap the whole thing.

It is far easier to manage schema evolution with XML. That's why it is all I have used
for the last ten years, and before that, I used text files that looked a lot like a very
limited subset of XML.
joe
On Tue, 8 Sep 2009 00:15:39 -0700 (PDT), Goran <goran.pusic(a)gmail.com> wrote:

>On Sep 7, 5:48�pm, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
>> Serialization works well in trivial cases, and small incremental
>> chnages are easy, but complex structures are hard to maintain long-term, particularly when
>> there is massive schema evolution (or, read, "We changed the fundamental data
>> structures").
>
>I beg to disagree about complex structures being hard to maintain long
>term. I think I've shown how that's done more or less easily.
>
>Massive schema change is more difficult, but it goes for rewrites
>only, so it's hopefully rare. Also, I'd wager that more often you will
>find yourself wanting to replace a particular __piece__ of the whole
>structure with another.
>
>Anyhow, you still can migrate like so:
>
>1. in "global" version BOOM-1 you have your usual serialization
>2. in version BOOM, you drop all of what you want replaced --except
>class definitions and Serialize functions--
>3. upon loading, if "global" version is BOOM-1 and less, load obsolete
>data, then "convert" to new data model
>4. continue saving new model.
>...
>X. you decide that you don't need to support versions BOOM-1 and less
>and drop corresponding classes from the code.
>
>Goran.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Goran on
On Sep 8, 3:31 pm, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
> Now do this with data structures that are very rich and which have been modified for ten
> years.

Hi!

I tried imagining how some soft of "tagged" data (I am guessing,
similar to XML, you are trying to push for some sort of id<->value
mapping for any particular n-tuple of data (a struct or a class) can
help significantly better than e.g. serialization and I can't see it.

Here's what I imagine (I am focusing on reading, because writing is
easier anyhow; I am also focusing on one n-tuple because everything
else, e.g. containers or other sorts of composition seem to be a
matter of putting bricks together):

If you have random access e.g. DOM of XML (I think, if you have
sequential access a là SAX of XML, things only get closer to
serialization), reading consists of getting out a value based on the
desired attribute, e.g.

member1 = value(attr1); member2 = value(attr2); ...

What this gives over serialization is random read order. That gives
possibility to skip "unknown" data items without using my "unused
idiom". In the light of small schema changes (which IMO in
overwhelming majority are additions to the n-tuple), that doesn't buy
much, either. One can alleviate missing attributes (get_value(member,
attr) and nothing is done if there's no attribute), avoiding if
(schema>=x) {} nesting. But that comes at a price of having bigger
"infrastructure"^^^.

Now... As far for "major" overhauls, I fail to see how "tagged data"
can avoid my step 3 from up here ("upon loading, if "global" version
is BOOM-1 and less, load obsolete data, then "convert" to new data
model"). It does avoid step 2, and there is hidden only major
conceptual advantage I can see: stored data is clearly disconnected
from data model present in the code. But again, that comes at a price
of having bigger "infrastructure". It should be noted that even with
serialization, he who is smart does not tie serialized "data model"
more than necessary with the rest of the code (incidentally, for the
most part that isn't my case :-( ).

^^^ infrastructure that which one doesn't do at all with
serialization - big amount of stuff is already there, e.g. container
serialization, schema support, very easy low-level primitives a là >>
and << etc. What serialization also offers is easy serialization of
complicated data graphs (doing ar <</>> p for one value of p in
multiple places results in correct p instance being read back). That's
something many are not aware of and comes in quite handy. Doable with
any other approach, sure, but again, a thing to write (and test).

?

Goran.