The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages - More
> Software Design
|
Most suitable place for object state validation
Discuss Most suitable place for object state validation in the Software Design forum on Dev Shed. Most suitable place for object state validation Software design forum discussing design principles and non-language specific algorithms. Get help with logic, algebraic, or relational concepts.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

February 6th, 2012, 06:48 PM
|
|
Registered User
|
|
Join Date: Feb 2012
Posts: 4
Time spent in forums: 30 m 50 sec
Reputation Power: 0
|
|
|
Most suitable place for object state validation
So assuming we have class Foo with properties FirstProp and SecondProp and ThirdProp. Business wise, the allowed values in SecondProp are dependent on the value set for FirstProp and ThirdProp's allowed values are dependent on the values of both FirstProp and SecondProp. Where is it most suitable to put this logic?
If it is in the setter of each property then there is the fact that the class user might set he ThirdProp before the other two, would we also need to enforce the order of setting the properties then? That does not seem optimal. Also, if we are to restrict initialization of the object to parmererized constructors then this would not be practical in cases like when we are designing the object as a value type (struct) since the default constructor in a struct is always available.
Any input appreciated.
|

February 6th, 2012, 06:56 PM
|
 |
Code Monkey V. 0.9
|
|
Join Date: Mar 2005
Location: A Land Down Under
|
|
|
To do that in the most flexible way you would do it both ways. Set up the object constructor to take in the arguments for the three values and then use it's internal functions to add the values in the correct order.
The validation should be done on the setter function for that value. If it's not then there's no way of enforcing it. You have to check... when the setter is called for ThirdProp, check that SecondProp is set. If it is, then allow it and if not don't allow it. You can sort out errors or exceptions how ever you need to for your application then.
|

February 6th, 2012, 07:23 PM
|
|
Registered User
|
|
Join Date: Feb 2012
Posts: 4
Time spent in forums: 30 m 50 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by Catacaustic To do that in the most flexible way you would do it both ways. Set up the object constructor to take in the arguments for the three values and then use it's internal functions to add the values in the correct order.
The validation should be done on the setter function for that value. If it's not then there's no way of enforcing it. You have to check... when the setter is called for ThirdProp, check that SecondProp is set. If it is, then allow it and if not don't allow it. You can sort out errors or exceptions how ever you need to for your application then. |
What about if I want to implement Foo as a struct, then the default constructor would be available and there is no automatic way of enforcing the rules.
|

February 6th, 2012, 07:35 PM
|
 |
Code Monkey V. 0.9
|
|
Join Date: Mar 2005
Location: A Land Down Under
|
|
Quote: | Originally Posted by EmEsDi What about if I want to implement Foo as a struct, then the default constructor would be available and there is no automatic way of enforcing the rules. | Assuming that I understand you correctly...
Yes there is. In your constructor you don't set the values directly. You pass the given values to your setter methods and they do the same checking that they do when you set them at any other time. That way you still have access to any errors that occur. You just have to set up your setter methods to throw the right sort of error/exception.
|

February 6th, 2012, 07:54 PM
|
|
Registered User
|
|
Join Date: Feb 2012
Posts: 4
Time spent in forums: 30 m 50 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by Catacaustic Assuming that I understand you correctly...
Yes there is. In your constructor you don't set the values directly. You pass the given values to your setter methods and they do the same checking that they do when you set them at any other time. That way you still have access to any errors that occur. You just have to set up your setter methods to throw the right sort of error/exception. |
Maybe I should have given more of an explanation:
Using C# as the language (in other words the .Net Framework)
public struct Foo
{
public int FirstProp{get;set;}
public int SecondProp{get;set}
public int ThirdProp{get;set;}
public Foo(int firstProp, int secondProp, int thirdProp)
{
FirstProp = firstProp;
SecondProp = secondProp;
ThirdProp = thirdProp;
}
}
//the consuming class
public static int main()
{
Foo foo = new Foo();
foo.ThirdProp = somValue;
}
Here you can see that I am creating a struct where the default constructor is always available even if I have a parameterized constructor. This would let the consumer initialize the properties in whichever order they want, evident by assigining to ThirdProp before First and Second.
If we are going to allow for such a scenario then why have the constructor to begin with.
Edit:
In the case above, if ThirdProp had validation logic that throws an exception if First and SecondProp were not set, then we get that exception upon using Foo in such a way. But my question is, is this the best way to do it by throwing exceptions to the user if they set the values in the not-so-expected order? Also keeping in mind that they could end up with a valid object after setting all the properties to the relevently correct values.
|

