tags:

views:

215

answers:

4

How would I properly pass along data to a class being referenced in this structure:

                                  -Head
Index - PageBuilder - PageSection -Body
                                  -Foot

I want to send lots of data to head, for example, but I would like to avoid this:

new PageSection('head','how to cook',$keywords,$description,$script,$css);

The above looks terrible to manage and modify. And there is more data that would be needed to be passed not shown in that example!

The classes Head, Body, and Foot need a lot of user supplied data, but what is the best way to send this data along. Keep in mind that some data needs to be hard-coded, while some needs to be set based on a database or in some cases rely on default settings.

A: 

That probably would be defining the object that contains your variables. This way you can safely refer to the particular property by its name. You can also use map or array. For example, jQuery wildly using params object for such purpose, so in your code you can have (mocked syntax)

doSomething(props) {
  props.head
  props.body
  props.foot
}
DroidIn.net
+3  A: 

Why not create an object representing your parameter set ? So you simply pass one object, but that contains your individual parameters. One advantage is that you can refactor easily to add/remove data sent to the method, but not change the method invocations since they're just handling the parameter object.

A (contrived) example follows (in Java, since I'm not PHP-aware)

// build the parameters from command-line args 
// (you could build from a database or XML or whatever)
PageParameters p = PageParameters.fromArgs(args);

PageSection page = new PageSection(p);

PageParameters would contain the properties required to construct a PageSection object in some form - not necessarily the form that PageSection would store them itself. PageParameters could have functionality itself that doesn't belong in PageSection (e.g. command line args parsing, sanity-checking values etc.)

Brian Agnew
This brings back the same problems, but just in another place...
Nicky De Maeyer
Not when you pass around that data across more than one object and/or through different layers.
Brian Agnew
I agree, I would refactor the parameters into a data-object (all member variables are public and very few (no?) methods) and then pass an instance of such an object to the PageSection class.
Morningcoffee
Could you show a simple example? Would I use an interface?
Allen
look at the Q, hes talking about passing params to the constructor. You state the following: Create an object, set all the params you need to pass to the constructor, pass the objct to the constructor, inside the constructor get all the properties off the object and set them as properties on itself. + save the saved object to be able to pass it around some more (in which case you could pass the class itself, since it has all the same properties)Doesn't seem very logical?
Nicky De Maeyer
1) the parameter object can be constructed in a variety of different ways. 2) you can pass it around very easily 3) it can source itself independently of the object(s) you pass it to 4) the parameter object doesn't have to contain/represent the data in the same format as the constructed object(s). It's a powerful separation of concerns.
Brian Agnew
Cool! How about an example?
Allen
Exactly correct answer.
Alex
A: 

You could use setters instead of passing everything through the constructor.

$section = new PageSection('head');
$section->addKeyword();
$section->setDescription();

you could get an array of the set keywords, edit the array and reset it:

$keywords = $section->getKeywords();
//edit them
$section->setKeywords($keywords);

or you could create even more subclasses, but watch out for complexity and unneccesary subclassing...

Nicky De Maeyer
The issue here is that I cant be calling functions that way because the Section object is being declared inside another object.
Allen
Using setters has the problems of (1) order in which they are called (2) not all setters have to be called by the client.
Alex
+1  A: 

Following the suggestions from Brian Agnew and Nicky De Maeyer, use both setters and getters and an array or an object in the constructor. My framework of choice (Zend) handles this precise problem in this manner.

Using both methods presents a couple of advantages over using just one of them.

  • Ease of initial configuration. If you were to use setters and getters solely then you would have to set each individual property in your code after the object is instantiated.
  • Using getters and setters, you get encapsulation of the logic that will drive each property that you need to manage within these objects.

Zend Framework uses a Config object that can be instantiated with an array and can be added to or removed from dynamically. But when a config object is passed to a constructor, then it is immediately converts to an array and is used as such. In this manner, its possible to use a Config object if that makes sense (say like loading in settings from the database or from a config file) or to just use an array if that makes sense (say like setting the parameters in code just object instantiation).

Additionally, Zend Framework provides the getters and setters so that you can freely modify the object in code at any time. Otherwise you would have to destroy the existing object and then re-instantiate with the adjusted parameters.

Noah Goodrich