Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save and load objects without breaking encapsulation

I want to save and load objects to a database without using a ORM (like Hibernate).

Lets say i have the following class:

public class Person {
    private int age;

    public void birthday(){
        age++;
    }
 }

This class doesn't provide a get-method, so the internal state (age) is encapsulated.

If i want to save the object i need a getter method to do the following:

insert into TABLE_PERSON (id, age) vales (1, person.getAge());

The otherway round i need a setter-method to load the object:

int age = "Select age FROM Person";
person.setAge(age);

But i dont want to break the encapsulation (by implementating additional setter- and getter-methods) just to save and load objects.

Is there any possibility to do this? Maybe some kind of pattern (memento?) or best practise?

Thank you in advance!

like image 264
Aeon Avatar asked Nov 21 '25 00:11

Aeon


1 Answers

You mentioned Memento. There's a variant called Snapshot documented by Grand. Here's the UML class diagram:

Snapshot pattern

Person would be the Originator in the pattern.

You could dump the Memento instance to a binary object in the database.

Note that Memento is an inner class of Originator. The createMemento/setMemento are a kind of single get/set which might be breaking encapsulation if you're a purist. However, the packet of information (the Memento) used on the call is an interface with no methods, so encapsulation of Originator's state is guaranteed. This might even work with an ORM if you map it properly.

Of course, this seems a lot of work just to avoid a get/set. Your Person/age example is not quite realistic (not a great model of a Person). It's quite normal to expose a person's age or date of birth, and exposing that property to persist the object would be OK. Encapsulation doesn't mean don't reveal anything. It means don't expose too much detail.

For example, let's not use age but rather Person.birthday. That could be stored internally as a String in YYYY-MM-DD format or using a Date object. Such detail would not be exposed (it would be encapsulated). This is also done so that you can change it and not affect clients of your class. Anything you hide can be changed without negatively affecting clients.

By exposing a person's birthday, you say "I'm taking the risk that Person will always have a birthday." That part is exposed and thus will be hard to change without breaking clients.

Edit after comments

Public methods (e.g., save and load) in Person can take care of the save/load database operation. They will have access to private fields (age) and can get the job done. You said you're not using an ORM, so then you just do it yourself.

like image 159
Fuhrmanator Avatar answered Nov 23 '25 14:11

Fuhrmanator



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!