Page 1 of 2

OOP General Question

Posted: Thu Jul 28, 2005 11:32 am
by Ree
after trying some things out with PHP, i decided to have a look at OOP using PHP and actually have a question regarding the same.

first of all, i should say i am currently studying software engineering in university and i do understand the OOP principle (is this called 'paradigm'?). we had Java and C/C++ and basically it was mainly OO programming. as you have probably guessed, i mainly did pretty simple tasks which included declaring classes and using objects with their methods. now there i do understand: you have a class, and you can create multiple objects different in some ways but of the same class (for example painting circles of different radius on the screen). i also understand polymorphism, encapsulation terms as well as OOP advantage of testing.

having tried purely procedural code in php, i now wonder how and why i could/should use classes in pretty simple ('everyday') websites the most sophisticated elements of which could be online registration, newsletter management and a product db? i have read an example of OOP with PHP which presented a use of a class to display fixed amount of records per page. well yeah, it's nice, but... couldn't i do the same with simple functions and include them where needed? i mean, why would i want a class with one instance only? for me it's a bit difficult to grasp where i could have a use of OOP with PHP in rather simple projects.

i would really like to know your opinion on this as well as a few useful examples if possible, as it will help me to get a better idea of how i could use OOP with PHP. the more info you can provide, the better. :)

Posted: Thu Jul 28, 2005 11:41 am
by nielsene
Well the biggest benefit, in my mind, for OOP on "simple" PHP projects is easier ability to re-use the utility classes you'll develop. There are a lot of shared functionalities on websites of all kinds, have your own set of useful classes makes starting a new project much easier.

While you can re-use pure procedural code, its often turns into cut-n-paste messes where you need to remember to change some variables names around, etc and its easy (for some people, like myself) to miss a few places, etc.

Plus when your simple website suddenly becomes less simple, your in a better building-off point if its OOP-ified.

Posted: Thu Jul 28, 2005 12:49 pm
by Ambush Commander
I cannot emphasize that enough. Last year, when I started programming PHP, I was coding everything procedurally because I didn't know any better (Classes? What classes?). We had this longstanding problem displaying text files, so I created a simple PHP script to take a txt file, do some parsing, and then display it.

Then, I realized that I needed to display the author name and story name and stuff inside the document. So I created a metadata system. All procedural. I got this premade guestbook script off the web. It was procedural. I modified it so it would work with multiple stories, and that was more procedural code. Everything was procedural, procedural, procedural.

And then, I saw the light. And now I have to rewrite everything into objects. Very easy to go from simple -> complicated.

Same thing happened with my localhost homepage. Originally, it was just going to be a few links and stuff. Then I decided a Wikipedia recent changes list on my homepage, prefetched and stuff, would be nice. So would a fetch from a Symantec page. All procedural, with a little OOP because I was learning about that at the time. Then, when I was porting my heavily procedural Megatokyo updater, I decided to revamp all the objects and now it would be very easy to add another updater to my homepage.

Posted: Thu Jul 28, 2005 1:27 pm
by McGruff
It's very easy to get in a mess when you're programming. Any lack of clarity is fatal. In OOP, wrapping up data with methods which act upon the data isolates cohesive chunks of the application. Unlike computers, our poor brains can only concentrate on one thing at a time. That's what it's all about really. The computer doesn't care what you feed it as long as it parses.

A decent OOP design should bring all the different threads in an app sharply into focus. Functions are a start in the battle against spaghetti code but the drive to separate out different resposibilities inevitably leads to OOP. It's much easier to wrap the data up with the methods which act upon it rather than trying to pass data around to functions.

It's kind of like the song:

"Well the hip bone's connected to the thigh bone
and the thigh bone's connected to the foot bone
..etc

In OOP that goes:

"Well the hip bone's a cohesive unit with low coupling to other skeletal parts so we can rip it out and fit a new nuclear-powered, titanium leg (implementing the hip interface) without affecting the rest of the body.

This makes an application much easier to maintain. Crucially, it's also easier to test. I don't want a new leg unless it's been properly tested, nuclear-powered or not.

Polymorphism is kind of hard, procedurally. Also, would there be some parallel way to do test-driven-design in procedural code?

Posted: Thu Jul 28, 2005 1:43 pm
by Ambush Commander
Functions maybe. Procedural? A hopelessly complicated mix of output buffering and variable sniffing.

