|
Posted by Moot on 04/20/07 17:54
On Apr 20, 12:56 pm, "Steve" <no....@example.com> wrote:
> "Moot" <use...@mootsoft.com> wrote in message
> | To me, the whole concept and reason for making a class is so that you
> | can encapsulate logic and present the user (remember, the user of your
> | class isn't the end user, it's you or another programmer) with a clear
> | set of "here's what you can do with this object type". Using the
> | magic get/set functions means that unless you have intimate knowledge
> | of the internal working of the class, you would have *no clue* as to
> | what is capable with an object of that class.
>
> reason for the big question mark? because there is nothing magic going on
> here. haven't you all programmed in non-scripted languages? here's how they
> implement what the op wants...let's say vb.net:
The word "magic" was not me being cute, it's the actual terminology
used in the PHP manual:
http://us2.php.net/manual/en/language.oop5.magic.php
Quote: "The function names __construct, __destruct (see Constructors
and Destructors), __call, __get, __set, __isset, __unset (see
Overloading), __sleep, __wakeup, __toString, __set_state, __clone and
__autoload are magical in PHP classes."
>
> private static myBar as string
> public static property bar() as string
> get
> return myBar
> end get
> set(byval value as string)
> ' add some validation
> ' maybe throw some errors
> ' else, if all is well
> myBar = value
> end set
> )
>
Yes, I've done plenty of .NET programming, but do you see what you did
there? You created a Getter/Setter specifically for the variable
MyBar, you didn't rely on a "magic" (again, the *actual term*) method
to interpret which private variable you wanted. You specifically
defined that to get myBar, you need to call bar().
>
> notice his suggestions encapsulates/protect his variable. all __set/__get
> does is pawn off the public call to private getters/setters...emulating the
> code above.
If you're going to have private get/set functions, why not just make
them public? Why add the extra layer of redirection?
>
> | Here's an example:
> | Say you and I are working on a web app. You've created a class to
> | wrap around a contact in a user's addressbook. I need to get a list
> | of phone numbers to call for some salespeople, so I say, "hey, I'll
> | use this handy Contact class my buddy made". I create an object, type
> | $contact-> and...??? My IDE's autocomplete pops up with a few
> | functions (save, update, etc...), but how do I get the phone number?
> | Is it:
> | $contact->phone;
> | $contact->phonenumber;
> | $contact->phone_num;
> | $contact->...
> | You get the point.
>
> your point is that you want to tailor/limit good coding practices to be
> inline with whatever ide of the week is being used. here's my point...the
> public vars will still show up as interfaces in an ide's autocomplete.
But since we're debating this, I can assume that we all acknowledge
that getter/setter functions in any implementation are far superior to
allowing the user to access the variable directly, so there should be
no public variables visible to the user. Internal object variables
should always be wrapped in some kind of get/set function.
>
> | Whereas with actual defined get/set functions, it would be very
> | intuitive. I'd see getPhoneNum() in the autocomplete and instantly
> | know that's what I need to call.
>
> christ...should we now have ide wars to go along with the browser wars? to
> which do we yeild our good coding standards/best practices. oh yes, to
> sacrifice.
>
Okay, I see that my mentioning an IDE as an analogy went right over
your head. It was a liberty I took to make the example easier, but I
see that I need to be more specific for you. Say you write a class
that I later want to use. We'll look at it as if you've done it 3
different ways:
A - you use the __get/__set methods to allow the user to access
private variables
B - you use the __get/__set methods to allow the user to access
private variables by going through a private getter/setter function
C - you make seperate getter/setter functions for each private
variable
Now, to know how to use that class (and, so you don't get snippy, I'll
code in Notepad for the sake of this argument), I have to:
A - go to the __get function and examine the code (including any if/
else or switch conditional logic there may be) to determine what X to
call so that it will return me Y
B - same as A, only now I find that X points me to Z, which returns me
Y
C - find the appropriate getX function
Maybe in a small class this concept is trivial, but any decently sized
class using __get is eventually going to end up being full of
conditional switching. Also, if I've been a good little programmer
and set up my code for auto-documentation generation, then the
generated interface for the object will show all getter/setter
functions, but will completely ignore any conditional switching
located inside of a __get function.
> | Yes, it is a lot of extra work to make individual get/set functions,
> | and most of them are going to be near identical copy/paste jobs, but
> | 12 months down the road when you have long since forgotten how
> | *exactly* your class works, which will be easier? Digging into the
> | class code to figure out which variable names you're supposed to use,
> | or letting your IDE's autocomplete pop up and immediately knowing what
> | get function to call. Take the extra time up front and you'll save
> | headaches down the line.
>
> i don't know that you've done oop in a non-scripted language. none of your
> arguments would make valid sense if you had.
Here's my main point: __get allows you to make your class dynamic in
that you can call $obj->anything and let the class figure out what
that "anything" means. That's all fine and dandy for the person
writing the class, and often makes their life easier. But you don't
code OOP for yourself, you code it for the person using the objects,
whether that be you or a team of a dozen other programmers. When you
make your class able to accept "anything", then how does the user know
that $obj->foo is allowed, while $obj->bar is undefined? They don't,
unless they open up your code to figure out what the heck you were
thinking when you wrote it.
Bottom line: the __get/__set functions enable developers to hide the
interface to the object INSIDE of the object. Since the interface is
how you are expected to interact with an object, it needs to be fully
exposed and visible to the outside user. The only way to do this is
with publicly visible getter/setter functions
- Moot
Navigation:
[Reply to this message]
|