#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2012
    Posts
    4
    Rep 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.
  2. #2
  3. Code Monkey V. 0.9
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Mar 2005
    Location
    A Land Down Under
    Posts
    2,095
    Rep Power
    1990
    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.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2012
    Posts
    4
    Rep Power
    0
    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.
  6. #4
  7. Code Monkey V. 0.9
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Mar 2005
    Location
    A Land Down Under
    Posts
    2,095
    Rep Power
    1990
    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.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2012
    Posts
    4
    Rep Power
    0
    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.
  10. #6
  11. Code Monkey V. 0.9
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Mar 2005
    Location
    A Land Down Under
    Posts
    2,095
    Rep Power
    1990
    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.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2012
    Posts
    4
    Rep Power
    0
    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.
  14. #8
  15. Code Monkey V. 0.9
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Mar 2005
    Location
    A Land Down Under
    Posts
    2,095
    Rep Power
    1990
    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.

IMN logo majestic logo threadwatch logo seochat tools logo