|
Posted by Steve on 04/20/07 18:59
"Moot" <usenet@mootsoft.com> wrote in message
news:1177091647.851097.10880@y80g2000hsf.googlegroups.com...
| 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."
let's just say they are *reserved* words as all other language constructs
have. however, *those* are all built-in to php and are a construct by which
all must abide. using getters/setters truly IS magic. as i said earlier,
setting a property in your example would mean that all properties have
associated getProperty/setProperty (for transparency). the preamble
(get/set) is a construct of your own making and you require it as a
construct yourself.
using __set/__get, were it to work the way the op thinks is does, let's you
name a property *ANYTHING* and your private getters/setters can be named
*ANYTHING*...further, it completely decouples special knowledge about your
home-brewed construct of getProperty/setProperty (no matter how commonly
used by others).
i'm not trying to argue with you here. i'm trying to be as technically
accurate as possible.
| >
| > 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?
well, you may want to have mixed scopes on properties - private set/ public
get. you may want to have a setter ONLY IN YOUR CLASS so that the validation
(which may refer to private members) can be handled uniformly
(self::propertySetter). and since you can't truly overload in php, there's
no way to have a public setter and a private setter at the same time - both
doing different things. that means you're stuck adding more magic
nomanclature for the private setter. the other way though, you can have a
public setter AND a private setter, calling them what you will.
plus, it is a hugely transparent operation for the developer. forget that
they don't have to know your prefixing the property with get/set. there is
less to code. as i showed,
$foo->bar = 'hello world';
echo $foo->bar;
much neater to me. on the back-end, my class is more uniformly defined: one
section defines the interfaces, the next with their private getters/setters,
and then finally ONE place where each getter/setter is utilized and where
the bulk of simple data validation would occur...leaving the getters/setters
to simply focus on the business logic rather than both.
| > 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.
for ANY property to be set, you HAVE TO HAVE a getter and setter. what we're
talking about is having php allow us to detect the event and validate the
rhs value being assigned to the property.
as for 'is it a good idea to let users directly massage properties?'...SURE
IT IS. it just depends on what you're doing with the information and how you
are going to validate it, if at all. using NEVER is a strong word. i have a
ton of singleton's that are all public static variables. the methods on the
object are what are used in most of those classes. gi == go...plus i tell
them if anything is amiss with properties when they are used. that too could
be advantagous as well. think of a setter/getter on an obj in a loop. were
validation going on behind each get/set and the loop happened many times,
THAT could be a huge lag on the cpu. however validation when needed means
the final value of the property would be analyzed only after the
loop...speeding things up much quicker.
| >
| > | 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
there is NO conditional stuff going on in __set/__get. it should contain a
switch that calls the appropriate private getter/setter, passing along its
arguments.
now, you're in the EXACT SAME delima as if we used PUBLIC getters/setters.
so, your point here becomes? that you have to look at the switch to see what
the private getter/setter name is? if that's the case, just have the law of
the land be the same...everything in a class the returns a prop value begins
with 'get' and those that set prop values begin with 'set'. but, again
you've made no real point here...that i can see.
| 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.
you make a lot of assumptions here, none of which you can back up. the
switch is how it is programmed. if you want to complicate the mechanism
beyond what i've described, then, yes, it could get ugly. however, my idea
of the switch is mearly to act as a stub to which is passes information to
the appropriate 'in/out' box.
are you simplifying here again? you literally mean this time that we are so
sacrifice solid best practices - not for an ide this time - for an
'auto-documentation' generator? my former comments on this frivolity apply
here as well...so i'll leave it at that.
| > | 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.
if you make $foo a PUBLIC var then even your ide's autocomplete will pick
that up. if it ties into php documentor, then your comments can have the
autocomplete state scope, type, etc., etc. as i've said before.
what the op wants to do IS define $foo, BUT want's php to let him handle
(with __get/__set) $foo when it is on then lhs or rhs of an operation.
again, i don't see you have a point. do you think if you gave some
psuedo-code here that is would help me get on the same page from which
you're reading?
| 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
no, the interface is PUBLIC. what we're hiding and NOT requiring the user to
know is the NAME of our PRIVATE getters/setters. they simply use the
interface either on the lhs or the rhs...making the object's consumption
easier and more decoupled. so NO, 'the only way to do this is' NOT JUST
'with publicly visible getter/setter functions'.
that's the bottom line, imo.
Navigation:
[Reply to this message]
|