The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

I don't believe in the "some people think procedurally, and some think in OO" thing. The me that's a load of bull. Before I coded in OOP about 15-18 months ago, I used to do everything in functions, and like wise I came from a background of using BASIC on Amstrads / C64 and DOS for a few years when i started getting into programming before I moved to PHP.

I have just found it is more natural to model things in OOP. It is a lot easier to make abstractions in OOP. At the end of the day, as humans, our thinking process generally works by making abstractions / simplifications, where different concepts are "layered" on top of each other, and each concept only really knows about the concepts surrounding it. That's probably wasn't explained too well, but look at the OSI Model used in networking. Each layer in this model has a group of related concepts. The Session Layer only knows how the Transport layer works, and the transport layer only knows how the Network layer works etc. There is no way the Session or Application layer knows how to directly communicate with the Physical layer. As Marcus said things change in the (business) models that our programs are synthesising. When these changes occur, we want to do the least amount of work to accommodate for these changes we need to make. Abstractions in the way things work enable us to do this. In OO, one can achieve this be reducing the coupling between classes by making each class have one specific role. In Procedural programming, being able to something similar is a lot harder, and requires more discipline imo.

The same sort of principles apply to almost any other model (non computing related in life). Electrical Engineering is another place where this applies, where this can apply. When writing a program it is natural to take this approach where things are layered in a similar way. This is just how the human mind works at the end of the day... as humans we need break problems down into smaller problems in order to solve them. Going back to something like electrical engineering, you never see someone just come up with a design for making a new processor. The task is split into smaller problem segments (I.e. How the ALU, FPU, Cache, etc work), and delegated off to other people. The people designing the FPU might further more split up the problem and delegate the task off etc etc. This model of splitting tasks up and delegating them off to objects that specialise in that area of knowledge / domain based on responsibility is common to moreless everything in the world. As programmers it is our task to model solutions to real world situations normally, and OO is the natural way to do it, because that is the way the world works.

I think part of the problem is the niche where PHP is located: web applications.

Probably a signification number of web applications are simple enough that you can "get away" with a procedural approach. As josheli alluded to, you can make quite a number of simplifying assumptions, i.e I am going to use MySQL and I am never going to change, therefore I will just hard code the PHP MySQL functions directly into my code.

Where OO begins to shine is where Marcus (lastcraft) began to talk about: complex business requirements that are subject to change over the lifetime of the project.

If you do not have the expectation that your needs are going to shift out from under you, then perhaps the flexibility (and to some extent intellectual complexity) of an OO model may not be required for your project.

I'd go even further than this and say that the power of OOP provides an advantage at much lower levels. A class can have as many methods as you want. A function can only return once. This requires you to manage lots of variable passing since more variables are exposed.

I don't know how far the readability argument should be seen as one of style. Rather than reading through a big chunk of code a class provides a simple handle for it. You don't need to know how it does its job, just how to use it - perhaps only one or two method calls to learn. Also, unit tests are a big advantage in terms of the documentation they provide.

I think part of the problem is the niche where PHP is located: web applications.

Probably a signification number of web applications are simple enough that you can "get away" with a procedural approach. As josheli alluded to, you can make quite a number of simplifying assumptions, i.e I am going to use MySQL and I am never going to change, therefore I will just hard code the PHP MySQL functions directly into my code.

Where OO begins to shine is where Marcus (lastcraft) began to talk about: complex business requirements that are subject to change over the lifetime of the project.

If you do not have the expectation that your needs are going to shift out from under you, then perhaps the flexibility (and to some extent intellectual complexity) of an OO model may not be required for your project.

My $0.02, YMMV

Regards,

Totally agreed there, and for big projects OO pays off. One of our clients who we did a big project for doesn't use OOP. They constantly want changes made and it's a real PITA now. However for newer projects we are using OO and are working on a centralised framework round the common requirements of our projects (i.e. Implementation of the Query Object, DB Abstraction, template system to enable us to employ less skilled staff at some point, and a range of Image Functions, and other things that help search engine optimisation). Although it's a PITA atm because it's hard working on this framework without delaying some of our work, certain pairs are already paying off for repeative work and projects that have evolving requirements. Many smaller sites can be done without OO, and are OK (though I do find it harder now to work like this). However many projects we work on are much bigger, and code reuse is important when you have a client who wants a bespoke solution that needs to be developed rapidly, as well as be adaptable with little hassle

I'd go even further than this and say that the power of OOP provides an advantage at much lower levels. A class can have as many methods as you want. A function can only return once. This requires you to manage lots of variable passing since more variables are exposed.

I don't know how far the readability argument should be seen as one of style. Rather than reading through a big chunk of code a class provides a simple handle for it. You don't need to know how it does its job, just how to use it - perhaps only one or two method calls to learn. Also, unit tests are a big advantage in terms of the documentation they provide.

