Object variables

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Although this if OT:

My issue with JavaBeans is that the setters are public void setX(value X)
It doesn't allow me to perform operator chaining or check if the property was really set (without calling getX)

Before i learned Java i used Pascal, and this language made even a distinction between a function (returns something) and a method (doesn't return something)
User avatar
AKA Panama Jack
Forum Regular
Posts: 878
Joined: Mon Nov 14, 2005 4:21 pm

Post by AKA Panama Jack »

Jenk wrote:I'm a Java fan boy, therefore it's method and property for me :P

btw - if anyone else is curious about the result of my previous question RE: parent::get() -

Code: Select all

<?php      
    
class A
{
    private $a = 1;
    
    public function getA ($a)
    {
        $this->a = $a;
        return $this->a;
    }
}

class B extends A
{
    public function getA ()
    {
        return parent::getA('a');
    }
}

$b = new B;
echo $b->getA(); //outputs 'a'
      
?>
The sad thing is that extending a class function with a function of the same name is very slow and memory hungry in PHP.

Code: Select all

<?php      
    
class A
{
    private $a = 1;
    
    public function getA ($a)
    {
        $this->a = $a;
        return $this->a;
    }
}

class B extends A
{
    public function getA2 ()
    {
        return $this->getA('a');
    }
}

$b = new B;
echo $b->getA2(); //outputs 'a'
      
?>
If you don't need the same function name the above method is many times faster and uses alot less memory when creating the extended object.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

timvw wrote:Although this if OT:

My issue with JavaBeans is that the setters are public void setX(value X)
It doesn't allow me to perform operator chaining or check if the property was really set (without calling getX)

Before i learned Java i used Pascal, and this language made even a distinction between a function (returns something) and a method (doesn't return something)
ASP uses the same distinction for functions(returns something) and subprocedures(doesn't return something)

Sometimes, it is the problem of how we set the member variable, some might do like,

Code: Select all

class A{
	private int var_a;
	//logic implemented inside the function.
	//This would require you to know whether the value sent is set or not.
	public void set_a(int a){
		if (a < 100){
			this.var_a = a;
		}
	}
	public int get_a(){
		return this.var_a
	}
}
this is better way where you avoid the necessity boolean return for set operations

Code: Select all

class A{
	private int var_a;
	public void set_a(int a){
		this.var_a = a;
	}
	public int get_a(){
		return this.var_a
	}
	//Logic is done here or in the JSP page itself
	//Beans only expect just to set and get member variables
	//You do not really implement logic over there
	public boolean check_a(int a){
		if (a < 100){
			set_a(a);
			return true;
		}
		return false;	
}
}
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

I don't really see why a void method is better than a boolean method to avoid mixing of concerns (doing bussiness logic in the view).

Eg: My (servlet) template simply accepts values, if my bean doesn't accept them, i have to display an error.
As you see, the logic (is the age valid or not) remains in the bean.

Code: Select all

if (!somebean.setAge(request.getParameter("age"))) {
  displayPageAgain();
} else {
  moveToNextPage();
}
Initializing an Entity(Bean) (J2EE/EJB3 Persistence) goes as following:

Code: Select all

Person p = new Person();
p.setAge(18);
p.setName("Van Wassenhove");
p.setSurname("Tim");
Now if a bean could return itself on a setter method i could write:

Code: Select all

Person p = new Person().setAge(18).setName("Van Wassenhove").setSurname("Tim");
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

When we normally look at something like that, we prefer boolean and I too agree with that. In some case, if business logic is huge and you cannot put that in the setter method so you validate business logic elsewhere and make a call to setter if necessary.

Code: Select all

Person p = new Person().setAge(18).setName("Van Wassenhove").setSurname("Tim");

I do not think this statement is valid. Forgive me if I am wrong.

Code: Select all

if setAge(18) returns one then you have 
(boolean).setName("Van Wassenhove").setSurname("Tim"); //which cannot be done
and this is the same for
(boolean).setSurname("Tim"); 
you are trying to call methods of a primitive data type which is an error.
a valid example would be

Code: Select all

BorderLayout bl = new BorderLayout();
System.out.println(bl.preferredLayoutSize(frameObject).toString().length());
Here first execution of preferredLayoutSize() on borderlayout object returns a Dimension object
execution of toString() method on Dimension object returns a String object
execution of length() method on String object returns the length of the string in int
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

raghavan20 wrote:

Code: Select all

Person p = new Person().setAge(18).setName("Van Wassenhove").setSurname("Tim");

I do not think this statement is valid. Forgive me if I am wrong.
That is because you snipped my line: "Now if a bean could return itself on a setter method"

Thus the methods would return Person which makes my code valid syntax :)
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

for the sake of pressing a few extra keys, it would be better for the setters to return true or false, or perhaps throw an exception/trigger_error.

Or you could design the constructor to take those param's optionally when you instantiate the object. :)

Code: Select all

$person = new Person('Tim', 'Van Wassenhove', '18');
$person->checkDetails();
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

timvw wrote:
raghavan20 wrote: That is because you snipped my line: "Now if a bean could return itself on a setter method"

Thus the methods would return Person which makes my code valid syntax :)
I am sorry about that, I somehow missed to read that line properly.

I have a clarification, why would a bean want to return itself other than it made three lines into line in your example. :?

And Jenk, I do not understand what you are trying to say with that constructor design. :roll:
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Code: Select all

<?php

class Person
{
    protected $name;
    protected $surname;
    protected $age;
    
    public function __construct ($name, $surname, $age)
    {
        $this->setName($name);
        $this->setSurname($surname);
        $this->setAge($age);
    }
    
    //etc..

}

$person = new Person('Tim', 'Van Wassenhove', '18');

?>
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Jenk wrote:

Code: Select all

$person = new Person('Tim', 'Van Wassenhove', '18');
$person->checkDetails();
This is something i would strongly advise not to do :) Because between the constructor and the call to checkDetails there is a time that the person is in an invalid state... And OOP is about preventing objects to go into an invalid state. As you said, throwing an error in the constructor is more appropriate

Code: Select all

try {
 $person = new Person(...);
} catch (InvalidAgeException iae) {
  //
}
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

That I am aware of, thus why there would be a boolean property to test if the checkDetails() has been called :P

Anyway, my later example is better - the constructor uses the setters.
Post Reply