|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
I've been a procedural PHPer for a while now and I don't know why it
has taken me so long to start the jump from procedural to OOP. I have a function that I would use for doing length conversions... feet to meters, inches to centimeters, etc... and I wanted to try and turn that into a useful class just for some OOP practice, but I don't think it was a very good start. Maybe it was a bad function to begin with... but I'm not seeing how this class is of any more use if any than the function was on its own. What are the advantages of turning that into a class and how could I improve it to make it better? ################################# ## Original conv function ################################# function conv($val, $lenFrom, $lenTo) { switch ($lenFrom) { case 'm': $m = $val * 1; $cm = $val * 100; $mm = $val * 1000; $ft = $val * 3.2808399; $in = $val * 39.3700787; break; case 'cm': $m = $val * 0.01; $cm = $val * 1; $mm = $val * 10; $ft = $val * 0.032808399; $in = $val * 0.393700787; break; case 'mm': $m = $val * 0.001; $cm = $val * 0.1; $mm = $val * 1; $ft = $val * 0.0032808399; $in = $val * 0.0393700787; break; case 'ft': $m = $val * 0.3048; $cm = $val * 30.48; $mm = $val * 304.8; $ft = $val * 1; $in = $val * 12; break; case 'in': $m = $val * 0.0254; $cm = $val * 2.54; $mm = $val * 25.4; $ft = $val * 0.0833333333; $in = $val * 1; break; } switch ($lenTo) { case 'm': return $m; break; case 'cm': return $cm; break; case 'mm': return $mm; break; case 'ft': return $ft; break; case 'in': return $in; break; } } // one foot... convert it to inches echo conv(1, 'ft', 'in'); // returns 12 // 24 inches... convert it to feet echo conv(24, 'in', 'ft'); // returns 2... well, after you round it is 2 ################################### ## My attempt at converting it into a class ################################### class Conv { var $m; var $cm; var $mm; var $ft; var $in; function conv($val, $lenFrom, $lenTo) { switch ($lenFrom) { case 'm': $this->m = $val * 1; $this->cm = $val * 100; $this->mm = $val * 1000; $this->ft = $val * 3.2808399; $this->in = $val * 39.3700787; break; case 'cm': $this->m = $val * 0.01; $this->cm = $val * 1; $this->mm = $val * 10; $this->ft = $val * 0.032808399; $this->in = $val * 0.393700787; break; case 'mm': $this->m = $val * 0.001; $this->cm = $val * 0.1; $this->mm = $val * 1; $this->ft = $val * 0.0032808399; $this->in = $val * 0.0393700787; break; case 'ft': $this->m = $val * 0.3048; $this->cm = $val * 30.48; $this->mm = $val * 304.8; $this->ft = $val * 1; $this->in = $val * 12; break; case 'in': $this->m = $val * 0.0254; $this->cm = $val * 2.54; $this->mm = $val * 25.4; $this->ft = $val * 0.0833333333; $this->in = $val * 1; break; } switch ($lenTo) { case 'm': return $this->m; break; case 'cm': return $this->cm; break; case 'mm': return $this->mm; break; case 'ft': return $this->ft; break; case 'in': return $this->in; break; } } } $conv = new Conv; // one foot... convert it to inches echo $conv->conv(1, 'ft', 'in'); // returns 12 // 24 inches... convert it to feet echo $conv->conv(24, 'in', 'ft'); // returns 2... well after you round it is 2 ################################################## ############# Well... I guess I can see ONE benefit. When converting the 24 inches into feet above: echo $conv->conv(24, 'in', 'ft'); I can go back and get millimeters for the 24 inches: echo $conv->mm; // returns 609.6 or centimeters for the 24 inches: echo $conv->cm; // returns 60.96 etc... without having to resend the '24' inches to the conv method in the Conv class each time as long as the inches value doesn't change. So essentially I can send the 24 inches once, and I've got the converted numbers for feet, meters, centimeters and millimeters at my disposal without having to send the 24 inches again each time. What other benefits are there other than that though? I'm totally green when it comes to OOP so you can totally rip that class and tell me how you would improve it if you've got the time and would like to share. Thanks guys! IBB |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
oh.i.love.spam@gmail.com escribió:
> I've been a procedural PHPer for a while now and I don't know why it > has taken me so long to start the jump from procedural to OOP. I have > a function that I would use for doing length conversions... feet to > meters, inches to centimeters, etc... and I wanted to try and turn > that into a useful class just for some OOP practice, but I don't think > it was a very good start. Maybe it was a bad function to begin > with... but I'm not seeing how this class is of any more use if any > than the function was on its own. What are the advantages of turning > that into a class and how could I improve it to make it better? > > ################################# > ## Original conv function > ################################# > function conv($val, $lenFrom, $lenTo) { > switch ($lenFrom) { > case 'm': > $m = $val * 1; > $cm = $val * 100; > $mm = $val * 1000; > $ft = $val * 3.2808399; > $in = $val * 39.3700787; I can't really you with your OOP questions*, but I think the best improvement you could add to your code is arrays. Hardcoding data in the middle of your scripts tends to be hard to maintain. (*) I hope you don't believe all those folks who claim that PHP will suck until it becomes a copy of Java. Object-oriented and procedural programming are just two approaches to choose from when face to an specific need. -- -- http://alvaro.es - Álvaro G. Vicario - Burgos, Spain -- Mi sitio sobre programación web: http://bits.demogracia.com -- Mi web de humor al baño María: http://www.demogracia.com -- |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
oh.i.love.spam@gmail.com wrote:
> I've been a procedural PHPer for a while now and I don't know why it > has taken me so long to start the jump from procedural to OOP. I have > a function that I would use for doing length conversions... feet to > meters, inches to centimeters, etc... and I wanted to try and turn > that into a useful class just for some OOP practice, but I don't think > it was a very good start. Maybe it was a bad function to begin > with... but I'm not seeing how this class is of any more use if any > than the function was on its own. What are the advantages of turning > that into a class and how could I improve it to make it better? > > ################################# > ## Original conv function > ################################# > function conv($val, $lenFrom, $lenTo) { > switch ($lenFrom) { > case 'm': > $m = $val * 1; > $cm = $val * 100; > $mm = $val * 1000; > $ft = $val * 3.2808399; > $in = $val * 39.3700787; > break; > case 'cm': > $m = $val * 0.01; > $cm = $val * 1; > $mm = $val * 10; > $ft = $val * 0.032808399; > $in = $val * 0.393700787; > break; > case 'mm': > $m = $val * 0.001; > $cm = $val * 0.1; > $mm = $val * 1; > $ft = $val * 0.0032808399; > $in = $val * 0.0393700787; > break; > case 'ft': > $m = $val * 0.3048; > $cm = $val * 30.48; > $mm = $val * 304.8; > $ft = $val * 1; > $in = $val * 12; > break; > case 'in': > $m = $val * 0.0254; > $cm = $val * 2.54; > $mm = $val * 25.4; > $ft = $val * 0.0833333333; > $in = $val * 1; > break; > } > > switch ($lenTo) { > case 'm': > return $m; > break; > case 'cm': > return $cm; > break; > case 'mm': > return $mm; > break; > case 'ft': > return $ft; > break; > case 'in': > return $in; > break; > } > } > > // one foot... convert it to inches > echo conv(1, 'ft', 'in'); // returns 12 > > // 24 inches... convert it to feet > echo conv(24, 'in', 'ft'); // returns 2... well, after you round > it is 2 > > > ################################### > ## My attempt at converting it into a class > ################################### > > class Conv { > var $m; > var $cm; > var $mm; > var $ft; > var $in; > > function conv($val, $lenFrom, $lenTo) { > switch ($lenFrom) { > case 'm': > $this->m = $val * 1; > $this->cm = $val * 100; > $this->mm = $val * 1000; > $this->ft = $val * 3.2808399; > $this->in = $val * 39.3700787; > break; > case 'cm': > $this->m = $val * 0.01; > $this->cm = $val * 1; > $this->mm = $val * 10; > $this->ft = $val * 0.032808399; > $this->in = $val * 0.393700787; > break; > case 'mm': > $this->m = $val * 0.001; > $this->cm = $val * 0.1; > $this->mm = $val * 1; > $this->ft = $val * 0.0032808399; > $this->in = $val * 0.0393700787; > break; > case 'ft': > $this->m = $val * 0.3048; > $this->cm = $val * 30.48; > $this->mm = $val * 304.8; > $this->ft = $val * 1; > $this->in = $val * 12; > break; > case 'in': > $this->m = $val * 0.0254; > $this->cm = $val * 2.54; > $this->mm = $val * 25.4; > $this->ft = $val * 0.0833333333; > $this->in = $val * 1; > break; > } > > switch ($lenTo) { > case 'm': > return $this->m; > break; > case 'cm': > return $this->cm; > break; > case 'mm': > return $this->mm; > break; > case 'ft': > return $this->ft; > break; > case 'in': > return $this->in; > break; > } > } > } > > $conv = new Conv; > > // one foot... convert it to inches > echo $conv->conv(1, 'ft', 'in'); // returns 12 > > // 24 inches... convert it to feet > echo $conv->conv(24, 'in', 'ft'); // returns 2... well after you > round it is 2 > > ################################################## ############# > > Well... I guess I can see ONE benefit. > > When converting the 24 inches into feet above: > echo $conv->conv(24, 'in', 'ft'); > > I can go back and get millimeters for the 24 inches: > echo $conv->mm; // returns 609.6 > > or centimeters for the 24 inches: > echo $conv->cm; // returns 60.96 > > etc... without having to resend the '24' inches to the conv method in > the Conv class each time as long as the inches value doesn't change. > So essentially I can send the 24 inches once, and I've got the > converted numbers for feet, meters, centimeters and millimeters at my > disposal without having to send the 24 inches again each time. > > What other benefits are there other than that though? > > I'm totally green when it comes to OOP so you can totally rip that > class and tell me how you would improve it if you've got the time and > would like to share. > > Thanks guys! > > IBB > > Essentially, not a lot of advantage for the way you have it. Back to basics. Variables have states - they remember things. $i is a typical variable - by itself it doesn't "do" anything. Functions have behavior - they do things. printf() is a function - it does stuff, but once the function call is complete, there's nothing left from that function. Variables don't do anything on their own (no behavior), and functions don't remember things (typically, at least). Objects have both state and behavior. They remember things like variables, but can do things. The class defines the objects state and behavior, and the object is an implementation of the class. mysqli is a typical database object is a typical example - it can open a connection to the database and perform operations on the database like functions, but also remembers the database connection and other information like a variable. In your case, you're probably doing a lot of unnecessary conversions - do you need every unit every time? But that doesn't mean it's not a candidate for an object. What I would do if I were making this an object is have functions such as set_m(), set_cm(), set_ft(), etc. Store the value in a private variable in whatever unit you want. Then have the equivalent get_m(), get_cm(), get_ft(), etc. functions to retrieve the information in the way your program needs. And variables are part of your implementation - they should almost always be private, occasionally protected but very seldom public. Anything public can never be changed without potentially affecting an unknown amount of other code - which is what OO is supposed to limit. -- ================== Remove the "x" from my email address Jerry Stuckle JDS Computer Training Corp. jstucklex@attglobal.net ================== |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
Good info guys... thanks! I've no idea when to make something public
or private or static or protected. I need to find a good book/ resource on just OOP in general and theory I think. I've got a couple of general beginner tuts that I'm sure will get me to a point... they give a lot of the "how" but not necessarily the "why". Any good resources you would recommend? Thanks again! IBB |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
oh.i.love.spam@gmail.com wrote:
> Good info guys... thanks! I've no idea when to make something public > or private or static or protected. I need to find a good book/ > resource on just OOP in general and theory I think. I've got a couple > of general beginner tuts that I'm sure will get me to a point... they > give a lot of the "how" but not necessarily the "why". > > Any good resources you would recommend? General: http://www.amazon.co.uk/Design-patte.../dp/0201633612 PHP specific: http://www.amazon.co.uk/PHP-5-Object.../dp/1590593804 -- Rik Wasmus ....spamrun finished |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
oh.i.love.spam@gmail.com schreef:
> Good info guys... thanks! I've no idea when to make something public > or private or static or protected. I need to find a good book/ > resource on just OOP in general and theory I think. I've got a couple > of general beginner tuts that I'm sure will get me to a point... they > give a lot of the "how" but not necessarily the "why". Hi, Many Java programmers had the opinion that *ALL* variables in your class (which are called 'members' then) should be private. In the case you want the user of that object to change them, expose a getter/setter method for it. But you'll easily find others who disagree and say all the getter/setter methods are a pain and unneeded noise brought to you by the Code Mafia. Why make a member private if you expose it again with a getter/setter method? What I want to say is you'll find a lot of differing opinions on the 'why' and 'how'. Best thing to do for you is simply learn how things work in OOP, and make up your own mind. And test a lot. Simply make a class, with public vars, and private vars. Can you access them? Then expose the private var via a getter/setter. Do you like that, or do you think it is codenoise? A rule of thumb I used (in Java) for choosing between private or public declarations was this: I only make those variables public (or private and offer a getter/setter) that are of direct interest to the coder using my class. For example: A class that fetches some article and related info from a database. The variable for setting the ID is public, then calling the fetch-routine would get that article. But the variables I use for database connection, errorhandling, looping over resultsets, etc is all private. Why would the user of my class care about them? Static and protected are completely different concepts. Best thing to do is buy a good book. :-) Since I don't know which PHP books are covering OOP well, I won't give you any advise. ;-) (I always found www.php.net sufficient, but I knew OOP already.) Or get a general idea from wikipedia: http://en.wikipedia.org/wiki/Object-...ed_programming That article contains a lot of usefull links, and will touch a lot OOP jargon. If you feel really brave, you can dive into some PEAR classes and see what they are doing. Just my 2 cent. Good luck. Regards, Erwin Moller > > Any good resources you would recommend? > > Thanks again! > > IBB |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
..oO(oh.i.love.spam@gmail.com)
>I've been a procedural PHPer for a while now and I don't know why it >has taken me so long to start the jump from procedural to OOP. I have >a function that I would use for doing length conversions... feet to >meters, inches to centimeters, etc... and I wanted to try and turn >that into a useful class just for some OOP practice, but I don't think >it was a very good start. Maybe it was a bad function to begin >with... but I'm not seeing how this class is of any more use if any >than the function was on its own. What are the advantages of turning >that into a class and how could I improve it to make it better? > >################################# >## Original conv function >################################# > function conv($val, $lenFrom, $lenTo) { > switch ($lenFrom) { > case 'm': > $m = $val * 1; > $cm = $val * 100; > $mm = $val * 1000; >[...] As already mentioned you should store such values in an array, which would also make it much easier to add new units. Additionally you can improve the entire algorithm by first converting the $from unit to meters, then in a second step to the $to unit. This way you don't have to hard-code all possible conversions, but can do both calculations with a single simple lookup array, e.g. function conv($val, $from, $to) { $factors = array( 'km' => 1000, 'm' => 1, 'ft' => 0.3048, 'dm' => 0.1, 'in' => 0.0254, 'cm' => 0.01, 'mm' => 0.001 ); return isset($factors[$from]) && isset($factors[$to]) ? $val * $factors[$from] / $factors[$to] : NULL; } Turning this single function into a class doesn't make much sense IMHO, but it could be part of a more generic conversion class for example, also supporting weights and such. Micha |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Erwin Moller wrote:
> oh.i.love.spam@gmail.com schreef: >> Good info guys... thanks! I've no idea when to make something public >> or private or static or protected. I need to find a good book/ >> resource on just OOP in general and theory I think. I've got a couple >> of general beginner tuts that I'm sure will get me to a point... they >> give a lot of the "how" but not necessarily the "why". > > Hi, > > Many Java programmers had the opinion that *ALL* variables in your class > (which are called 'members' then) should be private. In the case you > want the user of that object to change them, expose a getter/setter > method for it. > But you'll easily find others who disagree and say all the getter/setter > methods are a pain and unneeded noise brought to you by the Code Mafia. > Why make a member private if you expose it again with a getter/setter > method? There is a reason that's very important for this: tracing & validating and listeners. While I don't make everything private, most of them are, certainly if I need to validate them (throw exceptions on errors), and the ability to deploy listeners to trace certain problems (add observer to object, an change report where which change came from etc.). Not needed for small projects, but for bigger ones with a lot of interaction it's not only wise, it saves a terrible amount of time while bughunting. Another advantage is of course making a variable read-only: reading is possible, altering isn't. If not working with getters & setters, and you need a read-only variable, the only other option is to use a method rather then a variable, in which case you might as well code a getter (and possible exception throwing setter). -- Rik Wasmus ....spamrun finished |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
oh.i.love.spam@gmail.com wrote:
> Good info guys... thanks! I've no idea when to make something public > or private or static or protected. I need to find a good book/ > resource on just OOP in general and theory I think. I've got a couple > of general beginner tuts that I'm sure will get me to a point... they > give a lot of the "how" but not necessarily the "why". > > Any good resources you would recommend? > > Thanks again! > > IBB > I tend to make almost all of my variables private, with get and set functions for them. The set function returns true or false, depending on the validation of the parameter. Now maybe every variable doesn't need validation *now*, but who knows in the future? Making the value private allows for expansion when things change. The whole idea of OO is to separate the interface. The interface is what's publicly available, typically public methods(functions). The implementation includes the private/protected variables and the code in the methods. Once you've published the class, you can't change the interface (except to add to it) without potentially breaking code. But you can change the implementation as much as you want, as long as the interface performs the same functions (as seen externally) and returns the same value(s). It's a little harder to code and very slightly slower, but much more manageable in the long run. A floating point number could be considered a good example of an object. Internally, it is stored as base and mantissa. But you don't access that information; rather you perform operations such as add, subtract, print, etc. on it. If you change to another processor which uses a different method of storing the number (i.e. a mainframe with a real binary coded decimal feature), your code doesn't change. And neither do the results (except for rounding errors). An example I did not too long ago. Customer needed a small program to keep track of a few names/addresses (a couple of dozen). Unfortunately, the (free) server they were on didn't have MySQL available, and the needs were minimal - mainly be able to update and display the information. So I implemented it as a CSV file using a database class. Later, when they changed to a real hosting company with MySQL, I changed the database object to use MySQL. The class had to be rewritten (not that much, really), but the rest of the code didn't change at all. And I could change the database class to use PostGresSQL, SQL Server or any of a number of different methods. The rest of the code on the web site, no matter how much it was, didn't change. -- ================== Remove the "x" from my email address Jerry Stuckle JDS Computer Training Corp. jstucklex@attglobal.net ================== |
|
![]() |
| Outils de la discussion | |
|
|