Exactly, as I was going with the naming examples in a previous post. One should be able to read code without having to look at different objects and understand how they work behind the scenes too much.

Unit tests also help from a reuse point of view. If you have lot of code that is used in a number of projects and you make updates to this code, Unit tests can be a way of ensuring updates to the code do not break anything that is already dependant on it.

actually, I think my biggest hinderance to fully embracing "OO" is not with the architecture or design or understanding, but with the veiled condescencion and self-righteous superiority of so many of its crusaders.

And you wouldn't want to start a flame war or anything . The OOers are enthusiastic. That said I can be condescending of the attitude that procedural works for me, I couldn't get OO to work, so OO must be crap. This certainly hasn't happened in this thread of course, but both sides of the divide can give this kind of thread a bad name. If we all keep our cool, forget about all those other nasty threads we have seen and steer a course towards genuine difficulty we could end up with a good thread.

Originally Posted by josheli

so which is it? where does the rubber meet the road, documentation or naming? "hopefully both" you'll say. gotcha.

There are no best practices with programming, only good practices. Some combinations of those good practices will be contradictory. BTW, when the Cynefin (http://www.cynefin.net/) project becomes operation I'll be able to put this statement into greater perspective.

Originally Posted by josheli

i find that the universe is inherently procedural. you know, the whole "if action then reaction" thing. an important claim for OO is that it helpfully maps our feeble human thought processes to some system. i tend to disagree.

Wrong problem space.

A lot of languages are heavily influenced by Fortran, a language built for producing very simple simulations of physical reality. Performance is critical for these simulations and they used to be run on minimal hardware, so complied Fortran and C are the norm.

Originally Posted by josheli

i just don't think that the Object model captures our thought process as well as is claimed. in the real world, we don't ask objects to perform actions or to tell us their state, we usually determine them at "runtime" (while driving, while cooking, etc.),

I think this is where your own argument loses coherence. Any physical object that does anything complicated, rather than simply be picked up and put down, more naturally follows OO. The cooker and the car you mention are good examples. You send a message to the cooker timer to start. You send a message to the cooker to start, or the car to start. The target of that message is important because the outcome will be different.

You are using a model of a central intelligence (us) manipulating the world. That is roughly OK for simply cooking in your kitchen, but falls down badly when handling an organisation of people, unless it's some George Orwell nightmare. With multiple agents you need a different model of reality.

Originally Posted by josheli

...and it ends up being a bunch of data containers and associated "Managers/Finders/Factories" (see, i do use OOP ).

If they ended up being data containers then I am afraid you didn't "use" OO, at least not to it's full potential. You are doing procedural programming with some bits of OO syntax to name data groups. That's still a start, but nothing like a breakthrough.

Now I get rather stuck here because I cannot think of a way of saying the next bit without sounding condescending. The next stage you go to will be to forget about the data and start thinking about behaviour only. Data and functions as separate is a procedural programmers controlling intelligence view of the world and takes about a year to get rid of. In saying this I am implying that I am simply one step ahead of you and if you follow me up the ladder, dear disciple, all will be fine. That's the condescending part I cannot work around.

My difficulty is because I do actually believe this .

The enthusiastic OOers notice this affect at gut level. As the data fades away their brains have less to struggle with. The code becomes more of a bunch of intelligent lumps, rather than tools to be brought to the data. A procedural programmer has to completely understand the data structures. Easy for small projects, impossible for large ones or ones that change frequently. Quietly freed from this yoke, the budding OOer is suddenly capable of taking on much deeper problems, but without really understanding what has changed.

I think that's why it isn't always expressed so well.

Originally Posted by josheli

debatable i think.

Yes, but I believe I can convince you that this is so in the area of enterprise applications.

Be careful not to identify yourself as a non-OOer. I have seen people actively avoid learning OO because they have boxed themselves in by nailing their own egos to a public viewpoint. Once you outgrow procedural, that will only leave relational as a career path. You have to wear a tie for that life .

Originally Posted by josheli

still, it's difficult to follow the bouncing ball.

The resolution of this is to use the encapsulation in combination with good naming so atht you don't have to follow the ball at all. Again,you don't have to dig down to the data in the same way you do with procedural. Freed from this constraint, life gets easier.

The catch is that OO is high discipline because of the naming and encapsulation care. Bad OO code can force you to trace code and the bouncing ball now makes things worse. This is partly why OO is usually peoples second paradigm. These disciplines are good for any programming and it takes a few years for them to become automatic enough that they don't present a barrier to moving toward OO.

Originally Posted by josheli

YAGNI is a revered wiki item in object land, yet much of OO design is centered around JICYMNI (Just In Case You Might Need It).

Reuse has given way to flex points and YAGNI is a reaction against the big design up front movement (this is not OO specific, e.g XML-RPC vs. SOAP). These movements are progressions. You wouldn't try to apply them all at the same time.

Originally Posted by josheli

indeed, isn't much of the touting of abstraction and encapsulation about making it easier to change/maintain related components in the future? but i thought i wasn't going to need it?

OO gives you the chance to add it in later when you do need it. It's no accident that refactoring has come from the OO camp. In exposing software development to the world of business it has to exist with an intrinsictly chaotic (in the mathematical sense) world. Plans survive only as long as the time it takes for competitors to adapt. The development team has to interface with this world, hence the rise of iterative processes so as to give the business options. Iterative development combined with a clean refactorable code base is what allows YAGNI to work. All of this is only now becoming mainstream. A lot of the other stuff is so last century .

Originally Posted by josheli

a final question:
is it standard practice to instantiate an object in order to just subsequently "delete" it?

As an OOP programmer I agree with you on the real benefits, but I have never really understood the "I am simply one step ahead of you" condescending part. I am a believer in all the positive qualities of OOP. However I think you guys get so wrapped up in yourselves that you say things that make others think you can't see the forest for the trees.

- MiiJaySung rambles off about the OSI Model as if clear separation of layers and interfaces is a thing unique to OOP.

- McGruff fires off "A class can have as many methods as you want. A function can only return once" admittedly trying to make a valid point, but let's face it, that's not an apples to apples comparison and a library of functions with associated data structures has many of the same benefits.

- lastcraft makes many good points but slips in things like "It's no accident that refactoring has come from the OO camp" as if improving code without changing the interface is something that didn't exist before OOP gave it a fancy name.

You guys have a lot of good things to say and I have learned from all of you, but you seem to have a tin ear when it comes these converstations. It is too bad when people like josheli get to the unfortunate flame point. If only Fowler had a book "Charm School for Enterprise OOP."

A word that probably describes me very well. Probably coz I'm crap at english and therefore need 5x more lines of English than anyone else to get my point across.

</OFF_TOPIC>

I don't think it's case of us flaming at people. I don't think anyone is trying to slag some else off, it's just that people where are trying to argue a case and give reasoning. If our points are flowed in some way, I'm sure josheli and co will have some arguement to demonstrate flaws in our arguement and show his justificaton for it.

As an OOP programmer I agree with you on the real benefits, but I have never really understood the "I am simply one step ahead of you" condescending part.

If there's something you don't understand do ask - but please no more remarks about being condescending or having tin ears. If we can avoid name-calling its more likely that we'll have an interesting, informative discussion.

The point I possibly didn't make very well - and Lastcraft also touched on - is that functions do not have state. OK you can stick a bunch of stuff behind a function definition to "encapsulate" it but, since you don't have any state, you have the awkward problem of passing vars in and out all the time. It's better and simpler if you use classes.

At work I've got a lot of data to fix before getting busy with Quark for a product catalogue. One problem (of many) is that several different bits of data have been stored in the same database field. Hence this class:

PHP Code:

/*
CLASS StringCutter

Cut chunks out of a string using regex patterns.
Can make repeated cuts on the same target string.
The target string will remain unaffected.
Each cut removes a portion of (the internal copy of) the target string; the remainder can be obtained with the getRemainder() method. This could be used for example to check if the cuts have captured all data contained in the string.

/*
The class was written as part of a system to clean up user input where multiple bits of data had been stored in single fields. Multiple matches would mean the regex pattern has failed to identify a discrete data chunk; hence, an error is triggered if more than one match is found.
*/
function cut($regex)
{
$this->_num_matches = 0;
$this->cut = null;
if($string = preg_replace_callback($regex,
array(&$this, '_callback'),
$this->string))
{
$this->string = $string;
}
if($this->_num_matches > 1)
{
trigger_error($this->_num_matches_error);
return false;
}
return $this->cut;
}

You can't even do this procedurally - at least not with a single preg_replace_callback call. The callback function can only return once (and not the pattern match, obviously). With OOP, you can "observe" each callback execution to grab the match & etc. State gives you a whole new dimension to play with.

With OOP (and state) I can return a pattern match with each call to the cut() method and the class will automatically manage the $remainder from cut to cut. Procedurally, you would have to return the $remainder alongside the cut in an array, separate the two to get the bit you wanted, and then remember to pass the $remainder (not the original $string) back in for the next cut.

This is the sort of thing I meant when I said that you don't have to go all the way up to enterprise apps to find benefits from OOP: it starts very early, IMCO ("in my condescending opinion" ).

---
edit: I should read my own notes: there is no $remainder var: it's in $this->string

As an OOP programmer I agree with you on the real benefits, but I have never really understood the "I am simply one step ahead of you" condescending part.

I was trying to sidestep this, but couldn't figure out a nice way to do it (hence the warning). The thing is, all these confusions with OO are horribly familiar. I went through them too, and I see more developers pass through everyday with the same issues. I see no one who has finally passed through this stage to other side ever going back. Like I mean none, zilch, zip, nada. It's not meant to be condescending, it simply comes out that way because that is my own personal experience and my experience from coaching.

Now you can tell people's skill level from their comments and this isn't unexpected. When people say they are still using OO as data holders, or they cannot see how polymorphism will save them code, or how objects make refactoring easier or how a domain model is built, I can look at that and say that I have experienced these things. In that sense it does put me one step up this particular ladder. That's natural when everybody is at different stages in their various interests, and I would expect others to try to give me a leg up in areas where they know more than me.

I do try procedural sometimes (honest). In fact I try everytime I start writing what I think will be a simple script. It gets to 8 functions or so and suddenly I realise things are getting untidy and have to refactor to objects. I have never seen a need to move a short OO piece back into procedural.

Also, that some people think in procedural and some in objects I think is very wrong. I did procedural (C) for seven years and some assembly stuff before that. I have coded OO for only four at most. I haven't found the mind sets interfering in any way. It's just another mental tool to put into your toolbox.

Originally Posted by arborint

- lastcraft makes many good points but slips in things like "It's no accident that refactoring has come from the OO camp" as if improving code without changing the interface is something that didn't exist before OOP gave it a fancy name.

My cause and effect was more along the lines of OO being dominent in enterprise programming and the enterprise usually pays a premium for options. Thus there is a strong incentive for enterprise development to evolve more flexible delivery strategies.

Anyway I think your argument is a bit disengenious.

Giving refactoring a name is to recognise it's current prominence. After all the OO community has added nothing to the concept of phased delivery because that process does less to exploit the power of OO.

Also I have never seen before the strong move to view refactoring as a design technique, rather than a code tidying technique. Just because somebody shuffled a bit of code around in the past does not equate with treating refactoring as a development strategy and giving rise to YAGNI. Saying it has been done before is just not true in this case. Testing has been done before, but we have never had test driven development as a methodology until a couple of Smalltalkers got hold of it.

"There is nothing new under the sun" only if you cannot see the messy world of evolution.

Hard to know what to say, you guys are bitter enders. Even when I intentionally add things like "admittedly trying to make a valid point" and "makes many good points" you guys latch on and keep going. I fully acknowledge the benefits of encapsulation as well as the progress made in refactoring and testing by the OOP community. But: "You can't even do this procedurally" and all the pre-OOP thinking and work in an area reduced to "somebody shuffled a bit of code around in the past." Whew! Uncle!

Oh come on mate. I know Lastcraft to be a very intelligent and helpful guy. His contributions here are priceless. If you stick around long enough you'll learn that he's no bigot.

Neither, am I. Instead of the meta discussion about alleged egos/personality flaws how about we get technical. If you can show me how to return the pattern match from a callback as well as the replace value I'll be glad to take that back. As far as I know, you can only return once from a function...

A procedural version might make use of preg_split and preg_match_all. There's no great difference and I'd accept that this example is a bit of a special case. Still, it does I think help to illustrate the value of state.

I don't think either you or lastcraft are bigots in the least. I think you're both great and I have learned things from both of you. I agree that lastcraft's contributions are priceless. And as I said, your example clearly shows the the benefits of encapsulation.

No, my point is that for every nine things you guys say that is brilliant, you say one (like those I mentioned) that get people like josheli and your buddy iamsure's knickers in a twist. And they really aren't necessary because OOP sells itself quite well if you just don't piss people off.

i debated whether or not to even reply to this thread, as little positive usually ever comes from threads like this. partly this is due to having a 3 and a 5 year old tugging on my leg when i try to post ; partly it's due to the design and nature of this typical forum software: it encourages argumentative, line-by-line, point-by-point refutations of previous posts (Joel explained this to me). (And as an aside to this, have you ever noticed that no one is EVER wrong, it's always the other guy who's bonkers? The same is true also of code of course: the worst code in the world is the code the guy before you wrote. Oh, and why doesn't anyone ever admit that they just don't know what they're talking about? It's obvious I don't.)

