|
Posted by Dikkie Dik on 08/15/06 21:25
(This is going to be a long post)
Simon Dean wrote:
> Hi,
>
> I have a couple of questions. If you don't mind. Sorry, I do get a bit
> wordy at times. First one just throws some thoughts around hoping for
> answers :-)
>
> 1) Anyone got a theory on the usage of PHP Classes rather than an actual
> technical guide? ...
Programming has followed the same path as electronics. When I was born,
my parents bought a tape recorder. It came with a large piece of paper
(large enough to cover a whole table) with _the_ electrical scheme. You
could look for hours at it and still discover new things.
Just like a GW-basic program. Or a Pascal program. One program that
contained everything.
We don't build electronic devices like that anymore. If you open a
modern tape recorder, you'll see small circuit boards or even encased
circuits that are plugged together.
If you want to get a feeling to what an object is, look at a hard disk.
It has a lot in common with an "object-oriented" object:
- It has a case that shields its inner (private) parts.
- It has an interface: a boundary between inside and outside which only
exposed what needs to be exposed. An interface in the electrical sense
is a plug. It even has some partial interfaces (interface keyword in
PHP5): it has a power plug, a data plug, and a "busy" light plug.
- It has a specific task. This task is so specific that it is totally
useless without its normal environment. Just like a HtmlElement makes no
sense outside the HTML DOM.
- Because it is so specific, it can be tested separately. (in software,
we call these tests: unit tests)
- Because is features standard plugs (implements known or general
interfaces), it can be replaced by something that features the same
plugs (a RAID device, an optical disk, a storage device based on memory
cards, etc.)
>
> Class someclass {
> var $WhyUseVars;
> var $Something;
>
> function somefunction ($OrParameters) {
> $this->Something = result;
> return $OrReturnHere
> }
> }
>
> I mean, should you pass parameters into the function, or set the
> variable properties of the class? Return a value from a function, or set
> another variable?
Here we touch something new: responsibility. Because a class has a
specific and limited task, it can be held responsible for that task.
This responsibility can be thoroughly tested (with unit tests) and
therefore relied upon. Generally, you should not set the properties
directly, because then these properties are beyond control of the class,
and then the class looses its responsibility. This means that far more
code is responsible (or interfering with) the task. In essence, this is
the same problem as the use of global variables: you never know what the
state is and when it was set.
More on responsibility can be found on the net by searching for "Design
by Contract"
>
> What are the advantages? Which way is correct?
>
> I start thinking, if you start using properties to pass information in
> and out, it's going to get very complicated and messy with properties
> that have no real useful purpose.
This is another reason why you should not use the variables directly.
Once you separated the inside from the outside (the implementation from
the interface), you can _optimize_ the inside. Suppose you have a
collection whose members come from a database. If the class exposed an
array of member objects directly, The array should be filled beforehand,
even if only a part of it is used. But if you use an Item() method to
get to the members, your class now has the choice to load everything in
advance or on demand. This can have a good impact on performance, but
does not change the use of the class. This separation between inside and
outside is called "encapsulation". The outside only gives access to
_what_ a class does, and hides the _how_.
> But then if you have one function that relies on another function, there
> is the danger of getting variables floating around from one place to the
> other.
>
> eg, I pass in a code to function1. Function1 doesn't use that code, but
> passes it onto Function2 in order to perform a lookup and return
> readable information to Function1.
There need not to be anything wrong with that. In effect, lots of
coarse-grained functions "delegate" tasks to finer-grained functions.
Like some coarse-grained classes delegate to finer grained classes.
>
> Of course, then I come up with the thought, that I might want to use the
> second function outside of the first function, but I've written the
> second function in such a way that it can only be called from the first
> function.
Then change it. Or better, evolve it. If it is a private method, you can
make it public. If it relies on a property, you can change that into a
parameter of the function. No design up front is perfect. And if it is
perfect today, then it isn't anymore tomorrow. Software grows. Evolves.
>
> 2) I like minimalism and trying to keep things simple as possible,
> without having to remember that in order to use a function I need to
> pass it a number of the variables from the webpage or hardcoded in my
> config.php file. ie, I want to give a function a certain amount of
> autonomy - if it wants a constant in my file, it should get it itself.
> Of course when I first started out, I was using globals.
Be careful not to give too much responsibility to an object. Should the
object be responsible for digging for its own data, or should it get the
data through its constructor? The less you have your objects "break in"
into its environment, the better it can be understood and maintained.
The main danger in this is "tight coupling": the objects gets so
intertwined in other objects or their environment, that they are not
separate and specific anymore. And therefore cannot be tested separately
anymore. And therefore cannot be _trusted_ anymore. Think. Should a hard
disk go find its own power source? If so, could it be used in other
computers or devices? Definitely not. "Lone cowboy" objects cannot be
reused and are therefore of little value.
>
> Anything better?
>
> Maybe I could just have a "SiteParameters" class, create a new instance,
> and get the information that way?
That is certainly a way. That object has as responsibility "providing
access to the state definition of the site". Any object that depends on
that state, depends on that object. If the state is handled incorrectly,
you know where to look.
Such an object is no different from a switchboard or a control panel in
the electrical sense.
>
> Im not sure what the best way is, I know I just want to avoid needless
> repetition, keep things simple, and avoid the situation where Im passing
> the same information in chained function calls.
Please keep the intention of avoiding needless repetition and of
simplicity. However, some data is often needed and long-lived. The
database object (or connection), for example, is needed by almost all of
your database code. So it gets passed around. Nothing wrong with that.
Best regards
Navigation:
[Reply to this message]
|