February 6th, 2012, 10:18 PM
|
 |
Code Monkey V. 0.9
|
|
Join Date: Mar 2005
Location: A Land Down Under
|
|
I thought that's what you meant, and my solution is actually correct for what you said. I'm doing this in PHP because I haven't done Java for so long I don't remember much, but here's the basics of doing it my way.
PHP Code:
class Foo {
private $var1;
private $var2;
private $var3;
public function __construct ($var1 = NULL, $var2 = NULL, $var3 = NULL) {
if (!is_null ($var1)) {
$this->setVar1 ($var1);
}
if (!is_null ($var2)) {
$this->setVar2 ($var2);
}
if (!is_null ($var3)) {
$this->setVar3 ($var3);
}
}
public function setVar1 ($var) {
$this->var1 = $var;
}
public function setVar2 ($var) {
if (!is_null ($this->var1)) {
$this->var2 = $var;
}
else {
throw new Exception ("Var1 is not set");
}
}
public function setVar3 ($var) {
if (!is_null ($this->var2)) {
$this->var3 = $var;
}
else {
throw new Exception ("Var2 is not set");
}
}
}
The difference with mine is that I am not setting the values directly in the constructor the way that you are, and the values are not publicly visible so you have to use the internal setter methods in order to set a value to them.. I am setting them using the objects internal methods, which lets me check for the other values and set up the exceptions for when there's an error.
That is really all there is to it. You only want an exception when another value is not set, so just check the values that need to be set before you set the requested value.
Last edited by Catacaustic : February 6th, 2012 at 10:20 PM.
|

February 7th, 2012, 01:20 AM
|
|
Registered User
|
|
Join Date: Feb 2012
Posts: 4
Time spent in forums: 30 m 50 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by Catacaustic I thought that's what you meant, and my solution is actually correct for what you said. I'm doing this in PHP because I haven't done Java for so long I don't remember much, but here's the basics of doing it my way.
PHP Code:
class Foo {
private $var1;
private $var2;
private $var3;
public function __construct ($var1 = NULL, $var2 = NULL, $var3 = NULL) {
if (!is_null ($var1)) {
$this->setVar1 ($var1);
}
if (!is_null ($var2)) {
$this->setVar2 ($var2);
}
if (!is_null ($var3)) {
$this->setVar3 ($var3);
}
}
public function setVar1 ($var) {
$this->var1 = $var;
}
public function setVar2 ($var) {
if (!is_null ($this->var1)) {
$this->var2 = $var;
}
else {
throw new Exception ("Var1 is not set");
}
}
public function setVar3 ($var) {
if (!is_null ($this->var2)) {
$this->var3 = $var;
}
else {
throw new Exception ("Var2 is not set");
}
}
}
The difference with mine is that I am not setting the values directly in the constructor the way that you are, and the values are not publicly visible so you have to use the internal setter methods in order to set a value to them.. I am setting them using the objects internal methods, which lets me check for the other values and set up the exceptions for when there's an error.
That is really all there is to it. You only want an exception when another value is not set, so just check the values that need to be set before you set the requested value. |
I totally understand what you are saying, but thign is when I say property in C# this means it has setters and getters by default, so when I write "FirstProp = firstProp;" I am actually using a setter where I can validate the conditions. On the other hand, and maybe this is framework specific, in .Net a struct (which is a value type as opposed to a reference type) always has a "default parameterless constructor", this would mean that the struct user will still be able to leave the variable foo in an invalid state.
|

February 7th, 2012, 04:13 AM
|
 |
Code Monkey V. 0.9
|
|
Join Date: Mar 2005
Location: A Land Down Under
|
|
|
I don't know C# that well, but from what you are saying, you mean that there is no such thing as a private value in an object? And that you can't define your own setter/getter methods?
If that's the case (which I doubt) then sure, you can't do anything. But if you can have private values, and create your own getter/setter methods, then do it that way. it solves all of your issues.
I'll be honest... From this point I really don't know what else you want to hear.
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|