Thirdly, once a month or so someone like me comes along and challenges the conventional wisdom of this board, and is summarily shot down. Sometimes the debate is drawn out (hi Tony!), usually not, but in all cases, neither side ever seems enlightened to even a portion of the other viewpoint.

Next, it benefits everyone if we don't assume the reader is an idiot. If you're on this forum, chances are you're intelligent and you know, for instance, "Classes are normally names of things that represent real world objects" and that "Real world objects interact with each other (i.e. Verbs)."

Finally, and worst of all, this sort of "procedural versus objects" debate is BORING.

But let me respond in general to a couple of points and raise a couple of new ones:

I do not identify myself as a non-OOer. I don't identify myself as a proceduralist either, though you probably do. It's just that, as I mentioned above, the nature of the forum is for someone to make a statement, have it shouted down, and then everyone gets defensive. Defending your own viewpoint, even if you don't totally agree, is a hard thing to avoid.

The last few chapters of Code Complete (on personal character, religion in software, domain abstractions) explains much better than I can the issues I've been thinking about.

I've realized that I've merely been using objects mostly as data containers. While I code, I keep thinking: "It'd be much easier if i just decomposed these objects into associative arrays and functions."

I guess Marcus is right and I don't know how to take the next step and express the problem in the domain language, because for one, the domain language is different every week. So I always get stuck and revert to well-named functions and arrays.

