NOTE: Sorry for the long question!
I’m trying to understand some key areas behind object orientation and I couldn’t decide one way or another about my particular question.
Let’s say I have an object full of lovely data. Class bob.
Bob myBob = new Bob("This string is data");
Let’s say I want to save the contents of myBob to an xml file (bob.xml)
Should I have an object act on bob to write the contents out, or should I have myBob do this?
Case 1: Act on object
Writer myWriter = new Writer(myBob, "C:\\bob.xml");
Case 2: Save method
myBob.Save("C:\\bob.xml");
Some people are siding with option one as it means if the code for writing files is changed, it doesn’t need to updated across every Save method; promoting code reuse I suppose. My problem with this is getting all the data out of objects which may have private data with no accessor.
The case for option two is that the method only acts on the data held by the object and that’s the way it should be. No interference from other objects.
Or is the answer to my question one of those “case dependent” issues? If so, how do you know when one method is prefered over the other?
The correct approach, in general, is your Case 1. This maintains a single responsibility for the class (whatever it does) without coupling it to a specific persistence mechanism (a disk).
You’re looking at a specific case of a more generalized problem: Serialization. It’s good and OK for an object to have some means to indicate how it should be serialized– it’s the only entity that knows what’s necessary to deserialize it, after all. But if you make the object save itself to disk, you’ve tightly coupled that object to a specific implementation.
Instead, consider creating an interface that a generalized “writer” can use to “serialize” the object to whatever that writer serializes to. This way, you’ll be able to serialize to disk, to the network, to memory, to whatever you actually need to serialize to. 🙂