• Post Reply Bookmark Topic Watch Topic
  • New Topic

Adventures in Persistence  RSS feed

 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please forgive the length of this, but I've been working on it all week and have tried to pare it down to the smallest three examples I could.

I am trying to devise a clean and easy-to-use scheme to record selected persistent fields of my object using XMLEncoder. I am reluctant to use XMLEncoder on the object class itself, as that imposes requirements and restrictions I think would be problematic in my application (avoiding getters and setters in the JavaBeans format for properties I do not wish to save, while either always supplying them or making those fields public for the properties I do wish to save, basically).

I have come up with three techniques, no one of which is the clear winner.

First, was the "proxy" technique: I adapted Joshua Bloch's Serialization Proxy (Item 78, "Effective Java," 2d ed.). I adapted it because his technique relies on the Serialization interface, not XMLEncoder. Bloch's method works perfectly (well, that's why he's Bloch, and I'm not, eh?). But, it requires that the proxy class have a line for each and every field to be made persistent, copying the "real" object's fields to matching files in the proxy object. That's kind of tedious and risks leaving fields out when you add more of them to the "real" object during development.

Second, was the "memory" technique: I modified my first technique so that, instead of a proxy class that copies the fields, I used an instance of the proxy class as a field in the "real" object, and simply dereference that instance whenever I need to refer to one of its fields. This also works and has the advantage that I don't need to copy the "real" fields to the proxy fields prior to encoding, but has the disadvantage that every single use of one of the proxy's fields must be made indirectly, through the reference to the proxy. (Kind of looks like the bad old days when every member of a class had a name of the form m_<name>.)

Third, was the "conscience" technique: I put all the fields to be persistent into a class of their own as public fields, and extended my "real" class from that. Using reflection, I copy all the fields in the parent class to an instance of that class, then encode that instance. This has the advantage that all fields have conventional Java names (no prefix-style instance references as in the second technique), and no field has to be declared twice (that is, once in the real class, again in the proxy class). But, it requires that my "real" class be subclassed from the class containing my persistent state (fine, until I need to subclass something else).

Here's a class with a main routine with examples of all three techniques:



Here's the "real" class and its proxy for the first technique:



Here's the "real" class and its proxy for the second technique:



And here's the "real" class and its parent for the third technique (note that the parent includes the slightly demonic reflection code; in practice, this would be in a class of its own):





I can't seem to decide which of these is best, or, indeed, if I have overlooked something altogether superior.

Any comments?

 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:Any comments?

Yes: your lines are far too long.
I've broken them up as best I can.

I'm afraid I'm no expert on XMLEncoder (and I'll have to read Item 78 of EJ again), but if I see anything (else) that leaps out at me, I'll post further.

Winston
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Stevens Miller wrote:Any comments?

Yes: your lines are far too long.
I've broken them up as best I can.

Dang it, Winston! I paid a lot of money for this widescreen monitor. What good is it to me if you keep cramming everything into the left-hand side?


I'm afraid I'm no expert on XMLEncoder (and I'll have to read Item 78 of EJ again), but if I see anything (else) that leaps out at me, I'll post further.

Please do. One idea I'm mulling over is whether or not the "real" class could be an inner class of the "memory" class. Gonna work on that one next...
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:Dang it, Winston! I paid a lot of money for this widescreen monitor. What good is it to me if you keep cramming everything into the left-hand side?

Sorry old chap, dem's de rules. TBH, I wish we could get it fixed so that code windows create a horizontal scroll bar that works properly. You also have to forgive old farts like me who have trouble reading web print anyway; I almost always have to hit Ctrl-+ a few times before it's big enough.

I am trying to devise a clean and easy-to-use scheme to record selected persistent fields of my object...

One thing I'm having a bit of trouble working out is why reflection would help in this case, but I suspect I'm just being thick:

Unless "selected" is by some characteristic (eg public), surely you need some way of "telling" the persisting class which fields you actually want to save. In that case, the proxy pattern would seem to be ideal, since you simply define them in your proxy class. Obviously this means that you have to keep your proxy up to date if you ever add any new ones, but TBH:
(a) If you plan on doing that a lot, any serialization system is likely to struggle.
(b) Surely you'd still need to update something to say that the new field is "persistent".

Like I say, this isn't really my area of expertise, but I'm not quite sure what these other patterns give you over the proxy one (which also has the advantage of being a published, tested technique).

Winston
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:Unless "selected" is by some characteristic (eg public), surely you need some way of "telling" the persisting class which fields you actually want to save.

Ah. One thought occurred to me: Could you use an annotation? (eg, @Persist). That might give you the best of both worlds (I say 'might' because I've never tried it) - a generic way of indicating that a field needs to be saved that can be handled reflectively.

Winston
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:One thing I'm having a bit of trouble working out is why reflection would help in this case...


It gets me out of having to type a lot of lines of the form proxyObject.property1 = sourceObject.property1;. There's nothing inherently wrong with that method, and it certainly is simple. But, it feels like a DRY violation, a bit, or else like maintaining parallel data structures. By using reflection (on an instance of the parent class), I can limit what gets copied to exactly those public fields that are present in the parent class, and I never have to type another line like the foregoing, no matter how many fields I add to my parent class down the road.

Unless "selected" is by some characteristic (eg public), surely you need some way of "telling" the persisting class which fields you actually want to save. In that case, the proxy pattern would seem to be ideal, since you simply define them in your proxy class. Obviously this means that you have to keep your proxy up to date if you ever add any new ones...


And that's exactly what I don't want to have to do (you also have to do it again in a constructor that takes an instance of your proxy class as an argument, so there are actually two structures that must be maintained in parallel with each other, as well as with your list of selected properties).

TBH:
(a) If you plan on doing that a lot, any serialization system is likely to struggle.

You're referring to what some folks call "versionitis" I think. Yeah, I don't see any way out of that problem. That's not what I'm focused on here, though.

(b) Surely you'd still need to update something to say that the new field is "persistent".

Well, that's the question: what's the easiest way to designate something as persistent, and then make it be, in fact, persistent? (Add the criterion that I want to use XML or, at least, something human-readable.)


Like I say, this isn't really my area of expertise, but I'm not quite sure what these other patterns give you over the proxy one (which also has the advantage of being a published, tested technique).


My first one is, pretty much, Bloch's proxy pattern, but adapted for use with XMLEncoder (which doesn't allow the trick he plays with writeReplace()). My second is my adapted proxy, but with my own trick added to avoid the parallel assignment lists Bloch's method requires. (He clearly doesn't seem to mind that kind of thing. Item 11's "copy constructor" tacitly embraces the same thing.) My third solves both problems by using a superclass to be, implicitly, the designator of what is persistent (that is, all its public fields are inherently so designated), without requiring parallel assignment lists anywhere, nor quirky "prefixing" with an instance reference. But it does require that it be subclassed.

However, I think I'm on to an even better variation. If the fields to be made persistent are kept in an enclosing outer class, and all transient fields are kept in an inner class, references to the inner class can do the runtime work, while applying XMLEncoder to the outer class saves all, and only, its public fields:



The object creation relies on a static factory now, not a constructor, and it returns a reference to the inner class (so the declaration must reflect that fact; an interface could hide that). The inner class has direct access to its enclosing class's fields, so no prefixes nor copying are necessary. When saved, XMLEncoder only finds the public fields of the outer class, so no reflection or other pre-copy work is necessary:



Seems to work quite well:

 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Winston Gutkowski wrote:Unless "selected" is by some characteristic (eg public), surely you need some way of "telling" the persisting class which fields you actually want to save.

Ah. One thought occurred to me: Could you use an annotation? (eg, @Persist). That might give you the best of both worlds (I say 'might' because I've never tried it) - a generic way of indicating that a field needs to be saved that can be handled reflectively.


That seems like a very appealing idea (though I know little about annotations). The problem that doesn't solve, however, is that of getters/setters that match the JavaBeans spec. XMLEncoder will encode those (even if they don't actually get/set a field in your object). If "transient" could be applied to getters/setters, that would solve my problem, but it can't. One can "hide" getters/setters by departing from the JavaBeans spec (for example, "getReceiver" can become "receiverGet"), but that feels like I'm just fighting with the language at that point (not to mention departing from a getter/setter convention that is widely used regardless of whether or not one is writing a bean).
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:That seems like a very appealing idea (though I know little about annotations). The problem that doesn't solve, however, is that of getters/setters that match the JavaBeans spec. XMLEncoder will encode those (even if they don't actually get/set a field in your object).

OK, I've had a night to sleep on this and, as I see it, your problem is this:
1. You want a simple, generic (two adjectives that rarely correlate in programming ) mechanism for persisting a Java object to XML.
2. XMLEncoder is really simple to use, but essentially requires the persisted object to be a bean.
3. You don't want to implement the bean specification just to make an object "persistable" (at least, certainly not as part of its public API).

So, as I see it, you're looking for some way to "beanify" a non-bean object (or "selected members" of that object) so that you can use XMLEncoder to persist it. And that strikes me as deciding how you're going to tackle the problem before you've actually determined what it is (or what alternatives are available).

The first thing that occurred to me is that this kind of problem (the need to persist non-bean objects) must have already come up. Indeed, JPA arose for precisely this purpose; it's just not specifically geared for XML output.

The second thing I thought was: when it comes to something as fundamental (and fiddly, and potentially "crackable") as serialization, I certainly wouldn't want to "roll my own".

A bit of Googling found me this Stackoveflow thread, which links to XStream, which looks like it might well do what you want. Alternatively, the tutorials seem to suggest that you can customise XMLEncoder to do this kind of thing. And yet another possibility is JAXB.

Like I say: it's not something I've ever tried, and I suspect you'll need to read a fair bit to work out which solution is closest to your needs; but my basic advice would be this:
Unless you're willing to spend the time to become a real expert on this stuff, don't roll your own, because there are just too many things that (as a non-expert) you could get wrong.

And getting serialization wrong is potentially disastrous.

HIH

Winston
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:Dang it, Winston! I paid a lot of money for this widescreen monitor. What good is it to me if you keep cramming everything into the left-hand side?
So you can have pretty pictures, movies, e-mail etc. on the right half? Or even the API documentation?


Or so you can turn it and read 387458734685376 lines simultaneously?
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Stevens Miller wrote:Dang it, Winston! I paid a lot of money for this widescreen monitor. What good is it to me if you keep cramming everything into the left-hand side?
So you can have pretty pictures, movies, e-mail etc. on the right half? Or even the API documentation?

That stuff all goes on the right-hand monitor, not the right-hand half of the left-hand monitor.

Or so you can turn it and read 387458734685376 lines simultaneously?



I. Never. Thought.

Of that...

 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:That stuff all goes on the right-hand monitor, not the right-hand half of the left-hand monitor.

Bloody lawyers. Get all their toys by charging us poor jobbing programmers 200 bucks an hour.....

I'm sure you've heard it before: What's the difference between a lawyer and a catfish?

One's a scum-sucking bottom-feeder, and the other one's a fish.

Winston
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No offence meant of course...

Winston
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:OK, I've had a night to sleep on this and, as I see it, your problem is this:
1. You want a simple, generic (two adjectives that rarely correlate in programming ) mechanism for persisting a Java object to XML.
2. XMLEncoder is really simple to use, but essentially requires the persisted object to be a bean.
3. You don't want to implement the bean specification just to make an object "persistable" (at least, certainly not as part of its public API).

Nicely derived. (I think the school-room recursive solution to the Towers of Hanoi has left a lot of us on a lifetime quest for simple, generic ways of doing things, making us akin to the children of Diogenes).

The first thing that occurred to me is that this kind of problem (the need to persist non-bean objects) must have already come up. Indeed, JPA arose for precisely this purpose; it's just not specifically geared for XML output.

I looked at that. Although comforting claims are made about it being applicable to SE, its origins appear to be grounded in EE and EJB. Also, you need a database. Already, I am feeling the crushing weight of monumental infrastructure, when I just want to write a file.

The second thing I thought was: when it comes to something as fundamental (and fiddly, and potentially "crackable") as serialization, I certainly wouldn't want to "roll my own".

Heh. When you have a hammer, all problems look like nails. I had been using XMLEncoder quite successfully for something else, and the problem I'm looking at now started out in much the same form. Alas, it does look different now.

A bit of Googling found me this Stackoveflow thread

I found that one too. Why are so many of the best SO threads closed by their members? They seem awfully eager to do that.

which links to XStream, which looks like it might well do what you want.

It might, but I am allergic to most third-party libraries. They tend to be one or more of: buggy; costly; complicated; limited; closed source; mortal (that is, they can go out of business).

Alternatively, the tutorials seem to suggest that you can customise XMLEncoder to do this kind of thing.

Yeah, that would be a leap into the maelstrom. I am willing to play around with my own objects' structure to make them serializable by a standard library class, but I'm not going to risk modifying that class myself.

And yet another possibility is JAXB.

Jesper pointed me to that a short while ago. Yeesh! Too much learning curve for me to handle.

Like I say: it's not something I've ever tried, and I suspect you'll need to read a fair bit to work out which solution is closest to your needs; but my basic advice would be this:
Unless you're willing to spend the time to become a real expert on this stuff, don't roll your own, because there are just too many things that (as a non-expert) you could get wrong.

Becoming an expert (or, let me say more humbly, developing some needed expertise) is what I am trying to do. Sometimes, that does result in stepping back, evaluating in the light of new knowledge, and saying, "This ain't gonna work."

One glaring flaw that all four of my schemes have, when compared to Bloch's Item 78, is that they only support selective serialization for the class where serialization begins. That is, one typically doesn't just serialize an instance's fields by recording their values; one traverses the graph created by fields which are themselves references to other instances. Bloch's method can be applied to any class you create, such that, if it is serialized pursuant to a graph-traversal that began with an instance of another object (from, potentially, another class), that class will still be serialized selectively. My schemes only let me pick and choose the fields to be serialized within the instance where the traversal begins. Not much good to me after that, as every other instance in the graph will be serialized according to the XMLEncoder rules I started with. That tends to leave me thinking that applying transient to public fields and mangling the names of getters/setters may, in the end, be the easiest approach of general application. It's certainly within the spec (the name-mangling is even authorized by the JavaBean spec, I believe), and doesn't require me to roll anything new. It's just not quite what I was hoping for. (Kind of like Diogenes )
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Stevens Miller wrote:That stuff all goes on the right-hand monitor, not the right-hand half of the left-hand monitor.

Bloody lawyers. Get all their toys by charging us poor jobbing programmers 200 bucks an hour.....

I'm sure you've heard it before: What's the difference between a lawyer and a catfish?

One's a scum-sucking bottom-feeder, and the other one's a fish.

Winston


A lawyer joke. How very droll. (And one I've never heard before, imagine that. )

If you can find a lawyer worth his wig for US$200/hr, Winston, please let me know. I can use one.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:No offence meant of course...

Of course not. (And any attorney who can't laugh at a lawyer-joke should find another hobby.)

My personal favorite is from an actual, documented transcript of a real court proceeding. Goes like this:

 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey! I just noticed I got a third cow! Who gave me a third cow? (And thanks!)
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:
And yet another possibility is JAXB.

Jesper pointed me to that a short while ago. Yeesh! Too much learning curve for me to handle...

I hate to say Stevens (or is it Miller? (Japanese style)), but most of what I hear from your last post are the things that you don't want to do to solve your problem - you don't trust 3rd party software; you don't fancy customizing XMLEncoder; and you really don't like the learning curve of JAXB - and it's not a great platform to start from.

As Albert said (paraphrased): Everything should be as simple as possible, but no simpler; and I'm afraid that the apparent simplicity of the Serializable interface may have led you to believe that persistence is simple.

Well, let me tell you: after a lifetime in programming and database design and administration - it AIN'T.
Yes, the basic business of saving an object is reasonably straightforward (but probably not as simple as you think); but retrieving and re-instantiating are hellishly more complex - especially when this is usually the place when you also have to guard against potential "cracking" attacks.

I fear I've come to the limits of what I can advise; but I wish you luck, and I applaud your enterprise.

And if you do come up with a "better mousetrap", do tell.

Winston
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:Hey! I just noticed I got a third cow! Who gave me a third cow? (And thanks!)

Campbell. Send him a candy-cane by purple-post.

I notice he hasn't bothered to give me one though (probably because I still detest Scanners).

A parting shot before I get back to the Wimbledon final:
What the difference between a dead dog in the road, and a dead lawyer in the road?

Skidmarks in front of the dog.

Winston
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Stevens Miller wrote:
And yet another possibility is JAXB.

Jesper pointed me to that a short while ago. Yeesh! Too much learning curve for me to handle...

I hate to say Stevens (or is it Miller? (Japanese style))


My first name is "Stevens," and my last name is "Miller." Everyone finds that confusing (except me). "Stevens" was my father's middle name, and the last name of Mary Stevens, whom I believe was his grandmother. So, it has literally worked its way up from being a last name, to a middle name, to a first name. (Funny you should mention Japanese style. I am a military brat and, as one consequence of that, I was born in Japan; no connection to my funny first name, though.)

but most of what I hear from your last post are the things that you don't want to do to solve your problem - you don't trust 3rd party software; you don't fancy customizing XMLEncoder; and you really don't like the learning curve of JAXB - and it's not a great platform to start from.


Well, let me say in my own defense that I am not rejecting any option without giving it some consideration. I looked at all of those things and, for the moment, have decided to pursue what I can accomplish with unmodified XMLEncoder and my own code.

Well, let me tell you: after a lifetime in programming and database design and administration - it AIN'T [simple]


I'm convinced of that. After a lifetime in programming myself, I do still find that relying on my own code works better for me than trying to learn a lot of libraries. Those that are mature must be approached with respect. That means (despite what their sales forces might say), expecting them to take more than a few minutes to master. Unfortunately, my experience has been than most tend not to solve my problems any more easily than if I had simply hunkered down and written something suited to my needs on my own. One reason I do that is that I am flying solo here. In a larger setting, there might be a programmer working with me whose job was to be the XStream guru. Another might be the JPA DBA, and so on. Here, it is just me. I write everything. That means I must be able to maintain everything. Years of experience have forced me to admit that, if I spend a week developing the mastery of some library or product necessary to employ it properly, I will almost certainly forget what I learned by the time it is necessary to revisit it in order to cope with a bug and enhance a routine. That means spending a week again to learn what I forgot. OTOH, what I write myself tends to be limited exclusively to what I need to solve my problem, and it tends to stick with me over the long term. (More precisely, when I have to go back to that code, my comments and conventions reacquaint me with what I have forgotten faster than anything else would do it.) In cases where I am worried that I will not remember what I did, I write a short "white paper" on it, and save that to my "HowTo" directory (I have about 300 of those, at this point; maybe I should write a book...).

Yes, the basic business of saving an object is reasonably straightforward (but probably not as simple as you think); but retrieving and re-instantiating are hellishly more complex - especially when this is usually the place when you also have to guard against potential "cracking" attacks.
I fear I've come to the limits of what I can advise; but I wish you luck, and I applaud your enterprise.
And if you do come up with a "better mousetrap", do tell.


As always, your help is much appreciated. My mousetraps work pretty well, but they tend to be limited in application to mice of very specific varieties. They may not be better than other traps for other mice, but they are often the best for me and my own vermin.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Stevens Miller wrote:Hey! I just noticed I got a third cow! Who gave me a third cow? (And thanks!)

Campbell. Send him a candy-cane by purple-post.


Not for anything I posted in this thread, though.

I notice he hasn't bothered to give me one though (probably because I still detest Scanners).


Heh. This whole excursion into persistence came about after I had first tried using Scanners. If it gives you any comfort, all I can say about them now is, "meh."

A parting shot before I get back to the Wimbledon final:


Does that mean that endless soccer football tournament is finally over?

What the difference between a dead dog in the road, and a dead lawyer in the road?

Skidmarks in front of the dog.


Oh, please. You are more expert at Java than I am, but, if you are going to cross swords with me over lawyer-jokes, you are going to have to do better than that:

 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:
Yes, the basic business of saving an object is reasonably straightforward (but probably not as simple as you think); but retrieving and re-instantiating are hellishly more complex - especially when this is usually the place when you also have to guard against potential "cracking" attacks.
I fear I've come to the limits of what I can advise; but I wish you luck, and I applaud your enterprise.
And if you do come up with a "better mousetrap", do tell.


As always, your help is much appreciated. My mousetraps work pretty well, but they tend to be limited in application to mice of very specific varieties. They may not be better than other traps for other mice, but they are often the best for me and my own vermin.


A little story which may be related...

About 20 years ago, I went on a client site -- and this client wrote their own database. Believe it or not, it had many of the features of databases, and it was twice as fast as the best SQL database back then. This customer actually bragged about it... and how vendors products were generally too generic, and hence, were never as good in performance. My response was that a database was not their core business. They will never keep it up to date -- in regards to new techniques, new hardware, new features, etc. They never have to keep it competitive, or even improve it for improvement sake.

Unfortunately, the company that I worked for depended on a real database, so couldn't sell into this client -- not that it mattered, as they were considering writing there own service anyway.

Anyway, 15 years later. I was working for a different company. And I went to the same client, but met completely different people, and talked about completely different product. This time the client kept complaining about how they were stuck using a crappy in-house database, that had only half the performance as a off-the-shelf database, didn't support many features (including HA), but they were stuck because too many applications depended on it.

Henry
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:After a lifetime in programming myself, I do still find that relying on my own code works better for me than trying to learn a lot of libraries. Those that are mature must be approached with respect. That means (despite what their sales forces might say), expecting them to take more than a few minutes to master. Unfortunately, my experience has been than most tend not to solve my problems any more easily than if I had simply hunkered down and written something suited to my needs on my own.

Which is why I suggested XStream, which (AFAICG) is an open-source solution.

One reason I do that is that I am flying solo here. In a larger setting, there might be a programmer working with me whose job was to be the XStream guru. Another might be the JPA DBA, and so on...

I do understand, because I've been there myself. Unfortunately, it tends to produce the "bulldog breed" of programmer; something that I've had to fight in recent years. Symptoms are:
(a) If it doesn't work, and you didn't write it, rewrite it.
(b) If something is going to take more than a week to learn, ignore it.
and, while the job situation itself may be great, it's a bit of an ivory tower. Regular professionals don't usually have the luxury of deciding how they work and what paradigms they choose to use.

Since I've worked in both environments, the one thing I'll say for the "corporate" system is that you live in an environment where people are allowed to tell you that your code (or approach) is crap - or indeed, wrong - and because it can happen every day, it breeds humility.

If you don't have that, you can get into an insular, "I know best" mentality, since you're the only arbiter of your code. But what if you fall under a bus? Is your company (or your code) ready for someone else to take over?

That's the mark of a true professional.

Winston

PS: And on a similar subject, you might be interested in this article.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Stevens Miller wrote:After a lifetime in programming myself, I do still find that relying on my own code works better for me than trying to learn a lot of libraries. Those that are mature must be approached with respect. That means (despite what their sales forces might say), expecting them to take more than a few minutes to master. Unfortunately, my experience has been than most tend not to solve my problems any more easily than if I had simply hunkered down and written something suited to my needs on my own.

Which is why I suggested XStream, which (AFAICG) is an open-source solution.

Let me clarify: I am not so brazen as to say every library out there isn't worth learning. A lot of them are. Rather, I am humble enough to admit that learning a library well enough to use it properly is something that takes time to do. My complaint with that is not that the library isn't worth the time, but that one typically must master aspects of the library that are not relevant to my needs. With that in mind, the question is not, "Can I write better code than is in this library?" The question becomes, "What is the best use of my time, taking design, creation, and long-term maintenance all into account?"

One reason I do that is that I am flying solo here. In a larger setting, there might be a programmer working with me whose job was to be the XStream guru. Another might be the JPA DBA, and so on...

Since I've worked in both environments, the one thing I'll say for the "corporate" system is that you live in an environment where people are allowed to tell you that your code (or approach) is crap - or indeed, wrong - and because it can happen every day, it breeds humility.


Well, I'll agree that it can breed humility. When I worked at Bell Communications Laboratories, my co-workers were true experts. If one of them told me my code was crap, it probably was (not always, but probably). I learned to take them very seriously and to be grateful for the input.

But, I also spent many years working for banks and brokerages, writing in an environment where the only master was the deadline (and the deadline was always Right Now). Whenever I put a half-day into trying to figure out a reliable solution to a problem, one of my co-workers (who, most likely, had just been told his bonus was forfeit if we didn't deliver the app that afternoon) would inevitably say something like, "Why are you wasting your time with that??? Just write it yourself!!!" (Add to that the fact that most programmers who do not work for actual software or research houses have been, in my experience, less than first-rate, and you can see how I found this other than humbling.)

If you don't have that, you can get into an insular, "I know best" mentality, since you're the only arbiter of your code. But what if you fall under a bus? Is your company (or your code) ready for someone else to take over?


Good question. I work alone, in the sense that I write all of our code here. But, I do have to answer to a supreme authority for what I do: my wife. She's in this with me, and has written a lot of code. She writes no code now, but we have some, uh, "spirited" design discussions. When we embarked on the current project, we had a several-days conversation about possible business models. Would we have periodic reviews? Would there be a written spec? Did we want to release a simple version as freeware? And so on. What we adopted is something we call the "Crazed Coder Model (Modified)." It's based on the observation we have both made, many times, that a lot of successful software ventures seem to come down to the work of one programmer who, wisely or not, was allowed to follow some insane idea to its full potential. For a company of even a few people, that's nuts since, as you point out, the Crazed Coder might die (or quit, or be committed to a mental health institution, or something of that sort). But, in those cases where the Crazed Coder is allowed to run unfettered, and where the Crazed Coder does not die, quit, or become the subject of judicial findings that he is a danger to himself and others, amazing things have been known to happen. Not always, but they have been. (The "modified" part is that we do follow some sensible business practices, including actually backing up my code, having some design discussions, and setting soft deadlines we use to make sure I'm not goofing off or chasing some pointless side-issue.)

As a pure solo, it works. Would I suggest it to someone working on a team? Probably not, but I've worked in teams where my mates were competent, and I've worked in teams where my mates were simply loud. How well I receive criticism about my code depends a lot on whether it is competent, or simply loud.

PS: And on a similar subject, you might be interested in this article.


Hmmm... Interesting. I agree with most of his observations, but few of his conclusions. It is silly to reinvent wheels, even sillier to make your own wheels when better wheels can be had than you can make, and at a fair price. That's a far cry from admitting a bad job should be done over. He seems to be arguing that, if the ship is sinking, plugging the holes makes sense, but abandoning the ship is always the wrong move. Nah. Sometimes the ship is going to sink, no matter what you do. I note that programmers do jump to the conclusion that something must be scrapped and redone a lot more often than they should, and I think Spolsky's notions as to why the are like that are probably correct. But to leap the other way and say that starting from scratch (with new languages, new libraries, new techniques, all available) is always wrong is too much. Moreover, his examples of why that's a bad idea seem to be based mostly on marketing hype, not behind-the-scenes knowledge of what actually went down. (Whatever you may think of lawyers, Winston, you may safely assume my regard for software marketeers is markedly lower.)

Anyway, I assure you, I am much too old to think no one has ever written a line of code that I can use instead of writing that line (or two) myself. Indeed, every single time I think, "I need a routine to do X," first thing I do is search the SE library for such a thing. If I find it, I use it. If I don't, however, I look a little further, but usually (not always, but usually) draw the line there and see what I can write on my own for my specific problem.

That may be the kind of thing only a Crazed Coder would do, but I'm all I've got.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:Oh, please. You are more expert at Java than I am, but, if you are going to cross swords with me over lawyer-jokes, you are going to have to do better than that...

Nice one. Not really a stand-up joke though (I've been an MC a few million times, and you need a few good one-liners to break the flow; and lawyer jokes - for some unknown reason - always seem to work).

Winston
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think all humor depends upon someone getting the dirty end of a stick. To be able to avoid guilt when we laugh, we have to be laughing at someone whom we think deserves it (or, at least, that no one will say we were evil for laughing at). Lawyers (along with politicians) are in positions of power over us and, in the stereotypical version, live enviable lives. Thus, they are easy targets and provoke little guilt when made the butt of jokes.

That's not enough, of course, to be funny:

Client: How fast was the other car going?
Lawyer: I'm a lawyer so I will say it was going at whatever speed is best for your case.

That's not funny. It's boring. But this is (at least very slightly) funny:

Client: How fast was the other car going?
Lawyer: That depends. How fast do you want it to have been going?

This is due to something a friend of mine, who was one of the original writers for "The Daily Show," taught me: to be funny, you have to think about something to get the joke. (In programming, we might say there needs to be at least one level of indirection.) It's when you realize that the joke is not in the words, but in something implied by the words, that you start to laugh.

I suspect that, in a stand-up context, that requires short, punchy gags that make the connection quick to set up and easy to find, while still requiring the audience to make its own contribution (by thinking about the implication that, when they realize what it is, makes the joke funny).

On a vaguely related note, are you familiar with the paradox of Euathlus and Protagoras? It's not a joke, but it's a great blend of law and logic. Protagoras, a teacher of law, agreed that his student, Euathlus, would not have to pay him until after Euathlus won his first case. Euathlus (who, apparently, became a corporate lawyer and not a litigator) never goes to court, and so he never pays Protagoras. Protagoras sues Euathlus for his tuition money. Who wins? (Separate question: after the verdict, does Protagoras get paid?)
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!