the nature of my job is such that I need to produce working code quickly (not exactly unique). I deal almost entirely in small projects. I'm the sole developer on a fairly large governmental site (half a million visitors a month) that consists of around 30+ "web applications" which range from 2 page surveys to departmental hours entry systems to a multi-user, 20,000 line calls and letters tracking system. I put a new application into production, on average, twice a month. This turnover has lead me on a concerted search for anything that will reduce complexity, development time, repetition, etc. I don't care if it's OO or BS. Indeed, I wouldn't be on this forum if i didn't expect to learn useful things.

Marcus, I often wonder why you are so committed to PHP. it seems that a programming language is for you a mere implementation detail, and there would seem to be better tools than PHP for implementing object oriented systems.

well, i had more to say, but it was mostly about me and my phproblems, and i was boring even myself.

I've realized that I've merely been using objects mostly as data containers. While I code, I keep thinking: "It'd be much easier if i just decomposed these objects into associative arrays and functions."

This is where people often go wrong with OO, imo. A lot of OO newbies to me tend to make this mistake, where they use a class to handle everything related to a piece of data. Classes should be designed on a role / responsiblity basis. At the end of the day the formation/format of data in each project will change a lot, and you won't get that much reuse. On the other hand classes with specific roles can be reused a lot. Look at things like Recursive iterators in the SPL, they can be used many times in different projects and have no dependancy on kind of data you use, as long as your data needs some form of iteration (and that is in a tree structure or something similar in this case), then you can use the RecursiveIteratorIterator.

