Sign in to follow this  

Protecting data in MVC

This topic is 3459 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm working on a model-view-controller (MVC) design and have a lot of classes. Since the model is the domain-specific representation of the information on which the application operates, there several data objects in my game which are handled by the model. Some of them inherits from other classes. On a simple data model the application uses a persistent storage mechanism (such as a database) to store data. If your data consists of classes, then its not so easy to seperate them from the rest. The model should protect the data. I don't want to create hundreds of getter and setter methods. Whats the best way to protect the data objects in the model? For example if you write a getter method for class 'foobar', all methods can be called "from outside" and the model has no information about this calls. This breaks the encapsulation. I thought about returning deep copies of all big data objects in the model implementing clone() in java.

Share this post


Link to post
Share on other sites
For some reason people believe that if you can access the information that you are breaking Encapsulation. But it really doesn't. What Encapsulation is that the calling classes don't care how the holder class does it.

So you might have a number that is stored in your class and it is stored as an int when you create the class. All the other classes expect this int. Later you need to change it to a number string for some reason. You change the internal representation of the number but none of the calling classes even know about the change.

Getters and Setters are very good at protecting data. You pass all the data through them to verify the data is valid at all times. This will help keep your program from having some unexpected results.

theTroll

Share this post


Link to post
Share on other sites
We're talking about the simplest of tools (hammer, nail, screwdriver), yet there's no mention of the real issues (are we making a house, an airplane or a tomato).

Each approach has benefits and disadvantages. Accessors are perfect for some tasks, even if it takes thousands of them.

Quote:
Whats the best way to protect the data objects in the model?


By making sure integrity of data is preserved.

One way, perfectly valid, is to require user to not corrupt the data. For example, you have a field int x, and documentation says "Must not be set to 0 or 7" - this is how lots of very large and important applications were written.

You've already mentioned various techniques - which one is most suitable for you (we don't know the domain or the problems you're solving or even the reason for choice of MVC)?

There is never best. Everything is a compromise. But you didn't list your requirements or goals, so aside from "choose the best tool for the job", it's hard to give any meaningful advice.

Quote:
I thought about returning deep copies of all big data objects in the model implementing clone() in java.


Clonable and clone() are essentially broken by design.


The purpose of MVC is to completely separate concerns. Java's Swing models are nice example of that. View and model are completely independent from each other. They communicate through listeners, internal state is completely encapsulated.

Share this post


Link to post
Share on other sites
Quote:
Original post by TheTroll
For some reason people believe that if you can access the information that you are breaking Encapsulation. But it really doesn't. What Encapsulation is that the calling classes don't care how the holder class does it.

So you might have a number that is stored in your class and it is stored as an int when you create the class. All the other classes expect this int. Later you need to change it to a number string for some reason. You change the internal representation of the number but none of the calling classes even know about the change.

Getters and Setters are very good at protecting data. You pass all the data through them to verify the data is valid at all times. This will help keep your program from having some unexpected results.


Hi,

thanks for response!

You are right. Getters and setter work well for classes. But I'm talking about the design of the model in an mvc pattern. Encapsulation means that the model must know if the internal data gets modified by the controller.

This is not the case if a method returns an object. For example I have a class PlayerProfile. This class has some getters and setters.

Know I'm calling the model retrieving a profile. The model returns the object. Now I can call the setters of this object and the model doesn't know anything about this call.

This breaks the mvc pattern. I see only two options to ensure that the model has full control about the own data. Writing getters for every class twice, in the data class and the model or returning a deep copy of the object. The caller of this method can do anything they want with returned object, without affecting the internals of the model in any way.

However, setters still remain, since they can't be replaced by cloned objects.

Share this post


Link to post
Share on other sites
Quote:
Original post by Christian555
The model returns the object. Now I can call the setters of this object and the model doesn't know anything about this call.

So? Why is this a problem?

The PlayerProfile is a part of the model.

Quote:
This breaks the mvc pattern.

No it doesn't [smile]

The MVC pattern defines three concepts: The model, the view and the controller.
You seem to think that the MVC pattern demands that those concepts be implemented as a single class each - this is not the case - it is fine, and indeed normal, for the model, view and controller to each be divided amongst many classes.

Share this post


Link to post
Share on other sites
Hi, :)

Quote:
Original post by Antheus
We're talking about the simplest of tools (hammer, nail, screwdriver), yet there's no mention of the real issues (are we making a house, an airplane or a tomato).

Each approach has benefits and disadvantages. Accessors are perfect for some tasks, even if it takes thousands of them.

Quote:
Whats the best way to protect the data objects in the model?


By making sure integrity of data is preserved.

One way, perfectly valid, is to require user to not corrupt the data. For example, you have a field int x, and documentation says "Must not be set to 0 or 7" - this is how lots of very large and important applications were written.


You are right. First of all the integrity of data must be preserved. The application we are talking about is a java network game.

Quote:
Original post by Antheus
There is never best. Everything is a compromise. But you didn't list your requirements or goals, so aside from "choose the best tool for the job", it's hard to give any meaningful advice.

Quote:
I thought about returning deep copies of all big data objects in the model implementing clone() in java.


Clonable and clone() are essentially broken by design.


I know, avoid clone since it is very tricky to implement correctly in all circumstances. I already thought about using copy-constructors. But I think clone can do the job.

Share this post


Link to post
Share on other sites
Quote:
Original post by dmatter
So? Why is this a problem?

The PlayerProfile is a part of the model.


Yes, PlayerProfile is a part of the model. :-)

Quote:
Original post by dmatter
No it doesn't [smile]

The MVC pattern defines three concepts: The model, the view and the controller.
You seem to think that the MVC pattern demands that those concepts be implemented as a single class each - this is not the case - it is fine, and indeed normal, for the model, view and controller to each be divided amongsts many classes.


Hmmm. What happens if a data object changes and the model doesn't know anything about that change. For example a name displayed in the view?

Usually the model notifies each observer by calling the notify() function.

Share this post


Link to post
Share on other sites
Quote:
Original post by Christian555
Quote:
Original post by dmatter
So? Why is this a problem?

The PlayerProfile is a part of the model.


Yes, PlayerProfile is a part of the model. :-)

Sorry, I wasn't very clear...
You said that the client can change the state of the PlayerProfile and the model won't know - The thing is, the PlayerProfile is (a part of) the model, so the model does know.
Essentially, your definition of the model concept is flawed.


Quote:

Hmmm. What happens if a data object changes and the model doesn't know anything about that change. For example a name displayed in the view?

Usually the model notifies each observer by calling the notify() function.

What you're calling the model is really an implementation of the façade pattern - Nothing inherently wrong with that mind you.
However, this means that you have to 'double wrap' your functions; the model façade will notify the observers and call the underlying model function (in PlayerProfile for example).

An alternative is to expose the underlying model classes (ditch the façade) and associate the observers directly with them.

Share this post


Link to post
Share on other sites
Quote:
Original post by dmatter
What you're calling the model is really an implementation of the façade pattern - Nothing wrong with that mind you.
However, this means that you have to 'double wrap' your functions; the model façade will notify the observers and call the underlying model function (in PlayerProfile for example).

An alternative is to expose the underlying model classes (ditch the façade) and attach the observers directly to them, or whatever other variation on an event system you might prefer in that case.


Ok, this was the information I was looking for. 'Double wrapping' the functions using the façade pattern was one idea, which will be necessary for all settings made "outside" of the model.

For all getters a deep copy will do the job. ;-)

Thanks to all!

Best regards,
Chris

Share this post


Link to post
Share on other sites

This topic is 3459 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this