Posted: Thu Jul 28, 2005 3:15 pm
by Ree
Ambush Commander wrote:Functions maybe. Procedural? A hopelessly complicated mix of output buffering and variable sniffing.
am i using the wrong term here? i thought 'procedural programming' (term) involved using functions... :oops: i should have used 'functional programming' instead since i of course use functions (actually i can't imagine how one could do anything without them?).

anyways, thanks for your replies. so, if i understand it correctly, it may be useful to create a class just to work with some kind of data, right? are there any guidelines on how extensive a class should be (i mean, is it ok if a class is huge with, say, 30 methods)?

actually, i'm still having a difficulty to determine how i should make a class for a simple website (or, better said, what it could consist of). maybe a class to work with user records (add, delete, edit)? i see i lack a few exmples of where a class could be used...

Posted: Thu Jul 28, 2005 4:02 pm
by Roja
McGruff wrote:Also, would there be some parallel way to do test-driven-design in procedural code?
Absolutely.. in fact, its very similar to OOP's.

You make a test (given these inputs, the function should produce this output).

Then you make a function that fulfills those requirements. Once you are done, you will likely realize the test was too simple/limited, and you'll write a better test. Then you make a function..

You get the idea. Granted, thats functional code, but the same thing could be said for a file of procedural code too.. the test checks starting conditions and ending conditions for a given page.

Posted: Thu Jul 28, 2005 7:07 pm
by McGruff
But TDD isn't really about testing: it's a design tool. As you implement one class you might "discover" other responsibilities which don't really fit in the class you're working on. These are encapsulated in mock objects. In a mock, you'd create the interface you want then come back and write an implementation later. Thus the design ripples out from the point at which you started, evolving naturally rather than big upfront design.

I might well have missed something obvious but I can't see what the procedural equivalent of a mock object would be. A mock function?

Posted: Thu Jul 28, 2005 7:44 pm
by nielsene
Ree wrote:
Ambush Commander wrote:Functions maybe. Procedural? A hopelessly complicated mix of output buffering and variable sniffing.
am i using the wrong term here? i thought 'procedural programming' (term) involved using functions... :oops: i should have used 'functional programming' instead since i of course use functions (actually i can't imagine how one could do anything without them?).
Actually "procedural programming" was the correct term for the style of programming that
organizes its code into functions and treats data as secondary. "Functional Programming" is a VERY different beast, much more mathmatical. FP is not something most people get experience with as most programming languagess are setup for it. Haskell is one of the more common ones; Prolog is also somewhat of a functional programming paradigm language. Lisp can do it too.

Functional Programming is all about pattern matching in one sense. For instancce this would be the defination of factorial in Haskell (might be slightly wrong, haven't touched it in years):

Code: Select all

Factorialї0]=1
Factorialї1]=1
FactorialїN]=N*FactorialїN-1]
That's it. When given a function call, it tries to match to a left-hand side. Replacing the function call with the first RHS that matches and iterating until there are no more function calls.

Posted: Thu Jul 28, 2005 9:15 pm
by timvw
Ssssssst, i remember the pain from lambda calculus...

Posted: Thu Jul 28, 2005 9:49 pm
by nielsene
timvw wrote:Ssssssst, i remember the pain from lambda calculus...
I wish there were a good general purpose languange with it.... Its so useful... Python at times comes close for me, but nothing feels as "pure" as Scheme to me, but I've never had success with real projects in it....

Posted: Thu Jul 28, 2005 10:22 pm
by Roja
McGruff wrote:But TDD isn't really about testing: it's a design tool. As you implement one class you might "discover" other responsibilities which don't really fit in the class you're working on.
Thats part of the process I described - "you will likely realize the test was too simple/limited, and you'll write a better test".
McGruff wrote: These are encapsulated in mock objects. In a mock, you'd create the interface you want then come back and write an implementation later. Thus the design ripples out from the point at which you started, evolving naturally rather than big upfront design.
Right, the same accomplished goals, with one slight difference..
McGruff wrote:I might well have missed something obvious but I can't see what the procedural equivalent of a mock object would be. A mock function?
Mock objects are definitely a different creature than a mock function.

If my test requires that function foo() returns 2 from params 1,1, then I can make the mock function as simple as echo $param[1]+$param[2]).

However, thats substantially different from a mock *object* (not method) that has defined properties. Functions have inputs and outputs and are generally data-ignorant, while objects and classes tightly couple data with behavior (with many advantages).

Keep in mind that while I'm familiar with OOP and TDD, and have several books on them, I'm hardly the right person to speak to "What OOP & TDD is", I'm just making the point that yes, you can do a form of TDD with functions, although the flavor is certainly different, and there are some disadvantages.

Posted: Fri Jul 29, 2005 1:18 pm
by Ree
actually, i'm still having a difficulty to determine how i should make a class for a simple website (or, better said, what it could consist of). maybe a class to work with user records (add, delete, edit)? i see i lack a few exmples of where a class could be used...
it would help me a lot if you could provide me with a few class examples. what could a class be? db connection/query processing? user record management? what classes do you use and what they do?

Posted: Fri Jul 29, 2005 1:31 pm
by nielsene
Some rather "common" classes in most PHP projects:

Some sort of database abstraction layer, possibly from PEAR/ADODB,etc, or a small homegrown one.
This class (lets call it DB for now) often will have an interface like:
DB->connect($host, $db, $user, $pass);
DB->query($queryString);
DB->getError() // some people put it in the DB some in the ResultSet to be shown next)

ResultSet: some sort of object wrapper around the returned values from the DB. Again this could be home grown or re-used from PEAR.
The exact interface for these often follows an Iterator pattern, but doesn't have to. Here's one fairly common set of functions:
ResultSet->getNext()
ResultSet->numRows()
ResultSet->gotoStart()
ResultSet->release()

Some sort of HTML-Generators: A class/collection of classes that format domain objects/lists into webpages components. Depending on your tastes this can be a huge hierarchy of Composite patterns to implement each HTML tag as an object; or a higher level abstraction. I tend to use the latter and have things like
Display->beginPage($title);
Display->endPage()
Display->addTextBox($box);
Display->wrapForm($form,$action,$method);

With a helper Form class that has
Form->addTextField($name,$value,$message,$label,$size);
Form->addPasswordField...
Form->addSelect...
...

Now the "guts" of your application are your domain model. Ie classes that you need that work on your actual data and normal operations. These we can't give you examples of easily.

Posted: Fri Jul 29, 2005 1:39 pm
by McGruff
Ree wrote:actually, i'm still having a difficulty to determine how i should make a class for a simple website
The general answer is write a class for each discrete responsibility. Objects should have high cohesion and low coupling http://c2.com/cgi/wiki?CouplingAndCohesion. A class should as a rule do just one thing. Don't be afraid to write them by the dozen for a single script.