Marcus, I often wonder why you are so committed to PHP. it seems that a programming language is for you a mere implementation detail, and there would seem to be better tools than PHP for implementing object oriented systems.

I am not committed to PHP and PHP is only one language I use. I like it mainly because of the community, one of small companies.

What I like about PHP is that it is geared toward web development and text processing, whilst being a good deal less messy than Perl. The language is reaonably concise whilst still being readable by a wide variety of people. It is possible to throw up prototypes quickly as well as develop medium scale applications. It's a great glue language with both a shell execution (now with pipes) and a C interface. PHP pretty much talks to everything if you don't count enterprise messaging systems. And it has sufficient OO capabilities to grow the application as it gains complexity. It's a great fit with agile methods and PHP has a lot of secret converts in high places here.

It's also democratised the web for small inovators/companies because of the low barrier to entry. This makes the applications developed with PHP surprisingly cutting edge. Because most programming texts are written by big name enterprise developers, you would have thought that Java (and the clone that is C#) was the only game in town. PHP demonstrates that it is the applications, not just the frameworks and structures, that make a community interesting. Small is beautiful if you like.

And things are starting to get interesting...

At the moment the average PHPer is not very productive in the grand scale of things. Lot's of small idea apps. that cannot be combined very well. Very little in the way of small coherent classes, but lot's of packages. All of this is holding up PHP, because we get far too many duplicate applications. Not because the applications are not visually customisable, they are, but because they cannot be pulled apart to make other apps. The community has bogged itself down redoing each others work.

For example I am using WordPress. I managed to customise the front end, but as soon as I tried to change simple logic (such as stripping popups) it started to turn into a major exercise. Too much to justify my time. What I want is a blog class library or highly factored app., then I can write whatever front end I want. Ismo was an attempt at this. This would really leverage PHP because it is so easy to write your own front ends and everyone knows how to do it. I could then grab a spam blocking class or two and blend them into my blog. Easy because I write the app. myself. I don't want plug-ins, because they are framwork dependent. I want classes because my framework is PHP scripts; the most flexible framework of all.

It's just starting to change. The PHP community is starting to grow up and develop more variety. I am sure it will now go through an overdesign phase, RecursiveIteratorIterator being a good example of something completely ridiculous . Once we have the reaction to that I think things will start to kick off.

Ruby is an interesting contrast. It has a very elite community from the enterprise Java world. Lot's of libraries right now, few applications. It currently lacks the volume of PHP, but it doesn't need as much and it's growing. The Ruby community is an example of one doing a lot with much fewer resources. Ruby is an area of interest for me .

this is the essence of my work and i'd like to move away from it. show me how.

for example, i generate reports/output in the following formats: HTML, text, Excel, PDF, Access, Word Perfect, XML. Sometimes an application generates all formats; sometimes the data is the same for each format; sometimes the data for one format is a subset of another report.

what i currently do usually boils down to some form of this psuedocode:

At the moment the average PHPer is not very productive in the grand scale of things. Lot's of small idea apps. that cannot be combined very well. Very little in the way of small coherent classes, but lot's of packages. All of this is holding up PHP, because we get far too many duplicate applications.

This is one of the main advantages I find with .Net. It's not just a langauge like php or perl or java and so on - it's an extensive and mature framework with massive libraries for both front and back end, data access, as well as an IDE that is very powerful and speeds development. It's designed well so that even a novice will mess up less often (for example, it seperates logic and display in asp.net so that you would go against convention to mix them).

Sure, in php you have the option to use different IDE's or different data access modules, or make your own templating engine, and so on. But the problem with this is that everyone re-invents the wheel and little progress is made. It would be nice to see a single mature framework including a data access module, IDE, templating engine, etc .... all which are very mature and can speed development.

And as marcus said, many of the php products are written poorly without encapsulation, so it is quite hard to merge these products into your application.

I think the problem is similar the the VB problem from years ago. VB was made so easy to use that any man or his dog could use it - even with little or no programming/development experience. As a consequence, many novices did use it and with no idea about making their products maintainable. In the same way, php is also extremely easy to get something working (which php owes its popularity to), and as a consequence, php has enourmous amounts of code out there that was produced by people getting their products simply to work - and unfortunantly are unmaintainable. On top of this, people learnt to code the same way by seeing this dodgy code - becuase that's how we learn, by example.

So while it is very nice that it is easy to accomplish things in php (and VB alike), I think that has been a double edged sword and caused problems.

It sounds like a cop out, but I would need way more information. Also you are about to enter an area called knowledge crunching. That involves sorting out what parts are the same in each app. and what parts change often within the app. (parameters) and between apps. (flex points).

If you are building reports, are they mostly tabular data? Categories and subcategories with listings? How would you describe a typical report in words?

There are lot's of possible ways to re-express your psuedo code. Here is one...

Your first example had all of the application decisions hidden. What I am trying to do is to make these visible without exposing their implementation. Here are the design decisions in this (completely untrustworthy and off the cuff) first go...

You want to be able to assemble reports in some kind of language with verbs such as setTitle and addTable. You probably want to add sub sections later (Composite pattern).

Adding elements means declaring their sources of information. To build the table I am using a database stored procedure wrapped up in an object. I guess it returns a Table object of some sort. Note that the StoredProcedure object exposes the parameters to the application as these are likely to change a lot. I can imagine a daily report needing to have a more useful start time than the exact second the program was run for example.

We want to choose the rendering method and so again we make the target a flex point (here a Visitor pattern). I would suspect that there are various template families associated with each output format depending on style considerations. I am assuming then that the EmailStyle class (AbstractFactory pattern) can create the templates for tables, titles, etc.

Your application concerns will be different for sure as I am only guessing.

What I am hinting at is look for what is common across applications and so make these the classes that will make up the toolset. The language you will work with basically. Look for what changes across applications and promote that to the application or script level. As you refactor it's a bit like bubbles rising to the surface.

I realise that I am tapping into a huge area here and it's not going to be easy to discover the best design overnight. There will be false starts and restarts. The main thing is that things should get easier with each application.

Am I giving a hint at both the direction and the enormity of what's involved?

It is interesting to comments about solving problems commons to many applications and problems specific to an application.

lastcraft notes the "the direction and the enormity of what's involved." The goal of turning "what is common across applications" into reusable code and leaving "what changes across applications" in each program is a very old programming idea. Identifying what is common and what changes is often (but not always) clear to the programmer. It is the task of creating a really good, reusable "toolset" is the enormous part.

On the solving problems common to many applications front there may be more hope in PHP. lazy_yogi notes how .NET's standard framework makes the programmer's life easier. What I'm looking for is a way to solve the "Lot's of small idea apps. that cannot be combined very well." problem. However, "data access module, IDE, templating engine, etc." are not what I am looking for as a start. If there was, at least, some agreement on a FrontController/PageController and the Security,Access Control parts then the other blanks could start to be filled in.

Am I giving a hint at both the direction and the enormity of what's involved?

quite. the enormity was already apparent, and is one reason i've been avoiding going down that path. it's easier to just "make it work" and worry later about the elegance, reuse, maintainability, etc.

As to the direction, honestly I don't even know where to start, and the prospect seems daunting. (i wish we would hire another developer, preferrably smarter than me, so one of us could focus on just these issues.)

It sounds like a cop out, but I would need way more information.

ok, if you're up to it, here's an actual example: one application tracks "public correspondences". a correspondence is: a phone call, written letter, online form submission, email (all either ingoing or outgoing). we get a few thousand correspondences a week. a team of about 15 employees handles these correspondences. the information recorded includes the time of correspondence, the person's contact info, the method of correspondence, reason for contacting us, our response, internal notes on our reponse... (about 50 items total).

the system produce reports (in HTML and Excel) on the number of correspondences handled per employee per arbitrary time period (Oct. 21-Nov. 8), broken down by issue (complaint, company fraud, consumer issue, etc.). another report is a Word Perfect document listing all contact information for all correspondences concerning a certain issue during an arbitrary time period. another report would be a PDF dump for the public of all their correspondences with us. there are a dozen other reports. some are run by batch job, some are run manually through the browser. in most cases the logic looks like this:

should the Report class really know how to calculate employee productivity? should the Report class be validating the criteria? what if i want a version where the user only needs to see half the fields in the report, do i subclass or add a setFieldsToSee() method? what if a Super User can see fields 1,3,5 but an administrator can see all fields? should the Report know about prompting a download in a browser, or writing to a file, or emailing the report? the list is endless.

the idea of commonality among applications brings up another problem. each application is its own private Idaho, but i try to reuse as much of a single code base among all the 35+ applications as i can. so for instance i have a "common" shared directory with things like authentication, db access, form validation/generators, templating, etc. So let's say i create this first version of the Reporting infrastructure and use it in application #36 and #37, then refactor and use for application #38, and refactor a little bit for each successive application. on each refactoring, i have to go back to previous applications and alter the application interface to match the new Reporting version. either that or I maintain multiple versions of the Reporting classes, or worse, multiple instances of multiple versions local to each application. i really don't have the resources to do that (not to mention my boss would be livid for me "fixing" a "working" application). any ideas?

...it's easier to just "make it work" and worry later about the elegance, reuse, maintainability, etc.

That way lies burn out. You have to buy some amount of refactoring time even if it's only 10% of your total ltime. Otherwise you are leaving an unmaintainable code base behind which won't do the business any good anyway. They aren't hiring a slave, they are hiring a professional. You have to exercise your professional judgement when it comes to the quality of your work. Unfortunately explaining this to management when they are inexperienced with software development is a struggle. It's bad enough in the role of consultant (they take more notice when you charge 60 quid an hour).

You have to explain that the extra investment will reduce risk (when you leave there will be less code for the next person to learn) and lead to greater productivity long term. Management understand "risk", "options", "training costs" and "underinvestment".

The main thing is that they should never be able to tell you how long a task should take. They set scope and can make noises about quality (something they won't understand with respect to software) and can allocate more resources. You always say how long something will take and you don't even commit to that because it's an estimate.

Originally Posted by josheli

As to the direction, honestly I don't even know where to start, and the prospect seems daunting. (i wish we would hire another developer, preferrably smarter than me, so one of us could focus on just these issues.)

It won't be that bad if you face up to it being a gradual task over the course of a year. Even at 3 hours a week, that's a lot of design time. The trick is not to sign off on a task until you are happy with it. Not just working, but working better than the last one even if only slightly.

Originally Posted by josheli

... (about 50 items total).

This is all in the database, right. What is the current schema for this? Do you control that schema?

Originally Posted by josheli

the system produce reports (in HTML and Excel) on the number of correspondences handled per employee per arbitrary time period (Oct. 21-Nov. 8),

All of this can be done on the query side. Let's say that we give this query a class...

The plan is to move all of the stuff that is specific to retrieving the data for a report into just that one class. This is nothing complicated. The EmployeeProductivity class is just a glorified wrapper for the SQL query. All we are doing is making sure that enough information is returned (the types) so that the data can be displayed without knowing anything about where it came from.

The Table class is generic. You will only have to write it once. The Field classes are simply data holders that know how to display themselves. Simple for an integer, but you could also have MoneyField and DateField an deven subtypes of these. The main thing is that the report will only have to call asString() on each column without having to worry about all of that.

This means that the Report class can be left to focus only on display issues and will eventually be able to work with any type of data. Ideally we want to only write a single Report class for every type of report.

Originally Posted by josheli

broken down by issue (complaint, company fraud, consumer issue, etc.).

One step at a time. Just create a class for each of these.

Originally Posted by josheli

another report is a Word Perfect document listing all contact information for all correspondences concerning a certain issue during an arbitrary time period.

Ignore the Word Perfect part for the moment. Get the query class set up so that it returns the correct table. I'll deal with the formatting next.

Originally Posted by josheli

another report would be a PDF dump for the public of all their correspondences with us. there are a dozen other reports. some are run by batch job, some are run manually through the browser. in most cases the logic looks like this:

Well you only have to write a constructor and some simple declarative methods for each. that's lot's of very small classes right?

Basically there is nothing report specific in this code, it's all generic.

Originally Posted by josheli

should the Report class really know how to calculate employee productivity?

No. For this you need a decorator (a pattern) around the Table. the decorator would fiddle withthe rows as they pass through, adding additional columns, etc. Are you familiar with the decorator pattern?

Originally Posted by josheli

should the Report class be validating the criteria?

Do taht in the top level script, the one that assembled the report object.

Originally Posted by josheli

what if i want a version where the user only needs to see half the fields in the report, do i subclass or add a setFieldsToSee() method?

Either write another query class or write another decorator. The decorator is less work long term.

Originally Posted by josheli

what if a Super User can see fields 1,3,5 but an administrator can see all fields?

Either a different query class or a decorator again. I think I would go for a different query class in this case as there are likely to be other issues.

Originally Posted by josheli

should the Report know about prompting a download in a browser, or writing to a file, or emailing the report? the list is endless.

They are just different types of Writer classes. All they have to do is print something when the Report send them an event.

Originally Posted by josheli

the idea of commonality among applications brings up another problem. each application is its own private Idaho, but i try to reuse as much of a single code base among all the 35+ applications as i can.

Thirty five !

Ok, what is the churn rate on this code? That is how often are each of these legacy reports changed?

Originally Posted by josheli

i have to go back to previous applications and alter the application interface to match the new Reporting version. either that or I maintain multiple versions of the Reporting classes, or worse, multiple instances of multiple versions local to each application. i really don't have the resources to do that (not to mention my boss would be livid for me "fixing" a "working" application). any ideas?.

You have to treat each one as a tactical decision. If a report is likely to be heavily maintained then you will definitely want to keep it in sync. Regarding backporting, that's tactical too. Hopefully pretty soon you will be writing a lot less code and that may free up some time to tackle the backlog. Otherwise do it on need.

Don't forget that a lot of the time when you add some functionality to the Reporting/Writer side of things that will become available to the other reports. Sweeping changes that would have been a nightmare before should become easier. Hopefully you will win overall...

Now I am coding at a distance here, so everything I say may be completely wrong. Does any of this resonate with your current predicament.

Ok, what is the churn rate on this code? That is how often are each of these legacy reports changed?

i'm sorry, i didn't make myself clear. this one application (Public Correspondences) contains a dozen reports. in addition to this "Public Correspondences" application, i maintain 35 other applications such as a mailing list manager, hours tracking system, etc. Each of those applications uses a fair amount of shared code, and each of those 35 applications usually contains a reporting component. i'm tasked with creating a new application a couple times per month. so if i share the Reporting infrastructure among applications, that's a lot of backporting, synching, changing.

at any rate, the churn rate on the reports and the applications is pretty low. once they're working, they're not altered that often.

Are you familiar with the decorator pattern?

i've read about it, seen it discussed, possibly even used it unknowingly.

Does any of this resonate with your current predicament.

sure, when you have a stab at it, Bob's your uncle, but when i get a couple of iterations in, i can't see the forrest for the trees.

so, as devil's advocate, assuming i go down this OO route, what will it buy me that some glue code, some functions and a few classes won't?

on each refactoring, i have to go back to previous applications and alter the application interface to match the new Reporting version. either that or I maintain multiple versions of the Reporting classes, or worse, multiple instances of multiple versions local to each application. i really don't have the resources to do that (not to mention my boss would be livid for me "fixing" a "working" application). any ideas?

I have this problem as well and solve it with versioning, documentation, tools and testing. I give a new version number to every revision of the common libraries that breaks backward compatability and document how migrate from one version to the next. Then I write tools to automate the migration as much as possible. In my case these are usually shell scripts that automate VIM because that just works for me. As a practical matter I often have to also document/automate jumps of several version because I find that apps tend clump around certain versions. Finally any kind of automated testing you can do. I've never had the luxury of "they should never be able to tell you how long a task should take" or "don't even commit to that because it's an estimate."

The course lastcraft plots is a solid one. And he makes it wonderfully concrete when seen from the other side. I use a similar approach with a similar implementation. I have seen moving to OOP lead to great satifaction, but I have also seen it lead to pain and retreat. I would recommend starting with a reasonably isolated subsystem. You will need to maintain old and new codebases for a while until you reach a point where the OOP implementation starts to make you happy.

I think it's funny that I just wrote "make you happy," but I've come think of refactoring as little intellectual presents a programmer can give to her/himself to keep the job of programming interesting. Just build it into your schedule and don't tell you boss.

Finally, where lastcraft and I would disagree is that I think you could also refactor your current procedural code base and get similar gains.