Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What is/is not considered to be good OO programming

297 views
Skip to first unread message

Tony Marston

unread,
Aug 7, 2003, 7:45:59 AM8/7/03
to
On my website I have an article
http://www.tonymarston.net/php-mysql/databaseobjects.html which
describes an abstract class I have written to control all access to my
databases. Someone who is supposed to be a respected member of the PHP
community has informed me that my class breaks the rules of OO
programming and is therefore unworthy of serious consideration. To be
specific he complained that my class contains the following
variables:-

$rows_per_page (to set the page size)
$page_no (to request a particular page number)
$lastpage (returns the highest possible page number)

which he considers to related to formatting rather than the data
itself, and as such is *bad* programming.

I personally think that he is talking out of the wrong end of his
alimentary canal for the following reasons:-

1) Those variables are not for *formatting*, they are for *data
selection*. When my presentation layer communicates with a database
object it is basically saying "get me the data that satisfies this
selection criteria" part of which is "based on a page size of
$row_per_page get me the records for page $page_no, and tell me the
highest possible page available".

2) Despite me asking him what he considers to be the *right* way of
doing things he has failed to respond, probably because he doesn't
know the answer.

3) There is nothing in any OOP literature I have read that says what I
am doing is wrong, there it is not wrong.

4) The language allows me to do it, therefore it cannot be wrong.

5) It is simple and it works, therefore it cannot be all that bad.

Do you people out there in PHP-land have any opinions on this matter?
Is this critocism justified or not?

Tony Marston
http://www.tonymarston.net/

Martin Wickman

unread,
Aug 7, 2003, 8:16:55 AM8/7/03
to
In article <7588a50f.03080...@posting.google.com>, Tony Marston wrote:

> On my website I have an article
> http://www.tonymarston.net/php-mysql/databaseobjects.html which
> describes an abstract class I have written to control all access to
> my databases. Someone who is supposed to be a respected member of
> the PHP community has informed me that my class breaks the rules of
> OO programming and is therefore unworthy of serious consideration.

> he considers [the code to be ] related to formatting rather than the


> data itself, and as such is *bad* programming.

Everyone thinks they know what correct OO is, unfortunately I am the
only one that truly knows it. So here is the correct response:

Gimme a break. There is _nothing_ in OO which says that you should not
mix presentation code with logic code. OO deals with encapsulation and
dependencies, not implementation. As long concerns are separated "well
enough", there is no reason to worry.

Otoh, there is general consensus regarding GUI-apps which says you
should not mix presentation with logic. But that is more like common
knowledge than OO.

> 2) Despite me asking him what he considers to be the *right* way of
> doing things he has failed to respond, probably because he doesn't
> know the answer.

Probably.

> 4) The language allows me to do it, therefore it cannot be wrong.

Yup, otherwise you'd get a syntax error...

> 5) It is simple and it works, therefore it cannot be all that bad.

Yes, that is the single most important point to make:

KISS -- keep it simple, stupid.

Anything else will just make it a lot harder to keep up when the
system demands (inevitable) change.

> Do you people out there in PHP-land have any opinions on this matter?
> Is this critocism justified or not?

I think the OO features in PHP3/4 sucks. I mostly use PHPs object as
simple wrappers for variables (structs) and keep 95% of all
programming functional.

Dave Martin

unread,
Aug 7, 2003, 8:21:33 AM8/7/03
to
In article <7588a50f.03080...@posting.google.com>,
to...@marston-home.demon.co.uk says...

> http://www.tonymarston.net/php-mysql/databaseobjects.html which
> describes an abstract class I have written to control all access to my
> databases.

Nicely done Tony.

> 1) Those variables are not for *formatting*, they are for *data
> selection*. When my presentation layer communicates with a database
> object it is basically saying "get me the data that satisfies this
> selection criteria" part of which is "based on a page size of
> $row_per_page get me the records for page $page_no, and tell me the
> highest possible page available".

Well, in a way, they are for formatting really. Your layer doesn't need
any concept of a page per se since it really has nothing to do with
actually doing anything with the data.

> 3) There is nothing in any OOP literature I have read that says what I
> am doing is wrong, there it is not wrong.

I certainly wouldn't call it "wrong" that's for sure. You've simply
added a small bit of presentation logic to your class.

> Is this critocism justified or not?

I'd say not. If you took what you have and moved the
"formatting/presentation" bits into a separate class leaving just the
data manipulation bits in your class it might squash that criticism.

Personally I'd probably do it exactly the way you have since it's rare
that data manipulation and presentation are totally separate things
(IMO).

David Martin
DynaComp Solutions
http://DynaComp-Solutions.com

Andy Jeffries

unread,
Aug 7, 2003, 8:45:53 AM8/7/03
to
On Thu, 07 Aug 2003 12:16:55 +0000, Martin Wickman wrote:
>> 4) The language allows me to do it, therefore it cannot be wrong.
>
> Yup, otherwise you'd get a syntax error...

I disagree, something can be "wrong" as in an ugly way of doing something
but by syntactically correct.

However, I agree there is nothing wrong with what he is doing.

Cheers,


Andy

stephan beal

unread,
Aug 7, 2003, 10:15:19 AM8/7/03
to
Tony Marston wrote:
> $rows_per_page (to set the page size)
> $page_no (to request a particular page number)
> $lastpage (returns the highest possible page number)
>
> which he considers to related to formatting rather than the data
> itself, and as such is *bad* programming.

i wouldn't go so far as to say BAD, but i would consider it to be ill-suited
to the problem. i agree with him entirely that it's strictly formatting
info, and therefor has no place in a db abstraction layer. It does,
however, have a place in a DbTableRenderer, e.g., or a layer which builds
off of the db layer.

> 1) Those variables are not for *formatting*, they are for *data
> selection*.

No, they're not: consider that a PAGE is a layout convention, and layout is
formatting. Data selection has no unambigious concept of "page".

> 3) There is nothing in any OOP literature I have read that says what I
> am doing is wrong, there it is not wrong.

Yes, there is: most OO advocates will tell you to avoid ANY use of public
variables, for example.

> 4) The language allows me to do it, therefore it cannot be wrong.

The English language allows me to say many abusive things to you, but would
i be right in doing so? Languages are expressive tools, it's the
/expression/ of your solution which is not optimal: a) no public vars and
b) separate formatting from data.


> 5) It is simple and it works, therefore it cannot be all that bad.

If it serves the purpose, great, and that makes it good for it's purpose.
However, that almost inherently makes it less flexible for later adaption
into other contexts.


just my opinions, of course...

--
----- stephan beal
Registered Linux User #71917 http://counter.li.org
I speak for myself, not my employer. Contents may
be hot. Slippery when wet. Reading disclaimers makes
you go blind. Writing them is worse. You have been Warned.

matty

unread,
Aug 7, 2003, 3:36:13 PM8/7/03
to
Tony Marston wrote:

<snip>

> $rows_per_page (to set the page size)
> $page_no (to request a particular page number)
> $lastpage (returns the highest possible page number)
>
> which he considers to related to formatting rather than the data
> itself, and as such is *bad* programming.

I'd agree, and say that he's using the output buffer of the canal.

I've got something similar, although I have a subclass for paged output,
but much the same kind of thing.

Apart from nicer presentation, paging the results allows you to reduce
communication with the database server; if you insist on returning the
entire result set from the query, and *then* choosing a subset of it
from the PHP code, you introduce an unnecessary layer, which can be
done away with entirely by using "LIMIT x, y" in the query.

I think you've done it the right way (but then I would, 'cos I have too!)

> 5) It is simple and it works, therefore it cannot be all that bad.
>
> Do you people out there in PHP-land have any opinions on this matter?
> Is this critocism justified or not?

Definitely unjustified. Is he a first-year S/W Eng student by any chance???

matty

unread,
Aug 7, 2003, 3:37:38 PM8/7/03
to
The other point that occurs, is what is his stance on
using "LIMIT 0, 10", etc, in SQL?

Does he feel that it's bad, since the RDBMS is
taking part in presentation, which is wrong???

;-)

André Næss

unread,
Aug 7, 2003, 5:59:04 PM8/7/03
to
Tony Marston:

> On my website I have an article
> http://www.tonymarston.net/php-mysql/databaseobjects.html which
> describes an abstract class I have written to control all access to my
> databases. Someone who is supposed to be a respected member of the PHP
> community has informed me that my class breaks the rules of OO
> programming and is therefore unworthy of serious consideration. To be
> specific he complained that my class contains the following
> variables:-
>
> $rows_per_page (to set the page size)
> $page_no (to request a particular page number)
> $lastpage (returns the highest possible page number)
>
> which he considers to related to formatting rather than the data
> itself, and as such is *bad* programming.
>
> I personally think that he is talking out of the wrong end of his
> alimentary canal for the following reasons:-
>
> 1) Those variables are not for *formatting*, they are for *data
> selection*. When my presentation layer communicates with a database
> object it is basically saying "get me the data that satisfies this
> selection criteria" part of which is "based on a page size of
> $row_per_page get me the records for page $page_no, and tell me the
> highest possible page available".

The information is typical formatting information. I think it would be much
cleaner if you allowed for two more arguments to getData() that defined how
many rows to retrieve, and what offset to start at. The organization of
data into pages belongs in presentation code.

From a purist perspective, SQL operates on sets, and so operations like "get
me item 1 through 10" makes no sense since sets have no intrinsic ordering.
But the second one applies the SORT operator, the result is no longer a
set, but a list -- a structure with a defined order, and hence the
retrieval of rows 1 through 10 suddenly makes sense.

> 3) There is nothing in any OOP literature I have read that says what I
> am doing is wrong, there it is not wrong.

Right or wrong here is a matter of degree. If one agree that the variables
have to do with formatting, then what you have done is bad OO practice
according to a lot of people. The point is that good design typically
requires that classes have responsibilities, and it's not natural for a
database abstraction layer to be responsible for formatting.

> 4) The language allows me to do it, therefore it cannot be wrong.

Again, it depends on your usage of the word wrong. C allows me to write code
that generates random segmentation faults, and assembler allows me to write
self-modifying code.

> 5) It is simple and it works, therefore it cannot be all that bad.

I agree that it's simple and it does the job. But as far as I could
understand you wanted to submit your code to some sort of repository. When
code is to be used by many people it obviously has to be of much higher
quality than most of the code that's written every day, and -- more
importantly -- it must adhere to the principles accepted by most of the
developers who are supposed to use the code.

And in general I think your design is bad because you have to create a new
class for every table you create, and you have to recode both the table and
the class every time you change the table, which obviously doubles the
chances of bugs. I can't really see how this can save you very much work I
guess.

André Næss

Jochen Daum

unread,
Aug 7, 2003, 4:23:34 PM8/7/03
to
Hi Tony!

On 7 Aug 2003 04:45:59 -0700, to...@marston-home.demon.co.uk (Tony
Marston) wrote:

>On my website I have an article
>http://www.tonymarston.net/php-mysql/databaseobjects.html which
>describes an abstract class I have written to control all access to my
>databases. Someone who is supposed to be a respected member of the PHP
>community has informed me that my class breaks the rules of OO
>programming and is therefore unworthy of serious consideration. To be
>specific he complained that my class contains the following
>variables:-
>
>$rows_per_page (to set the page size)
>$page_no (to request a particular page number)
>$lastpage (returns the highest possible page number)
>
>which he considers to related to formatting rather than the data
>itself, and as such is *bad* programming.
>

The others wrote everything I could write.

My database class also supports a limit statement, I especially wrote
it, because its such a hassle to limit with MSSQL.

IMO, doesn't matter, if irt is parameter or class variable. I prefer
parameter, because I don't like:

$arith->x = 1;
$arith->y = 2;
$m = arith->multiply();

I rather like:

$m = arith->multiply(1,2);

HTH, Jochen


>I personally think that he is talking out of the wrong end of his
>alimentary canal for the following reasons:-
>
>1) Those variables are not for *formatting*, they are for *data
>selection*. When my presentation layer communicates with a database
>object it is basically saying "get me the data that satisfies this
>selection criteria" part of which is "based on a page size of
>$row_per_page get me the records for page $page_no, and tell me the
>highest possible page available".
>
>2) Despite me asking him what he considers to be the *right* way of
>doing things he has failed to respond, probably because he doesn't
>know the answer.
>
>3) There is nothing in any OOP literature I have read that says what I
>am doing is wrong, there it is not wrong.
>
>4) The language allows me to do it, therefore it cannot be wrong.
>
>5) It is simple and it works, therefore it cannot be all that bad.
>
>Do you people out there in PHP-land have any opinions on this matter?
>Is this critocism justified or not?
>
>Tony Marston
>http://www.tonymarston.net/

--
Jochen Daum - CANS Ltd.
PHP DB Edit Toolkit -- PHP scripts for building
database editing interfaces.
http://sourceforge.net/projects/phpdbedittk/

matty

unread,
Aug 7, 2003, 6:27:34 PM8/7/03
to
André Næss wrote:

<snip>

> The information is typical formatting information. I think it would be
> much cleaner if you allowed for two more arguments to getData() that
> defined how many rows to retrieve, and what offset to start at. The
> organization of data into pages belongs in presentation code.

The information is used to select a subset of the data, so how is this
formatting? Just because this kind of technique is commonly used in
presentation, doesn't mean that restricting the rows returning is a
formatting operation. If you were to take that viewpoint, then you
could argue that since the order records are displayed in a table is
presentational, then ordering the records returned is also a formatting
operation.

I do think that a GetPagedChunk($offset, $length) method could be a good
idea; however, the concepts of orthogonality and encapsulation would
indicate that having created a PagedResultSet($sourcequery, $pagelimit, $offset=0)
object (or similar), really, the object should handle issues such as which
records to return.

This *can* verge into formatting, but it's a trciky question: the presentational
requirements of displaying a table of data, along with "Showing records 5-19 of 235",
generation of next/previous links, etc, leads to a very heterogeneous set of data
to be returned by the object. One possible way to handle this is to have
GetPageNumber(), GetPageCount(), GetNextOffset(), etc, methods; another is to
return data as xml for transformation into the desired *format* for display, since
a generalized class cannot "know" the format required, etc.

>
> From a purist perspective, SQL operates on sets, and so operations like
> "get me item 1 through 10" makes no sense since sets have no intrinsic
> ordering. But the second one applies the SORT operator, the result is no
> longer a set, but a list -- a structure with a defined order, and hence
> the retrieval of rows 1 through 10 suddenly makes sense.

Arguing whether this is a part of a true relational query or not is fairly
academic as far as developing an application goes: very few large-scale applications
are built using databases in 5NF, since performance issues take a part. Sets have
no intrinsic ordering, but most people writing this type of class apply some
kind of ordering to the set returned, so that taking "records 16-20 of 33" has
some kind of meaningful semantic.

> Right or wrong here is a matter of degree. If one agree that the variables
> have to do with formatting, then what you have done is bad OO practice
> according to a lot of people. The point is that good design typically
> requires that classes have responsibilities, and it's not natural for a
> database abstraction layer to be responsible for formatting.

Good OO is about code reuse, orthogonality, and data encapsulation. Since the
data access class is there to handle the database queries, wouldn't it be
breaking the encapsulation to have a separate entity control which data is
actually displayed?

One of the funny things about this kind of application is that selecting
a subset of the data sits somewhere between database handling and presentation.
Reducing the number of records displayed reduces the overhead on 1) user
screens (and user brains); and on 2) the system serving the pages. I still
think there is a strong case that this kind of class doesn't have to violate
principles of OO; even if it did, the issues of performance dictate that it's
better to have the class function in this way, to increase code reliability and
reuse. People use OO to produce more reliable software, more rapidly: just
because a system is OO doesn't make it good in itself, it merely means it
has been written to conform to a specific paradigm.

> I agree that it's simple and it does the job. But as far as I could
> understand you wanted to submit your code to some sort of repository. When
> code is to be used by many people it obviously has to be of much higher
> quality than most of the code that's written every day, and -- more
> importantly -- it must adhere to the principles accepted by most of the
> developers who are supposed to use the code.
>
> And in general I think your design is bad because you have to create a new
> class for every table you create, and you have to recode both the table
> and the class every time you change the table, which obviously doubles the
> chances of bugs. I can't really see how this can save you very much work I
> guess.

Why do you have to recode the class? Admittedly, in the tutorial mentioned, the
number of rows per page is set in the constructor; there is no reason why the
variable cannot be changed. The same applies to the table name and database name.

As far as code quality is concerned, there are things missing (escaping the data
for one). But from a reusability point of view, mostly all that needs changing
is to pass a few parameters to the constructor, and add sorting to the queries
to get consistent results.

I think, though, that the page was meant more as a tutorial on writing classes
in PHP, and as such is better than many of those around online to date.

Zurab Davitiani

unread,
Aug 7, 2003, 6:33:15 PM8/7/03
to
stephan beal wrote on Thursday 07 August 2003 07:15:

> Tony Marston wrote:
>> 1) Those variables are not for *formatting*, they are for *data
>> selection*.
>
> No, they're not: consider that a PAGE is a layout convention, and layout
> is formatting. Data selection has no unambigious concept of "page".

Paging the data is being used by most databases that feature variable-length
records, such as Access, MSSQL, and others. While Tony's implementation
does not exactly serve the same purpose, it still goes to show that "page"
is not necessarily related to a presentation layer.

It seems to me that the issue here is with the naming of the properties with
"page" in them, not the merits of the properties, methods and
functionalities they provide. I believe it is perfectly acceptable for a
data layer to be able to divide data into "chunks" and only return
requested appropriate chunk(s) to the calling object/component/service/etc.

>> 3) There is nothing in any OOP literature I have read that says what I
>> am doing is wrong, there it is not wrong.
>
> Yes, there is: most OO advocates will tell you to avoid ANY use of public
> variables, for example.

Yes, I spotted this too and you are absolutely right.

--
Business Web Solutions
ActiveLink, LLC
www.active-link.com/intranet/

matty

unread,
Aug 7, 2003, 7:41:40 PM8/7/03
to
stephan beal wrote:


> Yes, there is: most OO advocates will tell you to avoid ANY use of public
> variables, for example.
>

Then you're screwed in PHP, since it doesn't support a top-level "application"
object; the closest you could get, is have an object that does everything from
its constuctor, and start it all off with

new MyApplication();

but that's probably at least a *little* counterintuitive...

Tony Marston

unread,
Aug 8, 2003, 3:22:24 AM8/8/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bguasp$rbr$1...@maud.ifi.uio.no>...

Rather have have extra arguments in my 'getData' method I have
separate setters for $rows_per_page and $pageno, with a getter for
$lastpage. The reason for this is that a default value for
$rows_per_page can be defined in the class constructor.

> From a purist perspective, SQL operates on sets, and so operations like "get
> me item 1 through 10" makes no sense since sets have no intrinsic ordering.
> But the second one applies the SORT operator, the result is no longer a
> set, but a list -- a structure with a defined order, and hence the
> retrieval of rows 1 through 10 suddenly makes sense.

My point is that the presentation layer asks the database object to
retrieve some data, and it is the database object is responsible for
constructing the SQL statement. As the SQL statement contains the
'LIMIT x,y' clause it is necessary for the database object to have
these values available. There is simply no other way.

> > 3) There is nothing in any OOP literature I have read that says what I
> > am doing is wrong, there it is not wrong.
>
> Right or wrong here is a matter of degree. If one agree that the variables
> have to do with formatting, then what you have done is bad OO practice
> according to a lot of people. The point is that good design typically
> requires that classes have responsibilities, and it's not natural for a
> database abstraction layer to be responsible for formatting.

Those variables are not used for *formatting* the data, they are used
for *selecting* a subset of rows instead of the entire contents of the
table which would be grossly inefficient.



> > 4) The language allows me to do it, therefore it cannot be wrong.
>
> Again, it depends on your usage of the word wrong. C allows me to write code
> that generates random segmentation faults, and assembler allows me to write
> self-modifying code.

I am aware that certain languages have functions which are more
trouble than they are worth (I remember the ALTER verb in COBOL) but
that is irrelevant in this case. I do not see why it could possibly be
*wrong* to have a variable in my database object which allows that
database object to construct the LIMIT clause in an sql SELECT
statement.

> > 5) It is simple and it works, therefore it cannot be all that bad.
>
> I agree that it's simple and it does the job. But as far as I could
> understand you wanted to submit your code to some sort of repository. When
> code is to be used by many people it obviously has to be of much higher
> quality than most of the code that's written every day, and -- more
> importantly -- it must adhere to the principles accepted by most of the
> developers who are supposed to use the code.

I have been a software developer for over 25 years and I have seen
many different programmers with many different principles. Some try to
produce code which is efficient, effective and maintainable then write
a methodology to match, while others create a fancy methodology
without any regard for efficiency or maintainability. As far as I am
concerned the overriding principle is the KISS principle (Keep It
Simple, Stupid). Too many people keep inventing stupid rules which
just get in the way of efficient software development. Too many people
have different ideas about what is *good* and *not good* practice. As
far as I am concerned if it works, is simple and is maintainable then
it is *good*. Anything else is *not good*.

> And in general I think your design is bad because you have to create a new
> class for every table you create, and you have to recode both the table and
> the class every time you change the table, which obviously doubles the
> chances of bugs. I can't really see how this can save you very much work I
> guess.

> André Næss

You have missed the point about my abstract database class. Each
database table has its own class which is a subclass of the abstract
class, therefore it inherits all the properties and methods of the
abstract class. Each table class therefore need only contain extra
code which is specific to that class, such as a list of field names,
validation rules, relationships, etc. All the code for retrieving,
inserting, updating, deleting and validating data is inherited from
the abstract class and does not have to be rewritten or copied.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 8, 2003, 3:29:21 AM8/8/03
to
Dave Martin <DJMa...@DynaComp-Solutions.com> wrote in message news:<MPG.199c0e595...@news.east.earthlink.net>...

> In article <7588a50f.03080...@posting.google.com>,
> to...@marston-home.demon.co.uk says...
>
> > http://www.tonymarston.net/php-mysql/databaseobjects.html which
> > describes an abstract class I have written to control all access to my
> > databases.
>
> Nicely done Tony.

Thanks.

> > 1) Those variables are not for *formatting*, they are for *data
> > selection*. When my presentation layer communicates with a database
> > object it is basically saying "get me the data that satisfies this
> > selection criteria" part of which is "based on a page size of
> > $row_per_page get me the records for page $page_no, and tell me the
> > highest possible page available".
>
> Well, in a way, they are for formatting really. Your layer doesn't need
> any concept of a page per se since it really has nothing to do with
> actually doing anything with the data.

They are not *formatting* the data, they are used for *selecting* rows
from the database in the same way as 'where columnname=value' is used
for selection. The only *formatting* which is done is when the HTML
code is generated, which is done using an XML file and an XSL
transformation.

> > 3) There is nothing in any OOP literature I have read that says what I
> > am doing is wrong, there it is not wrong.
>
> I certainly wouldn't call it "wrong" that's for sure. You've simply
> added a small bit of presentation logic to your class.
>
> > Is this critocism justified or not?
>
> I'd say not. If you took what you have and moved the
> "formatting/presentation" bits into a separate class leaving just the
> data manipulation bits in your class it might squash that criticism.
>
> Personally I'd probably do it exactly the way you have since it's rare
> that data manipulation and presentation are totally separate things
> (IMO).

The database object needs to construct the sql SELECT statement, which
contains the LIMIT clause. It is therefore imperative that the
database object has the information available to construct the LIMIT
clause. There is simply no other way.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 8, 2003, 3:36:18 AM8/8/03
to
stephan beal <ste...@wanderinghorse.net> wrote in message news:<bgtmob$8lm$1...@ork.noris.net>...

> Tony Marston wrote:
> > $rows_per_page (to set the page size)
> > $page_no (to request a particular page number)
> > $lastpage (returns the highest possible page number)
> >
> > which he considers to related to formatting rather than the data
> > itself, and as such is *bad* programming.
>
> i wouldn't go so far as to say BAD, but i would consider it to be ill-suited
> to the problem. i agree with him entirely that it's strictly formatting
> info, and therefor has no place in a db abstraction layer. It does,
> however, have a place in a DbTableRenderer, e.g., or a layer which builds
> off of the db layer.
>
> > 1) Those variables are not for *formatting*, they are for *data
> > selection*.
>
> No, they're not: consider that a PAGE is a layout convention, and layout is
> formatting. Data selection has no unambigious concept of "page".

Those variables are for SELECTION as they are used to construct the
LIMIT clause on the sql SELECT statement. Even if the sql statement is
generated in a separate object these variables must be passed to that
object, therefore they must exist in my database class.

> > 3) There is nothing in any OOP literature I have read that says what I
> > am doing is wrong, there it is not wrong.
>
> Yes, there is: most OO advocates will tell you to avoid ANY use of public
> variables, for example.

I only use public variables because PHP 4 does not cater for private
variables. I am aware however that these variables should only be
accessed through separate setters and getters, which is what I use.

> > 4) The language allows me to do it, therefore it cannot be wrong.
>
> The English language allows me to say many abusive things to you, but would
> i be right in doing so? Languages are expressive tools, it's the
> /expression/ of your solution which is not optimal: a) no public vars and
> b) separate formatting from data.

People who say that my method is *wrong* have yet to supply me their
version of a method which is *right*.

> > 5) It is simple and it works, therefore it cannot be all that bad.
>
> If it serves the purpose, great, and that makes it good for it's purpose.
> However, that almost inherently makes it less flexible for later adaption
> into other contexts.
>
>
> just my opinions, of course...

How can my method be inflexible?

stephan beal

unread,
Aug 8, 2003, 4:31:11 AM8/8/03
to
Tony Marston wrote:

> stephan beal <ste...@wanderinghorse.net> wrote in message

>> Yes, there is: most OO advocates will tell you to avoid ANY use of public
>> variables, for example.
>
> I only use public variables because PHP 4 does not cater for private
> variables. I am aware however that these variables should only be
> accessed through separate setters and getters, which is what I use.

Then don't publish the vars in your API and add functions to get at them
instead. Yes, it's not the most efficient solution, but it's simple to
implement and makes long-term maintenance simpler.


>> > 5) It is simple and it works, therefore it cannot be all that bad.
>>
>> If it serves the purpose, great, and that makes it good for it's purpose.
>> However, that almost inherently makes it less flexible for later adaption
>> into other contexts.
>>
>>
>> just my opinions, of course...
>
> How can my method be inflexible?

Let's say it's 6 months from now and your needs for your site have out-grown
what the framework of capable of. The question comes up: rewrite the site
or expand the existing framework? The more that a framework (i.e., your
database layer) is tied to a specific task, the less flexible it becomes
and the more difficult it becomes to re-use that code in other contexts.

i'm not at all saying that your db layer IS inflexible (i have no idea - i
haven't analysed it), but i am of the opinion that SELECT data, for
example, is in essence a formatting option (the WHERE clause, on the other
hand, is specifically a logic operation), and that shoe-horning such things
as paging into the db layer isn't necessary. i would first write the db
layer and then make another layer which includes the selection/limitation
code. What if i wanted to use your db layer but didn't want the paging
code? Is the class designed in such a way that i am forced to use it?
Just things to consider.

Glen Vermeylen

unread,
Aug 8, 2003, 8:22:54 AM8/8/03
to
A part of your solution is Object Oriented but I have some considerations:
Tables are part of a database, your approach only leaves room to work
with one database. If you create a database class (as in: $db = new
dataBase('server', 'username', 'password') you could have your table
class make use of this dataBase class as in $table = new
table($db->getLink()).
Then you can distanciate yourself from the whereabouts of the tables and
only worry about their data.
Considering your getData: this requires you to have insight into the
inner mechanics of your class (you have to set your desired pagesize,
and you have to go through trouble if you don't want to get the standard
subsequent pages, set by pagesize).
I suggest you have a method $table->getData(selection_criteria), which
gives you every result there is. Then you could have a method
$table->getPage(selection_criteria, pagesize='defaultvalue',
pagenumber='1'). (the "=" will use a defaultvalue, if you don't pass
that parameter).
Now you can make a getNextPage(), getPrevPage(), ... which do what you
can guess... :).
I don't know anything about error-handling with php, but you might want
to consider tying mysql-specific errors to your mysql-classes.
$results = $table->getPage(...);
if ($table->hasError())
$table->printError();
That way, with inheritance (and overriding) your $db errors can be
delegated to $table...

I hope this has been of any help.

ps: This is not written out of arrogance and I don't think I know it
better than anyone else. I'm just a student, and also was pondering
about a nice oo-approach to php/mysql scripting.
This is just a mere braindump.

Glen

Glen Vermeylen

unread,
Aug 8, 2003, 8:29:43 AM8/8/03
to
Oops, spotted some errors in my text:

"new table($db->getLink())" would offcourse be "new table($db)". The
user only knows that a table is part of a database, he shouldn't know
about the link.

"That way, with inheritance (and overriding) ... " should be "with
delegation ... "

:-)

André Næss

unread,
Aug 8, 2003, 2:27:59 PM8/8/03
to
matty:

> André Næss wrote:
>
> <snip>
>
>> The information is typical formatting information. I think it would be
>> much cleaner if you allowed for two more arguments to getData() that
>> defined how many rows to retrieve, and what offset to start at. The
>> organization of data into pages belongs in presentation code.
>
> The information is used to select a subset of the data, so how is this
> formatting? Just because this kind of technique is commonly used in
> presentation, doesn't mean that restricting the rows returning is a
> formatting operation. If you were to take that viewpoint, then you
> could argue that since the order records are displayed in a table is
> presentational, then ordering the records returned is also a formatting
> operation.

Ok let me try to clarify this. To fetch rows 1 through 10 is ok. Using limit
is ok. It's ok to define what subset of a sorted result set you want,
because that's part of the selection. I agree.

Here's the relevant code:
var $rows_per_page; // used in pagination
var $pageno; // current page number
var $lastpage; // highest page number

So what Tony has done is put *pagination* information into the DB-class, and
that is what I react to. He could insert two variables, $offset and
$numRows, and that would be ok. But the pagination belongs in the
presentation layer. It's a tiny difference, and not very important IMO, but
I still think it's worth pointing out.

>> And in general I think your design is bad because you have to create a
>> new class for every table you create, and you have to recode both the
>> table and the class every time you change the table, which obviously
>> doubles the chances of bugs. I can't really see how this can save you
>> very much work I guess.
>
> Why do you have to recode the class? Admittedly, in the tutorial
> mentioned, the number of rows per page is set in the constructor; there is
> no reason why the
> variable cannot be changed. The same applies to the table name and
> database name.

You have to write a new class which inherits the abstract class and has
variables to represent the fields in the DB. Quote from Tony's page:

function Database_Table ()
{
$this->tablename = 'default';
$this->dbname = 'default';
$this->rows_per_page = 10;

$this->fieldlist = array('column1', 'column2', 'column3');
$this->fieldlist['column1'] = array('pkey' => 'y');
} // constructor

The variable $fieldlist is used to list all the columns within that table,
and to identify which is the primary key. How this is used will become
apparent

End quote.

So when you add a field to your DB, you also have to change the class, this
sort of dependency can quickly lead to maintenance problems, especially if
someone else is supposed to use the classes.

André Næss

André Næss

unread,
Aug 8, 2003, 2:34:55 PM8/8/03
to
Tony Marston:

>> The information is typical formatting information. I think it would be
>> much cleaner if you allowed for two more arguments to getData() that
>> defined how many rows to retrieve, and what offset to start at. The
>> organization of data into pages belongs in presentation code.
>
> Rather have have extra arguments in my 'getData' method I have
> separate setters for $rows_per_page and $pageno, with a getter for
> $lastpage. The reason for this is that a default value for
> $rows_per_page can be defined in the class constructor.

But if you say that these variables are in fact selection criteria, then
certainly you must agree that seeing as $where is a collection of selection
criteria, and it's being passed to getData(), it would be much more
consistent to pass them as parameters!



>> From a purist perspective, SQL operates on sets, and so operations like
>> "get me item 1 through 10" makes no sense since sets have no intrinsic
>> ordering. But the second one applies the SORT operator, the result is no
>> longer a set, but a list -- a structure with a defined order, and hence
>> the retrieval of rows 1 through 10 suddenly makes sense.
>
> My point is that the presentation layer asks the database object to
> retrieve some data, and it is the database object is responsible for
> constructing the SQL statement. As the SQL statement contains the
> 'LIMIT x,y' clause it is necessary for the database object to have
> these values available. There is simply no other way.

And we agree on that. See my reply to "matty".



>> > 5) It is simple and it works, therefore it cannot be all that bad.
>>
>> I agree that it's simple and it does the job. But as far as I could
>> understand you wanted to submit your code to some sort of repository.
>> When code is to be used by many people it obviously has to be of much
>> higher quality than most of the code that's written every day, and --
>> more importantly -- it must adhere to the principles accepted by most of
>> the developers who are supposed to use the code.
>
> I have been a software developer for over 25 years and I have seen
> many different programmers with many different principles. Some try to
> produce code which is efficient, effective and maintainable then write
> a methodology to match, while others create a fancy methodology
> without any regard for efficiency or maintainability. As far as I am
> concerned the overriding principle is the KISS principle (Keep It
> Simple, Stupid). Too many people keep inventing stupid rules which
> just get in the way of efficient software development. Too many people
> have different ideas about what is *good* and *not good* practice. As
> far as I am concerned if it works, is simple and is maintainable then
> it is *good*. Anything else is *not good*.

KISS is a very good idea indeed. My point was that if you want to partake in
a community you have to follow the rules of the community, if you disagree,
you have to lobby your disagreement to the other members.



>> And in general I think your design is bad because you have to create a
>> new class for every table you create, and you have to recode both the
>> table and the class every time you change the table, which obviously
>> doubles the chances of bugs. I can't really see how this can save you
>> very much work I guess.
>
>

> You have missed the point about my abstract database class. Each
> database table has its own class which is a subclass of the abstract
> class, therefore it inherits all the properties and methods of the
> abstract class. Each table class therefore need only contain extra
> code which is specific to that class, such as a list of field names,
> validation rules, relationships, etc.

Precisely. And it is this code which leads to a problematic dependency
between the DB and the class. I understand the point of reusing code to
generate SELECT/INSERT/UPDATE/DELETE statements, but you can do that
without having to create a class for every table you have.

André Næss

matty

unread,
Aug 8, 2003, 4:38:30 PM8/8/03
to
André Næss wrote:

> Here's the relevant code:
> var $rows_per_page; // used in pagination
> var $pageno; // current page number
> var $lastpage; // highest page number
>
> So what Tony has done is put *pagination* information into the DB-class,
> and that is what I react to. He could insert two variables, $offset and
> $numRows, and that would be ok. But the pagination belongs in the
> presentation layer. It's a tiny difference, and not very important IMO,
> but I still think it's worth pointing out.
>

Well, certainly the values shouldn't be set in the constructor like
this, I agree. I still think that there is a place for a database class
that can handle pagination without outside help, although this does raise
issues as far as the heterogenous nature of the data it would have to
return (links, data values, etc)

> You have to write a new class which inherits the abstract class and has
> variables to represent the fields in the DB. Quote from Tony's page:
>
> function Database_Table ()
> {
> $this->tablename = 'default';
> $this->dbname = 'default';
> $this->rows_per_page = 10;
>
> $this->fieldlist = array('column1', 'column2', 'column3');
> $this->fieldlist['column1'] = array('pkey' => 'y');
> } // constructor
>

OK, I missed this one as I only scanned the article. Of course, a really
good DB class would identify the primary key itself, as the RDBMS can
provide this kind of information...

> So when you add a field to your DB, you also have to change the class,
> this sort of dependency can quickly lead to maintenance problems,
> especially if someone else is supposed to use the classes.

I agree entirely with you on this point - since the whole point of OO
is reusing code, not just an academic exercise, a class which cannot
be reused isn't very helpful!

Tony Marston

unread,
Aug 11, 2003, 6:06:59 AM8/11/03
to
stephan beal <ste...@wanderinghorse.net> wrote in message news:<bgvmv1$14d$1...@ork.noris.net>...

My method is correct according to the principles of the 3 tier
architecture in which the presentation layer talks to the business
layer which talks to the data access layer. It is not allowed for the
presentation layer to talk directly to the data access layer - it must
always go through thye business layer. Therefore (and this is the crux
of my argument) whatever information the data access layer needs to
construct the sql SELECT statement must go through the business layer.
That is why my business layer object contains variables for paging as
how else could the data access layer have the information required to
construct the LIMIT clause?

I think your idea of having data selection/limitation code in a
separate layer is totally wrong (but that's just my personal opinion).

> What if i wanted to use your db layer but didn't want the paging
> code? Is the class designed in such a way that i am forced to use it?
> Just things to consider.

If you want paging turned off (which I do in one of my test scripts)
then simply set $rows_per_page to zero, then my code will not generate
any LIMIT clause on the SELECT statement.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 11, 2003, 6:28:11 AM8/11/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bh0iss$ba8$1...@maud.ifi.uio.no>...
> matty:
>
> > André Næss wrote:

<snip>

> Ok let me try to clarify this. To fetch rows 1 through 10 is ok. Using limit


> is ok. It's ok to define what subset of a sorted result set you want,
> because that's part of the selection. I agree.
>
> Here's the relevant code:
> var $rows_per_page; // used in pagination
> var $pageno; // current page number
> var $lastpage; // highest page number
>
> So what Tony has done is put *pagination* information into the DB-class, and
> that is what I react to. He could insert two variables, $offset and
> $numRows, and that would be ok. But the pagination belongs in the
> presentation layer. It's a tiny difference, and not very important IMO, but
> I still think it's worth pointing out.

You method of pagination is more complicated than mine, therefore
violates the KISS principle. In my method all the presentation object
has to do before calling the getData() method is as follows:

$dbobject->setRowsPerPage()
$dbobject->setPageNo()

Both of these are optional because there is a default value for
$rows_per_page inside the class, and $pageno will default to whatever
was used previously for this object in the current session.

My presentation layer does not calculate the offset as that is done
inside the data access layer - all it does is specify a page number
(which comes from a hyperlink in my pagination area).

<snip>



> You have to write a new class which inherits the abstract class and has
> variables to represent the fields in the DB. Quote from Tony's page:
>
> function Database_Table ()
> {
> $this->tablename = 'default';
> $this->dbname = 'default';
> $this->rows_per_page = 10;
>
> $this->fieldlist = array('column1', 'column2', 'column3');
> $this->fieldlist['column1'] = array('pkey' => 'y');
> } // constructor
>
> The variable $fieldlist is used to list all the columns within that table,
> and to identify which is the primary key. How this is used will become
> apparent
>
> End quote.
>
> So when you add a field to your DB, you also have to change the class, this
> sort of dependency can quickly lead to maintenance problems, especially if
> someone else is supposed to use the classes.
>
> André Næss

Having a separate class for each individual database table is supposed
to be a GOOD idea in OOP as it encapsulates all the information
required to read/write/update/delete that particular database table.
This includes a list of all fields and their characteristics so that
basic validation can be done by the code which is inherited from the
abstract class instead of having to write a separate set of validation
code for each table.

If the physical database table is changed then the class which
contains information about that table is also changed. This is not a
maintenance problem, it is basic common sense. If a programmer changes
a database table without updating the code which accesses that table
then he is a ****KING PLONKER of the first order. In my method there
is one class per table, so the changes have to be made in only one
place. What could be easier than that?

Tony Marston
http://tonymarston.net/

Tony Marston

unread,
Aug 11, 2003, 6:37:39 AM8/11/03
to
Jochen Daum <joche...@cans.co.nz> wrote in message news:<c6d5jv4v8gm18j1kf...@4ax.com>...
> Hi Tony!

<snip>

> The others wrote everything I could write.
>
> My database class also supports a limit statement, I especially wrote
> it, because its such a hassle to limit with MSSQL.
>
> IMO, doesn't matter, if irt is parameter or class variable. I prefer
> parameter, because I don't like:
>
> $arith->x = 1;
> $arith->y = 2;
> $m = arith->multiply();
>
> I rather like:
>
> $m = arith->multiply(1,2);
>
> HTH, Jochen
>

The reason that I use separate variables instead of parameters on the
getData() method is that the number of possible parameters is quite
large and most of them are optional. So instead of having a long list
of parameters on the getData() method I find it easier to use a
separate set...() method whenever I DO have a value that I want to be
used. That is my personal preference. If I have a method which has a
small number of parameters then I would stick to supplying them on the
method call as you suggest.

The difference lies in the number of parameters and how many of them
are optional.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 11, 2003, 6:58:26 AM8/11/03
to
Glen Vermeylen <gverm...@pandora.be> wrote in message news:<3F339559...@pandora.be>...

> A part of your solution is Object Oriented but I have some considerations:
> Tables are part of a database, your approach only leaves room to work
> with one database.

WRONG! My current development uses 3 different databases within the
same application. Each class is named after the table, but the
database name is held within the class and is transparent to the
presentation layer.

> If you create a database class (as in: $db = new
> dataBase('server', 'username', 'password') you could have your table
> class make use of this dataBase class as in $table = new
> table($db->getLink()).
> Then you can distanciate yourself from the whereabouts of the tables and
> only worry about their data.
> Considering your getData: this requires you to have insight into the
> inner mechanics of your class (you have to set your desired pagesize,
> and you have to go through trouble if you don't want to get the standard
> subsequent pages, set by pagesize).

There is a default page size defined within each class, but it can be
changed at any time using the $dbobject->setRowsPerPage() method. A
zero value will turn off paging altogether.

> I suggest you have a method $table->getData(selection_criteria), which
> gives you every result there is. Then you could have a method
> $table->getPage(selection_criteria, pagesize='defaultvalue',
> pagenumber='1'). (the "=" will use a defaultvalue, if you don't pass
> that parameter).
> Now you can make a getNextPage(), getPrevPage(), ... which do what you
> can guess... :).

I don't want a separate method for firstpage(), previouspage(),
nextpage(), lastpage() when I can use a setPageNo() method followed by
my getData() method.

> I don't know anything about error-handling with php, but you might want
> to consider tying mysql-specific errors to your mysql-classes.
> $results = $table->getPage(...);
> if ($table->hasError())
> $table->printError();
> That way, with inheritance (and overriding) your $db errors can be
> delegated to $table...

Take a look at http://www.tonymarston.net/php-mysql/errorhandler.html

> I hope this has been of any help.
>
> ps: This is not written out of arrogance and I don't think I know it
> better than anyone else. I'm just a student, and also was pondering
> about a nice oo-approach to php/mysql scripting.
> This is just a mere braindump.
>
> Glen

You have to learn somehow, but something you have to watch out for is
that different people have different ideas about what is *good* or
*not good* programming. My advice is as follows:

- Try to follow the KISS principle and you won't go far wrong.

- When developing software there should only be 3 limiting factors:
1) The limits imposed by the user requirements.
2) The limits imposed by the chosen development language.
3) The limits of you own abilities.

Other limitations, such as people telling you which methodology is
*right* or even which interpretation of the methodology is *right*,
are entirely artificial and therefore can be ignored.

Tony Marston
http://www.tonymarston.net/

matty

unread,
Aug 11, 2003, 8:19:40 AM8/11/03
to
Tony Marston wrote:

<snip>

I have to disagree with you here! Having a separate class *instance* is
good OO, having a separate *class* is bad OO, since you lose all the
potential benefits of low maintenance, etc.

>
> If the physical database table is changed then the class which
> contains information about that table is also changed. This is not a
> maintenance problem, it is basic common sense. If a programmer changes
> a database table without updating the code which accesses that table
> then he is a ****KING PLONKER of the first order. In my method there
> is one class per table, so the changes have to be made in only one
> place. What could be easier than that?
>

How about something like this:

(obviously not a specific implementation, more a hypothetical description
of an interface)

$tablea = new DBTable($database, $user, $password, $table);
foreach(array('widgetid', 'manufr', 'cost', 'colour', 'weight') as $item)
{
$tablea->AddField($item);
}
$tablea->AddConstraint('cost > 20.00');
$tablea->AddConstraint('colour = \'blue\'');
if (!array_key_exists('offset', $_GET) or !preg_match('/^[0-9]+/', $_GET['offset']))
{
$dboffset = 0;
}
$resultarray = $tablea->GetPageList($offset, $config['database']['pagelength']);

Then you can change database, change fields, paging length, WHERE constraints, etc
without having to change the *class*, merely the class instance. You only have to change
DBTable class code if you're changing its functionality.

Otherwise, in a system with 12 database tables, having a different class for each
table? That's not good.

Matt

R. Rajesh Jeba Anbiah

unread,
Aug 11, 2003, 10:09:03 AM8/11/03
to
to...@marston-home.demon.co.uk (Tony Marston) wrote in message news:<7588a50f.03080...@posting.google.com>...

Kudos! Nice work... My points regarding the OOP style:

1. I could see the way you pass values to the methods contradicts the
OOP style. For example:

global $dbconnect, $query; <=======//
$dbconnect = db_connect($this->dbname) or trigger_error("SQL",
E_USER_ERROR);

at the "updateRecord ($fieldarray)" method.

You could have used setDBLink($db_link) to the class....

2.

function Database_Table ()
{
$this->tablename = 'default';
$this->dbname = 'default';
$this->rows_per_page = 10;

$this->fieldlist = array('column1', 'column2', 'column3');
$this->fieldlist['column1'] = array('pkey' => 'y');
} // constructor

If you this style, there won't be any reusability. In the
languages that support associative arrays, you may use like...
function Database_Table ()
{
$this->table_settings = array(); //hash array
} // constructor

Then...
function setTableSettings($key, $value)
{
$this->table_settings[$key] = $value;
}

function getTableSettings($key)
{
return( $this->table_settings[$key] );
}


This is my point. I may be wrong though...

Anyway... keep writing... nice article...

---
"If there is a God, he must be a sadist!"
Email: rrjanbiah-at-Y!com

André Næss

unread,
Aug 11, 2003, 4:42:15 PM8/11/03
to
Tony Marston:

> André Næss <andrena.spa...@ifi.uio.no> wrote in message
> news:<bh0iss$ba8$1...@maud.ifi.uio.no>...
>> matty:
>>
>> > André Næss wrote:
>
> <snip>
>
>> Ok let me try to clarify this. To fetch rows 1 through 10 is ok. Using
>> limit is ok. It's ok to define what subset of a sorted result set you
>> want, because that's part of the selection. I agree.
>>
>> Here's the relevant code:
>> var $rows_per_page; // used in pagination
>> var $pageno; // current page number
>> var $lastpage; // highest page number
>>
>> So what Tony has done is put *pagination* information into the DB-class,
>> and that is what I react to. He could insert two variables, $offset and
>> $numRows, and that would be ok. But the pagination belongs in the
>> presentation layer. It's a tiny difference, and not very important IMO,
>> but I still think it's worth pointing out.
>
> You method of pagination is more complicated than mine, therefore
> violates the KISS principle. In my method all the presentation object
> has to do before calling the getData() method is as follows:

How is it more complicated? All I suggest is that you let the presentation
layer handle a presentation issue. It's really simple to supply the
presentation layer with default values for the pagination, and if you want
to change those values you have to change them *somewhere*. It just makes
more sense to change them in the presentation layer and let the
presentation layer handle the translation from offset/page number to the
limit clause. Transparently, of course.

Now, if I was to code this I'd probably write a sort of
PagedPresentation thingy, which is meant for this sort of
situation. PagedPresentation should just supply a framework for
creating paged presentations, and it has to be coupled with a data
source. The data source supplies the PagedPresentation with data, and
the PagedPresentation transforms these data as defined by the
developer using some sort of template (a simple HTML/PHP mix is
sufficient).

But there obviously has to be a connection between the data source and
the presentation, because the presentation outputs stuff which in the
end has to result in $_GET variables which define what page to
display. And this data then has to be used to figure out what rows to
fetch.

So, we have to figure out how to implement this as clean as
possible. Let us start by considering the purist solution, which is to
fetch *all* the rows and supply them to the presentation layer, which
outputs the rows in question. How do we achieve this? Well, presumably
we have a structure where a presentation module must request data from
it's data source, so in the presentation module we have something like
this:

$collection = $source->getData();

The source defines *what* the data are, of course. In most cases a
data source is just an abstraction of a particular SQL query.
getData() returns an collection, because after all, we are requesting
a (possibly empty) collection of data.

So now the presentation layer is about to begin it's work, what we in
a PagedPresentation would expect is something like this:

$offset = $_GET['pageNum'] * $itemsPerPage;
$data = range($collection, $offset, $itemsPerPage)
applyTemplate($data);

So does this interface make sense? It does IMO, and it can be
implemented in a fashion that makes it as efficient as a solution
which supplies the offset and the number of items per page at an
earlier stage. Why? Because we don't have to actually perform the
query until the data are accessed, and they aren't really accessed
until applyTemplate() is called! In this case range() is a selection
utility which defines a certain subrange of the collection, but it doesn't
really have to do it, nor does $source need be an actual query result, they
are just a facade designed to make the interface coherent and highly
reusable, the implementation can be made as efficient as possible using any
trick in the book.

So let me stress that this was the *implementation* of PagedPresentation, to
use PagedPresentation we would expect an interface like this:

$source = new DataSource("SELECT ALL RED CARS FROM 1998");
$presentation = new PagedPresentation($source, $templateFile, $itemsPrPage);
$presentation->display();

All highly simplified, of course.

> $dbobject->setRowsPerPage()
> $dbobject->setPageNo()
>
> Both of these are optional because there is a default value for
> $rows_per_page inside the class, and $pageno will default to whatever
> was used previously for this object in the current session.

And the same can be done if you put this stuff in the presentation layer. I
don't see the problem.



> My presentation layer does not calculate the offset as that is done
> inside the data access layer - all it does is specify a page number
> (which comes from a hyperlink in my pagination area).

I you think that such a basic calculation violates KISS, then you're taking
it too far IMO. And besides, it's more important to apply KISS interfaces.
In this case you have a less than perfectly clean, and IMO less intuitive
interface.

>> You have to write a new class which inherits the abstract class and has
>> variables to represent the fields in the DB. Quote from Tony's page:
>>
>> function Database_Table ()
>> {
>> $this->tablename = 'default';
>> $this->dbname = 'default';
>> $this->rows_per_page = 10;
>>
>> $this->fieldlist = array('column1', 'column2', 'column3');
>> $this->fieldlist['column1'] = array('pkey' => 'y');
>> } // constructor
>>
>> The variable $fieldlist is used to list all the columns within that
>> table, and to identify which is the primary key. How this is used will
>> become apparent
>>
>> End quote.
>>
>> So when you add a field to your DB, you also have to change the class,
>> this sort of dependency can quickly lead to maintenance problems,
>> especially if someone else is supposed to use the classes.
>>
>

> Having a separate class for each individual database table is supposed
> to be a GOOD idea in OOP as it encapsulates all the information
> required to read/write/update/delete that particular database table.
> This includes a list of all fields and their characteristics so that
> basic validation can be done by the code which is inherited from the
> abstract class instead of having to write a separate set of validation
> code for each table.

Well, there's a much more interesting principle that applies here, and that
is the principle of orthogonality. You want to achieve two goals, that of
being able to simplify and reuse INSERT/UPDATE/DELETE/SELECT code, and that
of being able to validate data.

There is a very common error which people do the first time they do OO, and
that is to overuse inheritance. It's not that strange really as there's
always a lot og fighting over inheritance. But object composition is a
second technique that frequently applies, you can read more about this in
[1] (p. 18-20). In this case you can write two classes, and through object
composition solve the same problem. You won't need to write new classes to
handle new tables, which certainly is a lot simpler and cleaner.

If you think about it, it really makes sense. *Validating* data is a
completely different thing from ferrying data back and forth between a
DBMS, so why should the two be merged into one schizophrenic class?

Data-directed programming is the heart of OO, and this is brilliantly
covered in [2]. If you really want to understand OO I suggest giving it a
read. It teaches the basic principles that underlies OO, and it does so
without drowning the dicussion in empty buzzwords. A true gem.



> If the physical database table is changed then the class which
> contains information about that table is also changed. This is not a
> maintenance problem, it is basic common sense. If a programmer changes
> a database table without updating the code which accesses that table
> then he is a ****KING PLONKER of the first order.

Certainly there are plenty of cases when you need to rewrite parts of the
system due to changes in the database, but the it's still important to
*minimize* the number of such changes that need to be made.

> In my method there
> is one class per table, so the changes have to be made in only one
> place. What could be easier than that?

One where there is just two classes regardless of the number of tables, so
you didn't have to make any changes :)

One of your early complaints was that people just said you were wrong
without pointing out a better way. I think there's been plenty of ideas on
how to improve the design by now :)

André Næss

References:
[1] Gamma et.al., Design Patterns
http://www.amazon.com/exec/obidos/tg/detail/-/0201633612/qid=1060622571/sr=8-1/ref=sr_8_1/002-8378363-3212024?v=glance&s=books&n=507846

[2] Abelson and Sussman, Structure and Interpretation of Computer Programs,
Chapter 2 "Building Abstraction with Data"
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-13.html#%_chap_2

André Næss

unread,
Aug 11, 2003, 4:47:09 PM8/11/03
to
Tony Marston:

> The reason that I use separate variables instead of parameters on the
> getData() method is that the number of possible parameters is quite
> large and most of them are optional. So instead of having a long list
> of parameters on the getData() method I find it easier to use a
> separate set...() method whenever I DO have a value that I want to be
> used. That is my personal preference. If I have a method which has a
> small number of parameters then I would stick to supplying them on the
> method call as you suggest.
>
> The difference lies in the number of parameters and how many of them
> are optional.

Keyword arguments are very practical in this type of problem, but they are
unfortunately not supported by PHP. A common workaround is to use assoc
arrays to pass the parameters, something that had felt a lot cleaner had
PHP supported a more practical array notation than
array('a'=>1, 'b'=>2, 'c'=>3).

My favorite:
['a': 1, 'b': 2, 'c': 3]

André Næss

Jochen Daum

unread,
Aug 11, 2003, 5:55:45 PM8/11/03
to
Hi Tony!
On 11 Aug 2003 03:28:11 -0700, to...@marston-home.demon.co.uk (Tony
Marston) wrote:

snip


>
>Having a separate class for each individual database table is supposed
>to be a GOOD idea in OOP as it encapsulates all the information
>required to read/write/update/delete that particular database table.
>This includes a list of all fields and their characteristics so that
>basic validation can be done by the code which is inherited from the
>abstract class instead of having to write a separate set of validation
>code for each table.

I disagree here. This means you write the same code for each table -
select, insert, update, delete again and again. But basically its
always the same.

>
>If the physical database table is changed then the class which
>contains information about that table is also changed. This is not a
>maintenance problem,

It is, if there is a standard way to handle a varchar, or a datetime.

> it is basic common sense. If a programmer changes
>a database table without updating the code which accesses that table
>then he is a ****KING PLONKER of the first order.

Understood.

> In my method there
>is one class per table, so the changes have to be made in only one
>place. What could be easier than that?

One class for all. Changes are made in a data dictionary. That the
approach I take daily. You can see it in the project below.

Jochen

Tony Marston

unread,
Aug 12, 2003, 3:01:06 AM8/12/03
to
Jochen Daum <joche...@cans.co.nz> wrote in message news:<h14gjv8lr2r35qdt1...@4ax.com>...

> Hi Tony!
> On 11 Aug 2003 03:28:11 -0700, to...@marston-home.demon.co.uk (Tony
> Marston) wrote:
>
> snip
> >
> >Having a separate class for each individual database table is supposed
> >to be a GOOD idea in OOP as it encapsulates all the information
> >required to read/write/update/delete that particular database table.
> >This includes a list of all fields and their characteristics so that
> >basic validation can be done by the code which is inherited from the
> >abstract class instead of having to write a separate set of validation
> >code for each table.
>
> I disagree here. This means you write the same code for each table -
> select, insert, update, delete again and again. But basically its
> always the same.

No I do not write the same code again and again. The code which
handles select/insert/update/delete is inherited from the parent class
so it is inherited by every subclass.


> >If the physical database table is changed then the class which
> >contains information about that table is also changed. This is not a
> >maintenance problem,
>
> It is, if there is a standard way to handle a varchar, or a datetime.

By 'standard' processing I mean the following:-
- for char/varchar, is it required or optional? does it exceed the max
length?
- for datetime, is the date portion a valid date?, is the time portion
a valid time?
- for numbers, is the input valid numeric? is it signed or unsigned?
does it have too many significant digits? does it have too many
decimal digits?
- for key fields, is the key already in use?

Non-standard validation, such as 'is date A greater than date B?' is
handled by custom code within the class for that table.

> > it is basic common sense. If a programmer changes
> >a database table without updating the code which accesses that table
> >then he is a ****KING PLONKER of the first order.
>
> Understood.
>
> > In my method there
> >is one class per table, so the changes have to be made in only one
> >place. What could be easier than that?
>
> One class for all. Changes are made in a data dictionary. That the
> approach I take daily. You can see it in the project below.
>
> Jochen

My data dictionary is held within each table class, not in a separate
database. I do not want the overhead of accessing a separate database
to get at my validation rules.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 12, 2003, 3:13:18 AM8/12/03
to
matty <matt...@askmenoquestions.co.uk> wrote in message news:<%1LZa.1232$z7.3...@wards.force9.net>...
> Tony Marston wrote:
>
> <snip>

>
> > Having a separate class for each individual database table is supposed
> > to be a GOOD idea in OOP as it encapsulates all the information
> > required to read/write/update/delete that particular database table.
> > This includes a list of all fields and their characteristics so that
> > basic validation can be done by the code which is inherited from the
> > abstract class instead of having to write a separate set of validation
> > code for each table.
>
> I have to disagree with you here! Having a separate class *instance* is
> good OO, having a separate *class* is bad OO, since you lose all the
> potential benefits of low maintenance, etc.

I disagree most strongly. I have a separate class for each database
table as that contains the validation rules and special processing
considerations for that table. This is called 'encapsulation' which is
*good* OO programming. If there is only one class for ALL database
tables then where do I put the business rules for each individual
table? Where is the encapsulation in that idea?


> How about something like this:
>
> (obviously not a specific implementation, more a hypothetical description
> of an interface)
>
> $tablea = new DBTable($database, $user, $password, $table);
> foreach(array('widgetid', 'manufr', 'cost', 'colour', 'weight') as $item)
> {
> $tablea->AddField($item);
> }
> $tablea->AddConstraint('cost > 20.00');
> $tablea->AddConstraint('colour = \'blue\'');
> if (!array_key_exists('offset', $_GET) or !preg_match('/^[0-9]+/', $_GET['offset']))
> {
> $dboffset = 0;
> }
> $resultarray = $tablea->GetPageList($offset, $config['database']['pagelength']);
>
> Then you can change database, change fields, paging length, WHERE constraints, etc
> without having to change the *class*, merely the class instance. You only have to change
> DBTable class code if you're changing its functionality.
>
> Otherwise, in a system with 12 database tables, having a different class for each
> table? That's not good.
>
> Matt

Your idea requires too much effort. You have a generic table class
which contains no business rules, but you have a separate object which
creates an instance of this generic class then tells it what the
business rules are. In my method I do not build a class that tells the
generic class what the business rules are, I have a subclass which
contains those rules and which inherits all the generic code from the
base class.

We both seem to have a separate class for each table, but implemented
differently. I maintain that my method is easier.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 12, 2003, 3:30:56 AM8/12/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bh0j9s$bar$1...@maud.ifi.uio.no>...

> Tony Marston:
>
> >> The information is typical formatting information. I think it would be
> >> much cleaner if you allowed for two more arguments to getData() that
> >> defined how many rows to retrieve, and what offset to start at. The
> >> organization of data into pages belongs in presentation code.
> >
> > Rather have have extra arguments in my 'getData' method I have
> > separate setters for $rows_per_page and $pageno, with a getter for
> > $lastpage. The reason for this is that a default value for
> > $rows_per_page can be defined in the class constructor.
>
> But if you say that these variables are in fact selection criteria, then
> certainly you must agree that seeing as $where is a collection of selection
> criteria, and it's being passed to getData(), it would be much more
> consistent to pass them as parameters!

The number of possible parameters on the getData() method is quite
large, and as most of them are optional I find it easier to use a
set..() method for each of these variables only when a value is
available. As I save each object in the session array it also means
that any value set in one operation is maintained throughout the
session until it is changed or reset.

Also, the number of values I want returned may be more than, and as
PHP only allows one value to be returned with each function call I
save this as a separate object variable and use a get..() method it is
needed.

> <snip>


> KISS is a very good idea indeed. My point was that if you want to partake in
> a community you have to follow the rules of the community, if you disagree,
> you have to lobby your disagreement to the other members.

What is obvious from the various postings in this thread is that
different people have totally different ideas about what is *good/not
good* OO programming. Some people prefer simple solutions while others
seem to go out of their way to invent the most convoluted solutions
just to satisfy their personal interpretations of the *rules* of OOP.
I follow the KISS principle.

> >> And in general I think your design is bad because you have to create a
> >> new class for every table you create, and you have to recode both the
> >> table and the class every time you change the table, which obviously
> >> doubles the chances of bugs. I can't really see how this can save you
> >> very much work I guess.
> >
> >
> > You have missed the point about my abstract database class. Each
> > database table has its own class which is a subclass of the abstract
> > class, therefore it inherits all the properties and methods of the
> > abstract class. Each table class therefore need only contain extra
> > code which is specific to that class, such as a list of field names,
> > validation rules, relationships, etc.
>
> Precisely. And it is this code which leads to a problematic dependency
> between the DB and the class. I understand the point of reusing code to
> generate SELECT/INSERT/UPDATE/DELETE statements, but you can do that
> without having to create a class for every table you have.
>
> André Næss

Then where do I maintain the business rules for each individual
database table? In a separate class? That is what I have, but each
table class is a subclass of the generic database class, not a
separate class in its own right.

Tony Marston
http://tonymarston.net/

Tony Marston

unread,
Aug 12, 2003, 3:34:09 AM8/12/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bh8o4t$38m$2...@maud.ifi.uio.no>...

I prefer to use the features that the language does allow and not
waste my time in dreaming up features that it does not.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 12, 2003, 3:42:54 AM8/12/03
to
ng4rrj...@rediffmail.com (R. Rajesh Jeba Anbiah) wrote in message news:<abc4d8b8.03081...@posting.google.com>...

> to...@marston-home.demon.co.uk (Tony Marston) wrote in message news:<7588a50f.03080...@posting.google.com>...
> > On my website I have an article
> > http://www.tonymarston.net/php-mysql/databaseobjects.html
>
> Kudos! Nice work... My points regarding the OOP style:
>
> 1. I could see the way you pass values to the methods contradicts the
> OOP style. For example:

Contradicts what style? Where is this *style* documented?

> global $dbconnect, $query; <=======//
> $dbconnect = db_connect($this->dbname) or trigger_error("SQL",
> E_USER_ERROR);
>
> at the "updateRecord ($fieldarray)" method.
>
> You could have used setDBLink($db_link) to the class....

I could have done it in many different ways, but I am happy with the
method I have chosen. I see no reason to switch to another method
unless someone can point out some positive advantages.

> 2.
> function Database_Table ()
> {
> $this->tablename = 'default';
> $this->dbname = 'default';
> $this->rows_per_page = 10;
>
> $this->fieldlist = array('column1', 'column2', 'column3');
> $this->fieldlist['column1'] = array('pkey' => 'y');
> } // constructor
>
> If you this style, there won't be any reusability.

Then you do not understand OO programming. All the business rules for
a database table are maintained in a single class, so when any
presentation object wants to communicate with that table it uses that
table's class. Thus I can have many presentation objects all reusing
the same table class. That is where *reusability* comes from. This is
the basis of the 3 tier architecture which I used in a previous
language.

> <snip>

> This is my point. I may be wrong though...

You may well be!

Tony Marston
http://www.tonymarston.net/

R. Rajesh Jeba Anbiah

unread,
Aug 12, 2003, 10:01:18 AM8/12/03
to
to...@marston-home.demon.co.uk (Tony Marston) wrote in message news:<7588a50f.03081...@posting.google.com>...

> ng4rrj...@rediffmail.com (R. Rajesh Jeba Anbiah) wrote in message news:<abc4d8b8.03081...@posting.google.com>...
> > to...@marston-home.demon.co.uk (Tony Marston) wrote in message news:<7588a50f.03080...@posting.google.com>...
> > > On my website I have an article
> > > http://www.tonymarston.net/php-mysql/databaseobjects.html

> Contradicts what style? Where is this *style* documented?

> > global $dbconnect, $query; <=======//

This is what I meant---passing variables to the methods. This
style necessitates that you must have the variable "$dbconnect"
outside of the class. In otherwords, you should use/define the
variable "$dbconnect" whenever you use the class. IMO, this is not a
good practice/style. For example, I want to use your class and if
there is a mechanism to pass my "$DB___Connection__Link" variable to
your class, I can happily use the class without any modification. So,
my point is: this is not a good style to pass the variable to the
methods.


---> Contradicts what style? Where is this *style* documented?

All the time, we cannot refer the ___law books___... It comes from
the practice and excercises.


> > 2.
> > function Database_Table ()
> > {
> > $this->tablename = 'default';
> > $this->dbname = 'default';
> > $this->rows_per_page = 10;
> >
> > $this->fieldlist = array('column1', 'column2', 'column3');
> > $this->fieldlist['column1'] = array('pkey' => 'y');
> > } // constructor
> >
> > If you this style, there won't be any reusability.
>
> Then you do not understand OO programming.

Yes.

>All the business rules for
> a database table are maintained in a single class, so when any
> presentation object wants to communicate with that table it uses that
> table's class. Thus I can have many presentation objects all reusing
> the same table class. That is where *reusability* comes from. This is
> the basis of the 3 tier architecture which I used in a previous
> language.

I was refering *reusabiliy* on different projects (Not on a
single project in which your database is "foo" and table name is
"foo").

Also, if the class you mentioned is for single purpose, it's ok.
But, you've written a *tutorial*. Everybody who reads the *tutorial*
will be tempted to follow the style. If they follow the style, they
may suffer when it comes to reusability rules on more than 1 project.

> > This is my point. I may be wrong though...
>
> You may well be!

Yes... I'm wrong. But, IMO you're also not correct..

---
"Something is less than nothing"
Email: rrjanbiah-at-Y!com

Michiel

unread,
Aug 12, 2003, 10:35:47 AM8/12/03
to
Andy Jeffries wrote:

> On Thu, 07 Aug 2003 12:16:55 +0000, Martin Wickman wrote:
>
>>>4) The language allows me to do it, therefore it cannot be wrong.
>>
>>Yup, otherwise you'd get a syntax error...
>
>
> I disagree, something can be "wrong" as in an ugly way of doing something
> but by syntactically correct.
>
> However, I agree there is nothing wrong with what he is doing.
>

If we're talking about doing things wrong from an OOP point of view,
there's a shitload of things you can do wrong. This doesn't mean the
same thing is wrong from a PHP point of view, since PHP is not truly OO.

Michiel

unread,
Aug 12, 2003, 10:40:44 AM8/12/03
to
matty wrote:
> Tony Marston wrote:
>
> <snip>

>
>>$rows_per_page (to set the page size)
>>$page_no (to request a particular page number)
>>$lastpage (returns the highest possible page number)
>>
>>which he considers to related to formatting rather than the data
>>itself, and as such is *bad* programming.
>
>
> I'd agree, and say that he's using the output buffer of the canal.
>
> I've got something similar, although I have a subclass for paged output,
> but much the same kind of thing.
>
> Apart from nicer presentation, paging the results allows you to reduce
> communication with the database server; if you insist on returning the
> entire result set from the query, and *then* choosing a subset of it
> from the PHP code, you introduce an unnecessary layer, which can be
> done away with entirely by using "LIMIT x, y" in the query.

AND make it mysql dependent. The LIMIT clause is not widely supported.
Besides, mysql will most probably allocate the whole result set and
return only part of it, so it doesn't matter all that much.

>
> I think you've done it the right way (but then I would, 'cos I have too!)


>
>
>>5) It is simple and it works, therefore it cannot be all that bad.
>>

>>Do you people out there in PHP-land have any opinions on this matter?


>>Is this critocism justified or not?
>
>

> Definitely unjustified. Is he a first-year S/W Eng student by any chance???


Michiel

unread,
Aug 12, 2003, 10:48:32 AM8/12/03
to
Tony Marston wrote:
> On my website I have an article
> http://www.tonymarston.net/php-mysql/databaseobjects.html which
> describes an abstract class I have written to control all access to my
> databases. Someone who is supposed to be a respected member of the PHP
> community has informed me that my class breaks the rules of OO
> programming and is therefore unworthy of serious consideration. To be
> specific he complained that my class contains the following
> variables:-

>
> $rows_per_page (to set the page size)
> $page_no (to request a particular page number)
> $lastpage (returns the highest possible page number)
>
> which he considers to related to formatting rather than the data
> itself, and as such is *bad* programming.
>
> I personally think that he is talking out of the wrong end of his
> alimentary canal for the following reasons:-

>
> 1) Those variables are not for *formatting*, they are for *data
> selection*. When my presentation layer communicates with a database
> object it is basically saying "get me the data that satisfies this
> selection criteria" part of which is "based on a page size of
> $row_per_page get me the records for page $page_no, and tell me the
> highest possible page available".
>
> 2) Despite me asking him what he considers to be the *right* way of
> doing things he has failed to respond, probably because he doesn't
> know the answer.

>
> 3) There is nothing in any OOP literature I have read that says what I
> am doing is wrong, there it is not wrong.
>
> 4) The language allows me to do it, therefore it cannot be wrong.
>
> 5) It is simple and it works, therefore it cannot be all that bad.
>
> Do you people out there in PHP-land have any opinions on this matter?
> Is this critocism justified or not?
>
> Tony Marston
> http://www.tonymarston.net/

You've done a good job. Certainly. But.... if you learn some more about
OOP you could use it much more effective. And to be honest... a database
access layer is not the most difficult thing to write. You can afford to
make some design errors and still have a useful class. If you start
writing more complex software (probably soon) you would get into trouble
if you keep coding this style.

My advice:
- Learn some more about 'design patterns'. They can help you.
- Learn UML (unified modelling language), it helps you to first
conceptualize your ideas on a higher design level.
- Take a trip to phpclasses.org. Ther are a multitude of classes there
that do exactly what yours does. Maybe you can learn from it.

HTH, Michiel.

André Næss

unread,
Aug 12, 2003, 1:13:09 PM8/12/03
to
Tony Marston:

>> Keyword arguments are very practical in this type of problem, but they
>> are unfortunately not supported by PHP. A common workaround is to use
>> assoc arrays to pass the parameters, something that had felt a lot
>> cleaner had PHP supported a more practical array notation than
>> array('a'=>1, 'b'=>2, 'c'=>3).
>>
>> My favorite:
>> ['a': 1, 'b': 2, 'c': 3]
>>
>> André Næss
>
> I prefer to use the features that the language does allow and not
> waste my time in dreaming up features that it does not.

My main goal was to point out that assoc-arrays as parameters sometimes can
be an acceptable trick and it is supported by PHP, so that's not something
I'm dreaming up.

And I'd also like to point out that PHP has largely been developed as a
reply to the "dreaming" of it's users. That's probably why it's so popular!

André Næss

André Næss

unread,
Aug 12, 2003, 1:16:38 PM8/12/03
to
Tony Marston:

>> >Having a separate class for each individual database table is supposed
>> >to be a GOOD idea in OOP as it encapsulates all the information
>> >required to read/write/update/delete that particular database table.
>> >This includes a list of all fields and their characteristics so that
>> >basic validation can be done by the code which is inherited from the
>> >abstract class instead of having to write a separate set of validation
>> >code for each table.
>>
>> I disagree here. This means you write the same code for each table -
>> select, insert, update, delete again and again. But basically its
>> always the same.
>
> No I do not write the same code again and again. The code which
> handles select/insert/update/delete is inherited from the parent class
> so it is inherited by every subclass.
>

>[snip]


>
> Non-standard validation, such as 'is date A greater than date B?' is
> handled by custom code within the class for that table.

So in other words you have to rewrite those "non-standard" constraints every
time you need them. The problem is that you haven't properly decoupled two
different entities (data validation and database access). See my rather
long post which goes into this and explains how object composition rather
than inheritance leads to a much cleaner, simpler and more maintainable
solution in this particular case.

André Næss

André Næss

unread,
Aug 12, 2003, 1:22:30 PM8/12/03
to
Tony Marston:

>> 2.
>> function Database_Table ()
>> {
>> $this->tablename = 'default';
>> $this->dbname = 'default';
>> $this->rows_per_page = 10;
>>
>> $this->fieldlist = array('column1', 'column2', 'column3');
>> $this->fieldlist['column1'] = array('pkey' => 'y');
>> } // constructor
>>
>> If you this style, there won't be any reusability.
>
> Then you do not understand OO programming. All the business rules for
> a database table are maintained in a single class

The problem is that you're too hung up on *classes*, and forgetting about
their *instances* (objects)! This is fairly common for people starting out
with OOP, so you're not alone.

André Næss

André Næss

unread,
Aug 12, 2003, 1:35:40 PM8/12/03
to
Tony Marston:

> André Næss <andrena.spa...@ifi.uio.no> wrote in message
> news:<bh0j9s$bar$1...@maud.ifi.uio.no>...
>> Tony Marston:
>>
>> >> The information is typical formatting information. I think it would be
>> >> much cleaner if you allowed for two more arguments to getData() that
>> >> defined how many rows to retrieve, and what offset to start at. The
>> >> organization of data into pages belongs in presentation code.
>> >
>> > Rather have have extra arguments in my 'getData' method I have
>> > separate setters for $rows_per_page and $pageno, with a getter for
>> > $lastpage. The reason for this is that a default value for
>> > $rows_per_page can be defined in the class constructor.
>>
>> But if you say that these variables are in fact selection criteria, then
>> certainly you must agree that seeing as $where is a collection of
>> selection criteria, and it's being passed to getData(), it would be much
>> more consistent to pass them as parameters!
>
> The number of possible parameters on the getData() method is quite
> large, and as most of them are optional I find it easier to use a
> set..() method for each of these variables only when a value is
> available. As I save each object in the session array it also means
> that any value set in one operation is maintained throughout the
> session until it is changed or reset.

Well I guess that's an acceptable choice based on the fact that PHP does't
support keyword arguments.

However, I can only see that getData() supports *one* argument, $where?



> Also, the number of values I want returned may be more than, and as
> PHP only allows one value to be returned with each function call I
> save this as a separate object variable and use a get..() method it is
> needed.

A better approach would be to return a ResultObject, which you could then
query for information about the different values you want returned. This
would encapsulate these data properly, and you're going on and on about
enacpsulation, so that should appeal to you right? :)

>> KISS is a very good idea indeed. My point was that if you want to partake
>> in a community you have to follow the rules of the community, if you
>> disagree, you have to lobby your disagreement to the other members.
>
> What is obvious from the various postings in this thread is that
> different people have totally different ideas about what is *good/not
> good* OO programming.

Indeed

> Some people prefer simple solutions while others
> seem to go out of their way to invent the most convoluted solutions
> just to satisfy their personal interpretations of the *rules* of OOP.
> I follow the KISS principle.

I think everyone wants to apply KISS as much as possible, but like with so
many other things, overuse tends to be a bad thing. Design is obviously a
subjective thing, be it buildings, cars, kitchen utensils or software. But
good design has qualities, and I think Paul Graham[1] does a nice job of
describing them.



>> > You have missed the point about my abstract database class. Each
>> > database table has its own class which is a subclass of the abstract
>> > class, therefore it inherits all the properties and methods of the
>> > abstract class. Each table class therefore need only contain extra
>> > code which is specific to that class, such as a list of field names,
>> > validation rules, relationships, etc.
>>
>> Precisely. And it is this code which leads to a problematic dependency
>> between the DB and the class. I understand the point of reusing code to
>> generate SELECT/INSERT/UPDATE/DELETE statements, but you can do that
>> without having to create a class for every table you have.
>>
>

> Then where do I maintain the business rules for each individual
> database table? In a separate class?

No, in a separate object which is an instance of a some sort class that
models business rules. You can quickly turn this into an extensible type
system, which you can reuse in *all* part of your application, not just
with the DB. (For example to validate form input.)

André Næss

[1] Taste for Makers - http://www.paulgraham.com/taste.html

Jochen Daum

unread,
Aug 12, 2003, 11:06:54 PM8/12/03
to
Hi Michiel!

On Tue, 12 Aug 2003 16:40:44 +0200, Michiel
<michiel@...NO...SPAM!*.2see.nl> wrote:

(...)


>>
>> Apart from nicer presentation, paging the results allows you to reduce
>> communication with the database server; if you insist on returning the
>> entire result set from the query, and *then* choosing a subset of it
>> from the PHP code, you introduce an unnecessary layer, which can be
>> done away with entirely by using "LIMIT x, y" in the query.
>
>AND make it mysql dependent. The LIMIT clause is not widely supported.

But can be build in other database systems with nested queries. I run
such nested queries against well indexed tables in SQL Server and
Informix and it works fine.
Thats why I integrated the appropriate Query functions into my
Database Abstraction Layer.


>Besides, mysql will most probably allocate the whole result set and
>return only part of it, so it doesn't matter all that much.

I doubt that heavily. MySQL's query optimization is very good and I
don't think it would be that stupid. I'd expect this behaviour from MS
Access.

HTH, Jochen

Jochen Daum

unread,
Aug 12, 2003, 11:07:42 PM8/12/03
to
Hi Andre!

On Tue, 12 Aug 2003 17:13:09 +0000, André Næss
<andrena.spa...@ifi.uio.no> wrote:

>Tony Marston:
>
>>> Keyword arguments are very practical in this type of problem, but they
>>> are unfortunately not supported by PHP. A common workaround is to use
>>> assoc arrays to pass the parameters, something that had felt a lot
>>> cleaner had PHP supported a more practical array notation than
>>> array('a'=>1, 'b'=>2, 'c'=>3).
>>>
>>> My favorite:
>>> ['a': 1, 'b': 2, 'c': 3]
>>>
>>> André Næss
>>
>> I prefer to use the features that the language does allow and not
>> waste my time in dreaming up features that it does not.
>
>My main goal was to point out that assoc-arrays as parameters sometimes can
>be an acceptable trick and it is supported by PHP, so that's not something
>I'm dreaming up.

I think its more than a good trick.

Jochen Daum

unread,
Aug 12, 2003, 11:11:39 PM8/12/03
to
Hi tony!

On 12 Aug 2003 00:13:18 -0700, to...@marston-home.demon.co.uk (Tony
Marston) wrote:

>matty <matt...@askmenoquestions.co.uk> wrote in message news:<%1LZa.1232$z7.3...@wards.force9.net>...
>> Tony Marston wrote:
>>
>> <snip>
>>
>> > Having a separate class for each individual database table is supposed
>> > to be a GOOD idea in OOP as it encapsulates all the information
>> > required to read/write/update/delete that particular database table.
>> > This includes a list of all fields and their characteristics so that
>> > basic validation can be done by the code which is inherited from the
>> > abstract class instead of having to write a separate set of validation
>> > code for each table.
>>
>> I have to disagree with you here! Having a separate class *instance* is
>> good OO, having a separate *class* is bad OO, since you lose all the
>> potential benefits of low maintenance, etc.
>
>I disagree most strongly. I have a separate class for each database
>table as that contains the validation rules and special processing
>considerations for that table. This is called 'encapsulation' which is
>*good* OO programming. If there is only one class for ALL database
>tables then where do I put the business rules for each individual
>table? Where is the encapsulation in that idea?
>

And I put myself on matty's side. The validation rules belong to a
table, correct, but i don't need a validation rule to check for the
length of text in each class. Same with date/time entry, select boxes
for lookup etc.

Maybe have a look at the Strategy pattern and Delegation as a concept
altogether instead of the classic inheritance model of OO.


>
>> How about something like this:
>>
>> (obviously not a specific implementation, more a hypothetical description
>> of an interface)
>>
>> $tablea = new DBTable($database, $user, $password, $table);
>> foreach(array('widgetid', 'manufr', 'cost', 'colour', 'weight') as $item)
>> {
>> $tablea->AddField($item);
>> }
>> $tablea->AddConstraint('cost > 20.00');
>> $tablea->AddConstraint('colour = \'blue\'');
>> if (!array_key_exists('offset', $_GET) or !preg_match('/^[0-9]+/', $_GET['offset']))
>> {
>> $dboffset = 0;
>> }
>> $resultarray = $tablea->GetPageList($offset, $config['database']['pagelength']);
>>
>> Then you can change database, change fields, paging length, WHERE constraints, etc
>> without having to change the *class*, merely the class instance. You only have to change
>> DBTable class code if you're changing its functionality.
>>
>> Otherwise, in a system with 12 database tables, having a different class for each
>> table? That's not good.
>>
>> Matt
>
>Your idea requires too much effort. You have a generic table class
>which contains no business rules, but you have a separate object which
>creates an instance of this generic class then tells it what the
>business rules are.

Once for each page, yes.

> In my method I do not build a class that tells the
>generic class what the business rules are, I have a subclass which
>contains those rules and which inherits all the generic code from the
>base class.
>
>We both seem to have a separate class for each table, but implemented
>differently. I maintain that my method is easier.

Hmm. I actually prefer a class for all tables.

HTH, Jochen

Jochen Daum

unread,
Aug 12, 2003, 11:15:54 PM8/12/03
to
Hi Tony!
On 12 Aug 2003 00:01:06 -0700, to...@marston-home.demon.co.uk (Tony
Marston) wrote:

>Jochen Daum <joche...@cans.co.nz> wrote in message news:<h14gjv8lr2r35qdt1...@4ax.com>...
>> Hi Tony!
>> On 11 Aug 2003 03:28:11 -0700, to...@marston-home.demon.co.uk (Tony
>> Marston) wrote:
>>
>> snip
>> >
>> >Having a separate class for each individual database table is supposed
>> >to be a GOOD idea in OOP as it encapsulates all the information
>> >required to read/write/update/delete that particular database table.
>> >This includes a list of all fields and their characteristics so that
>> >basic validation can be done by the code which is inherited from the
>> >abstract class instead of having to write a separate set of validation
>> >code for each table.
>>
>> I disagree here. This means you write the same code for each table -
>> select, insert, update, delete again and again. But basically its
>> always the same.
>
>No I do not write the same code again and again. The code which
>handles select/insert/update/delete is inherited from the parent class
>so it is inherited by every subclass.

Ok, agree on that. Similar to the other thread part, we're talking
about the business rules here maybe.


>
>> >If the physical database table is changed then the class which
>> >contains information about that table is also changed. This is not a
>> >maintenance problem,
>>
>> It is, if there is a standard way to handle a varchar, or a datetime.
>
>By 'standard' processing I mean the following:-
>- for char/varchar, is it required or optional? does it exceed the max
>length?
>- for datetime, is the date portion a valid date?, is the time portion
>a valid time?
>- for numbers, is the input valid numeric? is it signed or unsigned?
>does it have too many significant digits? does it have too many
>decimal digits?
>- for key fields, is the key already in use?

Exactly. And that stuff should be handled centrally. In web pages you
might also use Lookup fields or enumerations, which come from other
(database ) tables. This can be handled by such standard ways as well.

>
>Non-standard validation, such as 'is date A greater than date B?' is
>handled by custom code within the class for that table.

Also agreed.


>
>> > it is basic common sense. If a programmer changes
>> >a database table without updating the code which accesses that table
>> >then he is a ****KING PLONKER of the first order.
>>
>> Understood.
>>
>> > In my method there
>> >is one class per table, so the changes have to be made in only one
>> >place. What could be easier than that?
>>
>> One class for all. Changes are made in a data dictionary. That the
>> approach I take daily. You can see it in the project below.
>>
>> Jochen
>
>My data dictionary is held within each table class, not in a separate
>database. I do not want the overhead of accessing a separate database
>to get at my validation rules.

Mine is in a PHP file as well. I didn't call it Data Dictionary until
recently. Only because I discovered a system called Clarion, which
does something similar, with a "local" data dictionary.

Tony Marston

unread,
Aug 13, 2003, 3:31:21 AM8/13/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bhb19n$9sg$1...@maud.ifi.uio.no>...

> Tony Marston:
>
> > André Næss <andrena.spa...@ifi.uio.no> wrote in message
> > news:<bh0j9s$bar$1...@maud.ifi.uio.no>...

<snip>

> However, I can only see that getData() supports *one* argument, $where?

There is only one permanent argument as a lot of the other values are
entirely option and are made available by using a set..() method
before the detData() method.

An advantage I have found with this approach is I save each object in
my session array, so that when I return to an object all the previous
values held in its variables are still there, so rather than the
script which calls the getData() method having to remember all those
values so that it can pass them in the argument list, the object
itself 'remembers' all the previous values automatically and reuses
them. The calling object only has to use a set..() method on one of
these values when it wants to change it, otherwise the previous valkus
is used automatically.

> > Also, the number of values I want returned may be more than, and as
> > PHP only allows one value to be returned with each function call I
> > save this as a separate object variable and use a get..() method it is
> > needed.
>
> A better approach would be to return a ResultObject, which you could then
> query for information about the different values you want returned. This
> would encapsulate these data properly, and you're going on and on about
> enacpsulation, so that should appeal to you right? :)

That won't work as some of the values I want are not held in the
database result object.

> <snip>

> >> I understand the point of reusing code to
> >> generate SELECT/INSERT/UPDATE/DELETE statements, but you can do that
> >> without having to create a class for every table you have.
> >>
> >
> > Then where do I maintain the business rules for each individual
> > database table? In a separate class?
>
> No, in a separate object which is an instance of a some sort class that
> models business rules. You can quickly turn this into an extensible type
> system, which you can reuse in *all* part of your application, not just
> with the DB. (For example to validate form input.)
>
> André Næss

So in your approach you have a PHP script containing the validation
rules for a database table which then has to set..() these rules in a
separate object before they can be processed?

My approach is to have the validation rules for each database table
held in a separate script which just happens to be a class where those
rules can be processed in situ, therefore I do not have to waste time
in sending those rules to another object before they can be processed.
My method seems neater somehow.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 13, 2003, 3:46:49 AM8/13/03
to
ng4rrj...@rediffmail.com (R. Rajesh Jeba Anbiah) wrote in message news:<abc4d8b8.03081...@posting.google.com>...

<snip>


> ---> Contradicts what style? Where is this *style* documented?
>
> All the time, we cannot refer the ___law books___... It comes from
> the practice and excercises.

You mean personal preference. My *style* is to write simple,
efficient, maintainable, reusable code based upon decades of
experience using a variety of 2nd, 3rd and 4th generation languages.



> >All the business rules for
> > a database table are maintained in a single class, so when any
> > presentation object wants to communicate with that table it uses that
> > table's class. Thus I can have many presentation objects all reusing
> > the same table class. That is where *reusability* comes from. This is
> > the basis of the 3 tier architecture which I used in a previous
> > language.
>
> I was refering *reusabiliy* on different projects (Not on a
> single project in which your database is "foo" and table name is
> "foo").

The database name is not tied to a project, it is specified within the
class for each individual database table. A project can have many
database tables existing on more than one database.

> Also, if the class you mentioned is for single purpose, it's ok.
> But, you've written a *tutorial*. Everybody who reads the *tutorial*
> will be tempted to follow the style. If they follow the style, they
> may suffer when it comes to reusability rules on more than 1 project.

It is an example of how to use PHP's OO capabilities to produce a
reusable class (through inheritance bu subclassing) to access a
database. The fact that some people would choose a different method is
their choice. When it comes to programming there is no single *right*
way. There are methods that work and methods that don't; there are
methods which are easy to implement and methods which are complex;
there are methods which achieve a result in 10 lines of code while
others take hundreds; there are methods which use a large number of
simple components while others use a small number of complex
components. My point is that variety is the spice of life, and I have
produced sample code which works and which is simple. If you do not
like my *style* then I don't care. It is results that count.

> > > This is my point. I may be wrong though...
> >
> > You may well be!
>
> Yes... I'm wrong. But, IMO you're also not correct..

Then we agree to disagree.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 13, 2003, 3:52:43 AM8/13/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bhb0h1$9p8$3...@maud.ifi.uio.no>...
> Tony Marston:
>
<snip>

> > Then you do not understand OO programming. All the business rules for
> > a database table are maintained in a single class
>
> The problem is that you're too hung up on *classes*, and forgetting about
> their *instances* (objects)! This is fairly common for people starting out
> with OOP, so you're not alone.
>
> André Næss

I am aware of the ifference between classes and objects, thank you
very much. If I want to access a particular database table then I
create an object (instance) from the class which contains all the
business rules for that table. I do not create an instance of a
generic class and then have to feed it the rules for the database
table I wish to access.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 13, 2003, 4:07:07 AM8/13/03
to
Michiel <michiel@...NO...SPAM!*.2see.nl> wrote in message news:<3f38fe40$0$49100$e4fe...@news.xs4all.nl>...
> Tony Marston wrote:

<snip>


> You've done a good job. Certainly. But.... if you learn some more about
> OOP you could use it much more effective.

More effective? In what way? Surely I have written an abstract class
which can be used to access any database table, where subclasses are
created to contain the specific business rules for individual database
tables. What can be more effective than that?

> And to be honest... a database
> access layer is not the most difficult thing to write.

Yet as can be seen from this thread everybody seems to have a
different way of writing one.

> You can afford to
> make some design errors and still have a useful class.

That is true for all software development.

> If you start
> writing more complex software (probably soon) you would get into trouble
> if you keep coding this style.

I have been using this style for over a year and rather than cause
problems it has provided me with a large chunk of reusable code which
saves a lot of development time.

> My advice:
> - Learn some more about 'design patterns'. They can help you.

Some people's ideas on design patterns are just as screwy as their
ideas on OOP.

> - Learn UML (unified modelling language), it helps you to first
> conceptualize your ideas on a higher design level.

I have been designing and writing for over 20 years and I see no
advantage in using UML. In fact on one project I worked on UML turned
out to be a great way to waste time.

> - Take a trip to phpclasses.org. Ther are a multitude of classes there
> that do exactly what yours does. Maybe you can learn from it.

I found too many classes with too many different styles, which is why
I decided to write my own class based on the sucessfull implementation
of the 3 tier architecture in another language which had a separate
service component for each table in the database, and which contained
all the business rules for that database table. All I did was change
'service component' into 'class' and it has worked very well.

Tony Marston
http://www.tonymarston.net/

André Næss

unread,
Aug 13, 2003, 3:40:23 PM8/13/03
to
Tony Marston:

> André Næss <andrena.spa...@ifi.uio.no> wrote in message
> news:<bhb0h1$9p8$3...@maud.ifi.uio.no>...
>> Tony Marston:
>>
> <snip>
>
>> > Then you do not understand OO programming. All the business rules for
>> > a database table are maintained in a single class
>>
>> The problem is that you're too hung up on *classes*, and forgetting about
>> their *instances* (objects)! This is fairly common for people starting
>> out with OOP, so you're not alone.
>>
>> André Næss
>
> I am aware of the ifference between classes and objects, thank you
> very much.

That's fine. What I'm saying is that you haven't yet appreciated the power
of object composition, and because of this you apply inheritance too much.

André Næss

André Næss

unread,
Aug 13, 2003, 6:56:42 PM8/13/03
to
Tony Marston:

> André Næss <andrena.spa...@ifi.uio.no> wrote in message
> news:<bhb19n$9sg$1...@maud.ifi.uio.no>...
>> Tony Marston:
>>
>> > André Næss <andrena.spa...@ifi.uio.no> wrote in message
>> > news:<bh0j9s$bar$1...@maud.ifi.uio.no>...
>
> <snip>
>
>> However, I can only see that getData() supports *one* argument, $where?
>
> There is only one permanent argument as a lot of the other values are
> entirely option and are made available by using a set..() method
> before the detData() method.
>
> An advantage I have found with this approach is I save each object in
> my session array, so that when I return to an object all the previous
> values held in its variables are still there, so rather than the
> script which calls the getData() method having to remember all those
> values so that it can pass them in the argument list, the object
> itself 'remembers' all the previous values automatically and reuses
> them. The calling object only has to use a set..() method on one of
> these values when it wants to change it, otherwise the previous valkus
> is used automatically.

That sounds very strange. Objects have states, sessions are a way to
maintain state. So your maintaining the state of something that already has
a state, or something like that.

The "remembering" you're talking about is just code, and code is very static
in nature. If you in your code write:

getData("color=red AND buildyear > 1999", 10, 10)

Then certainly the arguments won't change between runs. The code "remembers"
them, if you like. And if you use session you still have to initialize them
at some point anyway, and that is done through code!

Likewise if you write
$sometable->setPageCount(10);

Every time this script executes the object will have the same state, so I
can't understand why you need to stuff it into a session.

But I might be misunderstanding you, could you possibly supply an example
where using sessions is beneficial in the way you're describing?

A little tip: you don't have to serialize data that you stuff into the
_SESSION array, PHP takes care of that for you. See the paragraph just
after the "Caution" block here: http://www.php.net/session



>> > Also, the number of values I want returned may be more than, and as
>> > PHP only allows one value to be returned with each function call I
>> > save this as a separate object variable and use a get..() method it is
>> > needed.
>>
>> A better approach would be to return a ResultObject, which you could then
>> query for information about the different values you want returned. This
>> would encapsulate these data properly, and you're going on and on about
>> enacpsulation, so that should appeal to you right? :)
>
> That won't work as some of the values I want are not held in the
> database result object.

The object will contain what you define it to contain, you have to model it
for your needs of course! One of the points of OO is that you model the
world according to what suits your problem (abstraction). You don't have to
*mirror* it.

>> <snip>
>
>> >> I understand the point of reusing code to
>> >> generate SELECT/INSERT/UPDATE/DELETE statements, but you can do that
>> >> without having to create a class for every table you have.
>> >>
>> >
>> > Then where do I maintain the business rules for each individual
>> > database table? In a separate class?
>>
>> No, in a separate object which is an instance of a some sort class that
>> models business rules. You can quickly turn this into an extensible type
>> system, which you can reuse in *all* part of your application, not just
>> with the DB. (For example to validate form input.)
>>
>> André Næss
>
> So in your approach you have a PHP script containing the validation
> rules for a database table which then has to set..() these rules in a
> separate object before they can be processed?

Say I wanted to talk to the table "cars". I'd compose an object by creating
an instance of a Table class and add rules represented as objects to it. Of
course, the business rules should be taken care of by the DBMS, not your
application code, but unfortunately that is not completely possible in
current SQL systems. So let's take a simple rule like "the name of the car
should be at least 1 character, and no more than 32". To model this I'd
create a String object that has this limitation built in, and link it to
the 'name' field in the Table object. Other common data types are Number,
Date, File, Time, Creditcard etc.

These are fairly simple type validations, but they should go a long way.
You'll probably also want to have some sort of generic Rule object for rare
cases where none of the available objects suffice, and you don't want to
create a new class. It is of course very important that these things are
implemented separately, so that they can be reused whenever you need to
validate any data.

But the database can enforce a lot of constraints, and one should really put
as much business logic into the database as possible because:

* It's less work
* It's safer from bugs, because the DBMS developers have (hopefully) tested
it properly.
* It's most likely faster.

I see that you among other things have code to enforce foreign key
constraints, but wouldn't it be much better not to need that code at all?



> My approach is to have the validation rules for each database table
> held in a separate script which just happens to be a class where those
> rules can be processed in situ, therefore I do not have to waste time
> in sending those rules to another object before they can be processed.
> My method seems neater somehow.

What sort of time are you wasting? Are you saying that writing a whole new
class is better than instantiating a few objects?

The point here is that you have to think about what is static and what is
dynamic in your application. Now, the concept of a database table is
certainly static, and so are data types and the concept of a constraints.
But databases are dynamic, in any given application you will have different
databases, with different data types and different constraints. In general
you want to use classes for that which is static, and hence not application
specific or frequently changing, and objects for the other things. Abstract
concepts are classes, their instances are objects. IMO The table 'cars' is
not an abstract concept but an object in the world.

I guess this boils down to matter of personal taste. But one of the
hallmarks of good designers is that they have a gut-feeling for what's good
design and what's not, and I think that if you ask some good designers they
will tell you that an approach which uses instances of a single Table class
is better than one which requires the declaration of a new class for each
new table. A good advice is probably to pretend there is a sort of tax on
creating new classes.

And just to make sure we're not in total disagreement, I think you are
absolutely right in what you say in the bullet-list in the "Background"
section.

André Næss

R. Rajesh Jeba Anbiah

unread,
Aug 14, 2003, 3:52:05 AM8/14/03
to
> ng4rrj...@rediffmail.com (R. Rajesh Jeba Anbiah) wrote in message news:<abc4d8b8.03081...@posting.google.com>...
>
> <snip>
>
> > ---> Contradicts what style? Where is this *style* documented?
> >
> > All the time, we cannot refer the ___law books___... It comes from
> > the practice and excercises.
>
> You mean personal preference.
>My *style* is to write simple,
> efficient, maintainable, reusable code based upon decades of
> experience using a variety of 2nd, 3rd and 4th generation languages.

But, I'm sure you haven't done any projects with PHP OOP or you
have done limited projects with other OOP languages.

> It is an example of how to use PHP's OO capabilities to produce a
> reusable class (through inheritance bu subclassing) to access a
> database.

You always mean inheritance. OOP is more than inheritance.

>I have
> produced sample code which works and which is simple.

Following code is also a valid ISO C code to findout whether the
given integer is odd or even. But, it also works! Who will follow this
style? !!

#include <stdio.h>

int main(int argc, char **argv)
{
int n;
printf("Enter the number: ");
scanf("%d", &n);
(n%2) && printf("%d is odd", n);
!(n%2) && printf("%d is even", n);
return 0;
}

>If you do not
> like my *style* then I don't care.

Then don't start a thread "What is/is not considered to be good
OO programming"----Don't waste others time.

---
Email: rrjanbiah-at-Y!com

Tony Marston

unread,
Aug 14, 2003, 6:54:55 AM8/14/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bhe8fa$i0r$1...@maud.ifi.uio.no>...

When a user is looking at a page in his browser he has several options
provided with hyperlinks, such as switching to a different page or
sorting the data by a particular column name. Each of these is
provided by a different $_GET variable but only one is provided at a
time. So the user may select page 2, then within page 2 he selects to
sort on column A. The $_GET array does not contain the current page
number, only the request to sort, but as my script 'remembers' the
current page number there is no problem. Likewise after selecting to
sort on a particular column the user may go to another page and that
new page will still be sorted on the same column. (BTW, my sorting
mechanism toggles between ascending and descending, so that is another
option that has to be 'remembered'). It would be too complicated to
have each hyperlink specify the full combination of options which are
currently available, so I only need to specify what has changed, such
as 'page=3' or 'sort=columna'.



> >> <snip>
>
> >> >> I understand the point of reusing code to
> >> >> generate SELECT/INSERT/UPDATE/DELETE statements, but you can do that
> >> >> without having to create a class for every table you have.
> >> >>
> >> >
> >> > Then where do I maintain the business rules for each individual
> >> > database table? In a separate class?
> >>
> >> No, in a separate object which is an instance of a some sort class that
> >> models business rules. You can quickly turn this into an extensible type
> >> system, which you can reuse in *all* part of your application, not just
> >> with the DB. (For example to validate form input.)
> >>
> >> André Næss
> >
> > So in your approach you have a PHP script containing the validation
> > rules for a database table which then has to set..() these rules in a
> > separate object before they can be processed?
>
> Say I wanted to talk to the table "cars". I'd compose an object by creating
> an instance of a Table class and add rules represented as objects to it. Of
> course, the business rules should be taken care of by the DBMS, not your
> application code, but unfortunately that is not completely possible in
> current SQL systems.

No DBMS can handle business rules in a 'user friendly' manner, they
can either accept or reject an update. In the case of an update
failure the error message may not be very usefull. That is why it is
necessary to write program code to validate the user's input before it
gets sent to the database. It has been this way for decades, and will
still be this way for many more decades.

> So let's take a simple rule like "the name of the car
> should be at least 1 character, and no more than 32". To model this I'd
> create a String object that has this limitation built in, and link it to
> the 'name' field in the Table object. Other common data types are Number,
> Date, File, Time, Creditcard etc.

So in your method you create an instance of a generic Table class,
then feed it the rules that you want it to perform for a particular
table. This means that your rules exist in another object which have
to be passed to your Table object before they are processed. In my
method the rules for each database table exist in the class I create
for each database table. These rules can be processed using the
methods inherited from the superclass (remember that each table class
is a subclass of my abstract database class) without having to be
passed to another object. So in fact I achieve the same result with
fewer steps, therefore my method is more efficient.

> These are fairly simple type validations, but they should go a long way.
> You'll probably also want to have some sort of generic Rule object for rare
> cases where none of the available objects suffice, and you don't want to
> create a new class. It is of course very important that these things are
> implemented separately, so that they can be reused whenever you need to
> validate any data.

I have a standard function/method which validates all user input based
on the field specifications for that table. This is described in
http://www.tonymarston.net/php-mysql/databaseobjects2.html#a4b

> But the database can enforce a lot of constraints, and one should really put
> as much business logic into the database as possible because:
>
> * It's less work
> * It's safer from bugs, because the DBMS developers have (hopefully) tested
> it properly.
> * It's most likely faster.

It is just not possible to put all your business into the database,
therefore program code will always be necessary.

> I see that you among other things have code to enforce foreign key
> constraints, but wouldn't it be much better not to need that code at all?

Foreign key constraints (if you want them at all) must exist
somewhere, either in the database or in your code. I just happen to
have them in my code.

> > My approach is to have the validation rules for each database table
> > held in a separate script which just happens to be a class where those
> > rules can be processed in situ, therefore I do not have to waste time
> > in sending those rules to another object before they can be processed.
> > My method seems neater somehow.
>
> What sort of time are you wasting? Are you saying that writing a whole new
> class is better than instantiating a few objects?

When I want to communicate with a database table I use a single class
which contains all the details for that database table, not several
different classes which contain bits and pieces. Using a single class
to contain all the information (properties and methods) about an
entity is supposed to be what encapsulation is all about.

> The point here is that you have to think about what is static and what is
> dynamic in your application. Now, the concept of a database table is
> certainly static, and so are data types and the concept of a constraints.

Database tables are static until they are changed, and with an
evolving system they WILL change over time.

Business rules static until they are changed, and with an evolving
system they WILL change over time.

So when a database table changes or a business rule changes you have
to make a corresponding change to code in order to keep up. In my
method I have a separate class for each database table which
identifies the rules for that table. What is wrong with that? Why do
you keep insisting that it is *wrong* to have a separate class for
each database table?

> But databases are dynamic, in any given application you will have different
> databases, with different data types and different constraints. In general
> you want to use classes for that which is static,

Each of my table classes contains information which is specific to
that particular database table. The code which is inherited from my
superclass contains generic code which can be applied to any database
table. So my superclass is static while each subclass is dynamic.

<snip>


>
> And just to make sure we're not in total disagreement, I think you are
> absolutely right in what you say in the bullet-list in the "Background"
> section.
>
> André Næss


What? You mean there is actually something I have said that you agree
with? Well I'll go to the foot of our stairs!!!

Tony Marston
http://www.tonymarston.net/

Frank Grimes

unread,
Aug 14, 2003, 8:19:37 AM8/14/03
to
On 14 Aug 2003 03:54:55 -0700, to...@marston-home.demon.co.uk (Tony
Marston) wrote:

>No DBMS can handle business rules in a 'user friendly' manner, they
>can either accept or reject an update. In the case of an update
>failure the error message may not be very usefull. That is why it is
>necessary to write program code to validate the user's input before it
>gets sent to the database. It has been this way for decades, and will
>still be this way for many more decades.

Another approach (which I often use) is to let the database validate
the data for you by sending a unvalidated query and parsing the error
message. For example, lets say I have a table of users in which the
userId is the primary key. Additionally I have an email address field
which has a unique index. When adding a user from an admin interface
I have to check the possibility that the userId entered already
exists, as well as the email address, and return an error.

I used to issue a separate select (or select count(*) ) query to find
out if the userId or email address already existed, but not only is
this cumbersome, it also introduces a race condition that could
trigger an unexpected error (very unlikely, but possible). Now my
approach is to try the insert statement, and parse the error message
that gets returned from the database (sorry if my news client wraps
this):

if (!(@$this->_db->query($query))) {

$sqlErrorMsg = $this->_db->error();

if (preg_match('/user_pkey/', $sqlErrorMsg)) {

$this->errors[] = array(
'fieldName' => 'userId',
'errorMsg' => 'The User ID you selected is already in use.'
);

} elseif (preg_match('/idx_emailaddr/', $sqlErrorMsg)) {

$this->errors[] = array(
'fieldName' => 'emailAddr',
'errorMsg' => 'The email address you selected is already in
use.'
);

} else {

$this->errors[] = array(
'fieldName' => '',
'errorMsg' => 'SQL insert failed. This is what the server
said: '.
"'$sqlErrorMsg'"
);

}

Hopefully one day I will be able to define "friendly" versions of
error messages directly in the DBMS engine so I can avoid having to
translate them in the application level code.

André Næss

unread,
Aug 14, 2003, 2:55:21 PM8/14/03
to
Tony Marston:

>> > An advantage I have found with this approach is I save each object in
>> > my session array, so that when I return to an object all the previous
>> > values held in its variables are still there, so rather than the
>> > script which calls the getData() method having to remember all those
>> > values so that it can pass them in the argument list, the object
>> > itself 'remembers' all the previous values automatically and reuses
>> > them. The calling object only has to use a set..() method on one of
>> > these values when it wants to change it, otherwise the previous valkus
>> > is used automatically.

>> But I might be misunderstanding you, could you possibly supply an example


>> where using sessions is beneficial in the way you're describing?
>

> [explanation snipped]

Ok, sounds fair enough, not sure if I would have stored the entire object
just to store a few variables, but I guess there's no real performance hit
involved unless the site is getting a massive number of hits from a large
number of users.



>> So let's take a simple rule like "the name of the car
>> should be at least 1 character, and no more than 32". To model this I'd
>> create a String object that has this limitation built in, and link it to
>> the 'name' field in the Table object. Other common data types are Number,
>> Date, File, Time, Creditcard etc.
>
> So in your method you create an instance of a generic Table class,
> then feed it the rules that you want it to perform for a particular
> table. This means that your rules exist in another object which have
> to be passed to your Table object before they are processed. In my
> method the rules for each database table exist in the class I create
> for each database table. These rules can be processed using the
> methods inherited from the superclass (remember that each table class
> is a subclass of my abstract database class) without having to be
> passed to another object. So in fact I achieve the same result with
> fewer steps, therefore my method is more efficient.

But also less reusable, because the validation code cannot be used in other
places where it makes sense due to the lack of orthogonality. The design is
inherently more static, and static designs are always less resistant to
change.



>> But the database can enforce a lot of constraints, and one should really
>> put as much business logic into the database as possible because:
>>
>> * It's less work
>> * It's safer from bugs, because the DBMS developers have (hopefully)
>> tested it properly.
>> * It's most likely faster.
>
> It is just not possible to put all your business into the database,
> therefore program code will always be necessary.

Certainly. But I said "as much as possible", not all.



>> I see that you among other things have code to enforce foreign key
>> constraints, but wouldn't it be much better not to need that code at all?
>
> Foreign key constraints (if you want them at all) must exist
> somewhere, either in the database or in your code. I just happen to
> have them in my code.

But handling them in the DBMS is *much* safer because a DBMS is built to
withstand system crashes and all sorts of weird errors. If data integrity
matters -- and IMO it *always* does -- it is crazy to make a poor
implementation of what the DBMS excels at!

>> > My approach is to have the validation rules for each database table
>> > held in a separate script which just happens to be a class where those
>> > rules can be processed in situ, therefore I do not have to waste time
>> > in sending those rules to another object before they can be processed.
>> > My method seems neater somehow.
>>
>> What sort of time are you wasting? Are you saying that writing a whole
>> new class is better than instantiating a few objects?
>
> When I want to communicate with a database table I use a single class
> which contains all the details for that database table, not several
> different classes which contain bits and pieces. Using a single class
> to contain all the information (properties and methods) about an
> entity is supposed to be what encapsulation is all about.

Well yes, but classes are supposed to represent abstract concepts. The
concept of a table is abstract. A given SQL table is not, it's an object in
the world. You wouldn't model people by creating a Person class and
subclass it for each new person would you? The concept of a Person is
abstract, a given person is not.

>> The point here is that you have to think about what is static and what is
>> dynamic in your application. Now, the concept of a database table is
>> certainly static, and so are data types and the concept of a constraints.
>
> Database tables are static until they are changed, and with an
> evolving system they WILL change over time.
>
> Business rules static until they are changed, and with an evolving
> system they WILL change over time.

I'm saying that the *concept* -- the *idea* -- of a table is static, and
thus it's natural to represent it as a class. Likewise for rules. However,
the table 'cars' is an instance of the table concept, and so it's natural
to represent it using an object. That's all there is to it.

> So when a database table changes or a business rule changes you have
> to make a corresponding change to code in order to keep up. In my
> method I have a separate class for each database table which
> identifies the rules for that table. What is wrong with that? Why do
> you keep insisting that it is *wrong* to have a separate class for
> each database table?

Imagine you have this system written in Java. In Java you have to compile
stuff into class files. If you have a single Table class, and a bunch of
Rule classes, you can mix these together on run-time, and you can expand
the application by making changes to the *application* only. In your
approach you will have to recompile the class files for any tables you
change, whereas in my approach you just change application code and
recompile (which you'd have to do anyway). This just illustrates that
classes are at a different "level" than objects, it was what I tried to
explain by saying there's a sort of "tax" on creating new classes. But of
course, this argument is not as strong when the distinction between
run-time and compile-time is so blurred.

Also, in your approach a change in the abstract superclass could potentially
wreak havoc on existing code. You can't know, all you know is that you have
an enormous amount of dependency, and that's a bad thing. It could be as
simple as you adding a variable for some purpose, forgetting that in one of
the hundreds of derived classes you have shadowed this variable, and before
you know it parts of your applications starts behaving randomly. That's no
fun.

If you've specialized one of the generic validation rules in one of the
subclasses, then a change to the superclass declaration could cause
problems.

And it's also the potential of adding methods and variables to the derived
classes, which makes them seem like they represent distinct concepts, when
in fact they all represent the same thing, a table, and tables should
behave the same, regardless of their name. Of course, doing that is just
bad programming, but sometimes it's a good idea to try to prevent the bad
from ever occurring. However this is more important if you write code that
you want to distribute to the community. This sort of code should not rely
on the programmer having to learn lots of do's and dont's to use it.
Community publication was after all the basis of this discussion.

And then there's the point from a little earlier about the reduced
reusability due to the lack of orthogonality.

I think that sums it up. Of course, there's also a bit of designer's
gut-feeling here. I've been working with OO for something like 5 years, so
I feel that I have a fairly good grasp on it.

André Næss

Jochen Daum

unread,
Aug 14, 2003, 5:25:28 PM8/14/03
to
Hi R.!

On 14 Aug 2003 00:52:05 -0700, ng4rrj...@rediffmail.com (R. Rajesh
Jeba Anbiah) wrote:

>to...@marston-home.demon.co.uk (Tony Marston) wrote in message news:<7588a50f.03081...@posting.google.com>...
>> ng4rrj...@rediffmail.com (R. Rajesh Jeba Anbiah) wrote in message news:<abc4d8b8.03081...@posting.google.com>...
>>
>> <snip>
>>
>> > ---> Contradicts what style? Where is this *style* documented?
>> >
>> > All the time, we cannot refer the ___law books___... It comes from
>> > the practice and excercises.
>>
>> You mean personal preference.
>>My *style* is to write simple,
>> efficient, maintainable, reusable code based upon decades of
>> experience using a variety of 2nd, 3rd and 4th generation languages.
>
> But, I'm sure you haven't done any projects with PHP OOP or you
>have done limited projects with other OOP languages.
>

I think you're right with the rest of your comments, but this is just
an insulting accusation.

HTH, Jochen



>
>> It is an example of how to use PHP's OO capabilities to produce a
>> reusable class (through inheritance bu subclassing) to access a
>> database.
>
> You always mean inheritance. OOP is more than inheritance.
>

I think it comes down to that exactly.

Tony Marston

unread,
Aug 15, 2003, 11:55:58 AM8/15/03
to
Jochen Daum <joche...@cans.co.nz> wrote in message news:<fgvnjvgtp16dl7pl5...@4ax.com>...

> Hi R.!
>
> On 14 Aug 2003 00:52:05 -0700, ng4rrj...@rediffmail.com (R. Rajesh
> Jeba Anbiah) wrote:
>
> >to...@marston-home.demon.co.uk (Tony Marston) wrote in message news:<7588a50f.03081...@posting.google.com>...
> >> ng4rrj...@rediffmail.com (R. Rajesh Jeba Anbiah) wrote in message news:<abc4d8b8.03081...@posting.google.com>...
> >>
> >> <snip>
> >>
> >> > ---> Contradicts what style? Where is this *style* documented?
> >> >
> >> > All the time, we cannot refer the ___law books___... It comes from
> >> > the practice and excercises.
> >>
> >> You mean personal preference.
> >>My *style* is to write simple,
> >> efficient, maintainable, reusable code based upon decades of
> >> experience using a variety of 2nd, 3rd and 4th generation languages.
> >
> > But, I'm sure you haven't done any projects with PHP OOP or you
> >have done limited projects with other OOP languages.

I have written enough components to know that my methodolgy works, and
I can create new components quite quickly. This includes the fact that
all my HTML is produced via XML and XSL.

> I think you're right with the rest of your comments, but this is just
> an insulting accusation.
>
> HTH, Jochen
>
> >
> >> It is an example of how to use PHP's OO capabilities to produce a
> >> reusable class (through inheritance bu subclassing) to access a
> >> database.
> >
> > You always mean inheritance. OOP is more than inheritance.
> >
>
> I think it comes down to that exactly.

The main principles behind OOP (according to the books I have read and
articles I have found on the web) are inheritance, encapsulation and
polymorhism. I have mangaged to achieve all three with my code, so I
can't be far off the mark.

Other developers seem to criticise me simply because I have done it in
a way which is different from theirs. My method is right for me, your
method is right for you, and Tom/Dick/Harry's method is right for
Tom/Dick/Harry. Provided that these diferent methods are capable of
producing workable and maintainable sofware each should be allowed to
exist and judged by the results it produces rather than being slammed
simply for 'being different' or 'not invented here'. As the French
would say, 'Vive la Difference'

If everybody always did things the same way there would be no progress
made, ever. I choose to do things differently because I have a
creative streak. I don't like relying on other people's methods when I
reckon that I can do better.

Tony Marston
http://www.tonymarston.net

matty

unread,
Aug 15, 2003, 2:25:44 PM8/15/03
to
R. Rajesh Jeba Anbiah wrote:

>> You mean personal preference.
>>My *style* is to write simple,
>> efficient, maintainable, reusable code based upon decades of
>> experience using a variety of 2nd, 3rd and 4th generation languages.
>
> But, I'm sure you haven't done any projects with PHP OOP or you
> have done limited projects with other OOP languages.

OK, Rajesh, what have *you* worked on then - URLs please?

matty

unread,
Aug 15, 2003, 2:59:09 PM8/15/03
to
Go away for a few days and you miss it all... A few opinions...

Programming is a craft more than an art (software engineering, not
black magic) and as such, is about writing code that works, first
and foremost. If it works well, even better. The same goes for
ease of maintenance, memory footprint, speed, etc, etc. Most of the
time, people are writing code for a use in the *real world*, and
not just as an academic exercise.

Look at Windows 9x. Big messy mixture of functional and OO coding,
varying APIs, inconsistent, bug-ridden, often unstable and unpredictable.
But, a very successful product commercially. (Before you flame, I'm
not a windows lover...) Partly this is due to marketing and business
practices (very effective ones, whatever you think of Microsoft), and
partly because the products were shipped, new features were added, and the
general perception of users is that the software can "do stuff".

I don't think many end-users of Windows (proportionately) care whether
the code is written in Pascal, Lisp, ALGOL, Objective C; whether the design
was refactored from scratch, or what kind of multiple inheritance/interface/
MVC paradigms were used to construct the code.

There is also More Than One Way To Do It. Lots of tools, things to
make throwaway one-liner code, IDEs, collaborative development tools, frameworks
to aid in OO design, database access, you name it. All of it, though, is
geared at writing software that does something. It may be that you feel that,
if you use a totally OO language (e.g. Java), you will have better code than
if you write it in C; but the metric is, does the software work?

And then TMTOWTDI in a given language environment. Some people like to
have generic base classes, which they subclass to use in a generic application.
A lot of GUI frameworks (MFC, Borland's, QT) seem to be based around this idea.
Others like to write generic classes, which handle any given situation within
their stated problem domain. I like this method: Kind of a "Write Once, Forget
Anywhere" method, where the class implementation is not important once coded,
and (hopefully), you can use the same class in a wide variety of projects,
without having to change the class code.

And so-on.

There are benefits in the form of code-reuse, encapsulation, etc. But making
code OO doesn't make it good code. (Cool is not always Va-Va-Voom, to quote
a recent car advert...) I doubt many people could point to a non-trivial
DB app, that uses a 5NF database design, that couldn't be improved with some
denormalization of the data. Applying an academic theory to a problem doesn't
guarantee to solve it, it just helps you analyze what's going on. And "My" idea
of OO design doesn't necessarily match with "Yours" - it's just different.

Matt

R. Rajesh Jeba Anbiah

unread,
Aug 16, 2003, 11:46:17 AM8/16/03
to
> Jochen Daum <joche...@cans.co.nz> wrote in message news:<fgvnjvgtp16dl7pl5...@4ax.com>...
> > Hi R.!
> > I think you're right with the rest of your comments, but this is just
> > an insulting accusation.
> >
> > HTH, Jochen

If you took it as insulting tone, sorry I can't help you. This is what
I meant: the person who used others classes or given his class to
others won't talk OOP like this. Starting a thread about the style,
but arguing that "this code compiles and works" is IMO, too naive.

If there is a dynamic property in the class, there must be a option to
set the property via some methods like setDbLink() or so. This is the
basic OOP style so that the data is tightly bound within the class.
While setting the property foo directly via some global $fooo, the
code breaks the basic OOP style. It is no more an *object* while some
user-global variable is directly controls the object. If you like to
set the property foo directly via global fooo, why go for OOP?


> If everybody always did things the same way there would be no progress
> made, ever. I choose to do things differently because I have a
> creative streak.

If you're confident about your creativity, just transform your PHP OOP
code into Java and C++ (__but with the present style__) and post it to
Java and C++ group. Just see how those OOP guys feel about your
creative OOP style. Hope, this is ok with you.

André Næss

unread,
Aug 17, 2003, 9:16:10 AM8/17/03
to
matty:

> Look at Windows 9x. Big messy mixture of functional and OO coding,
> varying APIs, inconsistent, bug-ridden, often unstable and unpredictable.

Well what you're saying is that it sucks. We want software that is bug-free.
stable and predictable. So we clearly don't want to code stuff the Windows
way.

> I don't think many end-users of Windows (proportionately) care whether
> the code is written in Pascal, Lisp, ALGOL, Objective C; whether the
> design was refactored from scratch, or what kind of multiple
> inheritance/interface/ MVC paradigms were used to construct the code.

Of course not. But we as programmers care for our craft, and for us these
are extremely important issues because we want to produce high quality
products. And this obviously benefits end-users in the long run.

> There is also More Than One Way To Do It. Lots of tools, things to
> make throwaway one-liner code, IDEs, collaborative development tools,
> frameworks
> to aid in OO design, database access, you name it. All of it, though, is
> geared at writing software that does something. It may be that you feel
> that, if you use a totally OO language (e.g. Java), you will have better
> code than if you write it in C; but the metric is, does the software work?

But each language has it's collection common knowledge known as
best-practices. If you want to write good software in whatever language you
choose there are basically two approaches:

A) I'm so much smarter than all the people who have worked with this
language before, I can do it better, because I *really* know how it should
be done. Screw the best-practices and the knowledge they have collected
through decades of experience, I'll do it my way.

B) I'll better listen to the masters if I want to be an expert in this
language.

Guess what approach I prefer.

> And then TMTOWTDI in a given language environment. Some people like to
> have generic base classes, which they subclass to use in a generic
> application. A lot of GUI frameworks (MFC, Borland's, QT) seem to be based
> around this idea. Others like to write generic classes, which handle any
> given situation within
> their stated problem domain. I like this method: Kind of a "Write Once,
> Forget Anywhere" method, where the class implementation is not important
> once coded, and (hopefully), you can use the same class in a wide variety
> of projects, without having to change the class code.

There are of course different ways of doing things that apply to different
circumstances. That's why we have so many different programming languages.
There is no language to end all languages, nor is there a single
methodology that always works. Best-practices always apply within a
context, nobody ever said that you should always use them, although newbies
tend to do that. But they are best-practices for a *reason*.

André Næss

Jochen Daum

unread,
Aug 17, 2003, 4:23:34 PM8/17/03
to
Hi Tony!

On 15 Aug 2003 08:55:58 -0700, to...@marston-home.demon.co.uk (Tony
Marston) wrote:

>Jochen Daum <joche...@cans.co.nz> wrote in message news:<fgvnjvgtp16dl7pl5...@4ax.com>...
>> Hi R.!
>>
>> On 14 Aug 2003 00:52:05 -0700, ng4rrj...@rediffmail.com (R. Rajesh
>> Jeba Anbiah) wrote:
>>
>> >to...@marston-home.demon.co.uk (Tony Marston) wrote in message news:<7588a50f.03081...@posting.google.com>...
>> >> ng4rrj...@rediffmail.com (R. Rajesh Jeba Anbiah) wrote in message news:<abc4d8b8.03081...@posting.google.com>...
>> >>
>> >> <snip>
>> >>
>

>The main principles behind OOP (according to the books I have read and
>articles I have found on the web) are inheritance, encapsulation and
>polymorhism. I have mangaged to achieve all three with my code, so I
>can't be far off the mark.
>
>Other developers seem to criticise me simply because I have done it in
>a way which is different from theirs. My method is right for me, your
>method is right for you, and Tom/Dick/Harry's method is right for
>Tom/Dick/Harry. Provided that these diferent methods are capable of
>producing workable and maintainable sofware each should be allowed to
>exist and judged by the results it produces rather than being slammed
>simply for 'being different' or 'not invented here'. As the French
>would say, 'Vive la Difference'
>
>If everybody always did things the same way there would be no progress
>made, ever. I choose to do things differently because I have a
>creative streak. I don't like relying on other people's methods when I
>reckon that I can do better.
>

You're right with that actually.

I'd like to say, I enjouyed this thread.

Jochen

Tony Marston

unread,
Aug 19, 2003, 3:05:57 AM8/19/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bhgeml$omk$1...@maud.ifi.uio.no>...
> Tony Marston:
>
<snip>


> And then there's the point from a little earlier about the reduced
> reusability due to the lack of orthogonality.
>

What has bird watching got to do with it?

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 19, 2003, 3:35:19 AM8/19/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bhgeml$omk$1...@maud.ifi.uio.no>...
> Tony Marston:
>
<snip>

> Ok, sounds fair enough, not sure if I would have stored the entire object


> just to store a few variables, but I guess there's no real performance hit
> involved unless the site is getting a massive number of hits from a large
> number of users.

I discovered that I needed to store most of the variables from each
object, and it was easier to store the entire object instead of
individual bits and pieces.



> >> So let's take a simple rule like "the name of the car
> >> should be at least 1 character, and no more than 32". To model this I'd
> >> create a String object that has this limitation built in, and link it to
> >> the 'name' field in the Table object. Other common data types are Number,
> >> Date, File, Time, Creditcard etc.

I don't have, nor do I want, a separate object to handle strings. If I
want do to the validation in your example I simply do the following:

1) Create a subclass CAR to contain all the rules regarding all cars.
2) In the class constructor I have this entry:

$fieldspec['name'] = array('type' => 'string',
'size' => 32,
'required' => 'y');

When the insertRecord() or updateRecord() method is invoked the
contents of the $_POST array is compared with the specifications
contained in $fieldspec. Thus an error message will be produced if the
field is NULL or has more than 32 characters. Simple, isn't it?

> > When I want to communicate with a database table I use a single class
> > which contains all the details for that database table, not several
> > different classes which contain bits and pieces. Using a single class
> > to contain all the information (properties and methods) about an
> > entity is supposed to be what encapsulation is all about.
>
> Well yes, but classes are supposed to represent abstract concepts. The
> concept of a table is abstract. A given SQL table is not, it's an object in
> the world. You wouldn't model people by creating a Person class and
> subclass it for each new person would you? The concept of a Person is
> abstract, a given person is not.

I have a database table called PERSON. I have a set of rules that need
to be applied to any data before its gets inserted/updated/deleted
from this table. I need to hold those rules somewhere, either in a
script which is a class or in a script which is not. The rules get
processed by standard methods in my generic/abstract database class,
therefore I need to make these rules accessible to my generic class. I
can either have a separate process which obtains the rules for PERSON
and feed them into an object created from my generic table class, or I
can hold the PERSON rules in a separate class which happens to be a
subclass of my generic database handler. In my method when I
instantiate an object of my PERSON class I have the rules for PERSON
and the method (which is inherited from the superclass) to process
them all in the same object. I think that having everything inside a
single object is far easier than having it spread about multiple
objects. That is the KISS principle in operation.

<snip>



> I'm saying that the *concept* -- the *idea* -- of a table is static, and
> thus it's natural to represent it as a class. Likewise for rules. However,
> the table 'cars' is an instance of the table concept, and so it's natural
> to represent it using an object. That's all there is to it.

If I have an application that has to deal with such things as
customers, products and invoices I will end up with a CUSTOMER table,
a PRODUCT table and an INVOICE table. In my methodology I will also
create a CUSTOMER class, a PRODUCT class and an INVOICE class to hold
all the business rules for each of those entities. This is a technique
that I have seen quite a few people use, so it cannot be all that
obscure. It works and it is also simple.

Or is your argument that because it is so simple that it cannot really
be *proper* OOP because only a select few *experts* are deemed to be
able to understand the complexities of OOP and can therefore charge
enormous fees.

Tony Marston
http://www.tonymarston.net/

André Næss

unread,
Aug 19, 2003, 8:47:24 AM8/19/03
to
Tony Marston:

> André Næss <andrena.spa...@ifi.uio.no> wrote in message
> news:<bhgeml$omk$1...@maud.ifi.uio.no>...
>> Tony Marston:
>>
> <snip>
>
>> And then there's the point from a little earlier about the reduced
>> reusability due to the lack of orthogonality.
>>
>
> What has bird watching got to do with it?

http://www.britannica.com/dictionary?book=Dictionary&va=orthogonality

André Næss

André Næss

unread,
Aug 19, 2003, 8:56:46 AM8/19/03
to
Tony Marston:

You can keep repeating this as much as you like, or you can actually make an
interesting point by addressing the problems I listed (which you simply
ignored). And don't forget that the basis of this discussion is why your
approach was not accepted into a library of code, not whether it works for
you or not.

>> I'm saying that the *concept* -- the *idea* -- of a table is static, and
>> thus it's natural to represent it as a class. Likewise for rules.
>> However, the table 'cars' is an instance of the table concept, and so
>> it's natural to represent it using an object. That's all there is to it.
>
> If I have an application that has to deal with such things as
> customers, products and invoices I will end up with a CUSTOMER table,
> a PRODUCT table and an INVOICE table. In my methodology I will also
> create a CUSTOMER class, a PRODUCT class and an INVOICE class to hold
> all the business rules for each of those entities. This is a technique
> that I have seen quite a few people use, so it cannot be all that
> obscure. It works and it is also simple.

But this is not an application that deals with invoices or products. This is
a package which you have created to deal with databases. To represent the
concepts of tables and rules. It is supposed to be at a much higher level
of abstraction than invoices and products and people. So this is a
completely spurious point.



> Or is your argument that because it is so simple that it cannot really
> be *proper* OOP because only a select few *experts* are deemed to be
> able to understand the complexities of OOP and can therefore charge
> enormous fees.

No.

André Nęss

Tony Marston

unread,
Aug 20, 2003, 4:49:28 AM8/20/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bhsvhg$3pc$1...@maud.ifi.uio.no>...
> Tony Marston:
>
> <snip>

>
> You can keep repeating this as much as you like, or you can actually make an
> interesting point by addressing the problems I listed (which you simply
> ignored).

My code does not have any of the problems you listed.

> And don't forget that the basis of this discussion is why your
> approach was not accepted into a library of code, not whether it works for
> you or not.

I did not submit my code for inclusion in any library, I simply
bpublished it as an example of what could be done using OOP techniques
with PHP. What is certain from this discussion is that different
people would achieve the same result in different ways, but just
because my method is *different* does not make it *wrong*.

> >> I'm saying that the *concept* -- the *idea* -- of a table is static, and
> >> thus it's natural to represent it as a class. Likewise for rules.
> >> However, the table 'cars' is an instance of the table concept, and so
> >> it's natural to represent it using an object. That's all there is to it.
> >
> > If I have an application that has to deal with such things as
> > customers, products and invoices I will end up with a CUSTOMER table,
> > a PRODUCT table and an INVOICE table. In my methodology I will also
> > create a CUSTOMER class, a PRODUCT class and an INVOICE class to hold
> > all the business rules for each of those entities. This is a technique
> > that I have seen quite a few people use, so it cannot be all that
> > obscure. It works and it is also simple.
>
> But this is not an application that deals with invoices or products. This is
> a package which you have created to deal with databases. To represent the
> concepts of tables and rules. It is supposed to be at a much higher level
> of abstraction than invoices and products and people. So this is a
> completely spurious point.

While building an application that deals in such entities as
customers, invoices and products it was natural to create a class for
each of those entities. Each of these classes needs to communicate
with the database, so rather than duplicate the necessary code in each
class I decided to put all the necessary code into a 'common' area so
that I could write it only once and share it many times. I started by
making this common area into its own class, then discovered that I
could share this code with my individual entity classes simply by
making each entity class a subclass of my database access class. Thus
all the methods and properties of my generic database access class are
inherited by my individual entity classes.

My generic database access class contains the code to access any
database table in various ways, but it does not know which database or
which table. That is what the subclass is for. Each subclass needs to
specify at least 3 things - the database name, the table name, and the
list of fields for that table with their characteristics so that
standard validation (known as declarative checking in some languages)
can be performed.

As far as I am concerned I have followed the concepts of OOP by
creating a class for each real-world entity. Each class contains all
the business rules for that entity, therefore I have demonstrated
encapsulation. I have shared common code by using subclasses to
inherit properties and methods from the superclass, therefore I have
demonstrated inheritance. I use common methods on each of my classes
so my standard scripts can do common functions on any class without
having specific methods for specific class, thus I have demonstrated
polymorphism.

Forgive me if I have misunderstood the concepts of OOP, but aren't
encapsulation, inheritance and polymorphism the primary goals? I have
demonstrated a methodology that achieves all three, yet all you can do
is complain that the method is *not valid*.

Every book I have read on OOP says that 'you can create objects from
classes which include the benefits of encapsulation, inheritance and
polymorhism'. Nowhere do thay say 'you cannot create an object for
that entity' or 'you must create an object for that entity'. That is
simply up to the creativity of the individual developer. At the end of
the day it is a matter of how to use these techniques to achieve
results, and the quicker that results can be achieved the better.
Whatever you or others like you say, the better methodology is one
that enables developers to produce results faster. If I have developed
a methodology which enables me to create fully-functional components
in a matter of hours as far as I am concerned this is far better than
a rival methodology that takes days or even weeks.

The bottom line is that results take precedence over the methodology,
and any methodology which gets in the way of developer productivity,
regardless of how many fancy rules and theories it contains, is a
candidate for the rubbish bin.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 21, 2003, 3:26:12 AM8/21/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bhsuvu$3o1$1...@maud.ifi.uio.no>...

Apart from the fact I cannot see what a geometry term has to do with
software, I also found this little snippet on page
http://dictionary.reference.com/search?q=orthogonal

<quote>
Also used loosely to mean "irrelevant to", e.g. "This may be
orthogonal to the discussion, but ...", similar to "going off at a
tangent.
</quote>

I know that I am not the one who keeps going off at a tangent and
losing the plot.

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 21, 2003, 9:31:16 AM8/21/03
to
For all those people who keep telling me that it is not good OOP to
create a separate class for each database table I invite you to take
at look at http://www.zend.com/zend/tut/tutorial-wong4.php which under
the heading "Use an object oriented approach" quite clearly states the
following:-

<quote>
A class should be used to create each DB interface you require. This
class should be a logical (code) representation of a single database
structure.
</quote>

where "database structure" means "database table".

This article is published on the website run by Zend Technologies who
are supposed to know a thing or two about PHP, and perhaps a little
about OOP, so if they say that it's OK to have a separate class for
each database table then it's just fine by me.

You may also like to read the comment from someone (who prefers to
remain anonymous) that the solution in the article is far from perfect
because it requires far too much code in the table class and has far
too little code in the DML class therefore has very little
reusability.

In my methodology each table class contains the barest essentials
because my super-DML class not only executes each DML statement it
actually constructs it as well. And not only for INSERT, UPDATE and
DELETE but it can even handle complex SELECT statements.

Who do you think is closest to winning the proverbial cigar? Please
submit your answers on the back of a $50 bill to....

Tony Marston
http://www.tonymarston.net/

André Næss

unread,
Aug 21, 2003, 3:28:02 PM8/21/03
to
Tony Marston:

>> >> And then there's the point from a little earlier about the reduced
>> >> reusability due to the lack of orthogonality.
>> >>
>> >
>> > What has bird watching got to do with it?
>>
>> http://www.britannica.com/dictionary?book=Dictionary&va=orthogonality
>>
>> André Næss
>
> Apart from the fact I cannot see what a geometry term has to do with
> software,

Orthogonality in this context means to by creating things that are
orthogonal to eachother and then combining them you achieve more than by
designing lots of overlapping and specialized things.

As an example, Scheme is a good example of a language that has been designed
this way, in that it offers a rather small collection of simple constructs
from which you can build very large and complex structures by combination.

By designing your systems in an orthogonal fashion you can harness the power
of small, simple constructs combined. It's easier to maintain, easier to
understand, and easer to reuse.

André Næss

André Næss

unread,
Aug 21, 2003, 3:35:24 PM8/21/03
to
Tony Marston:

> André Næss <andrena.spa...@ifi.uio.no> wrote in message
> news:<bhsvhg$3pc$1...@maud.ifi.uio.no>...
>> Tony Marston:
>>
>> <snip>
>>
>> You can keep repeating this as much as you like, or you can actually make
>> an interesting point by addressing the problems I listed (which you
>> simply ignored).
>
> My code does not have any of the problems you listed.

Well, I guess that marks the end of this discussion. If you can't address
the problems and say *why* your code doesn't suffer from them there really
isn't any discussion, it's just you making unsupported claims.

André Næss

Tony Marston

unread,
Aug 22, 2003, 4:30:10 AM8/22/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bi2v6m$khf$1...@maud.ifi.uio.no>...

What a coincidence! The methodology I have been using over the last 20
years in several languages is to build systems from lots of small,
simple components instead of large, complex ones.

I've finally found something we agree on! What a relief!

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Aug 22, 2003, 4:31:28 AM8/22/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bi2vkg$ki4$1...@maud.ifi.uio.no>...

Just as you are making unsupported claims that my software has problems.

Tony Marston
http://www.tonymarston.net/

André Næss

unread,
Aug 22, 2003, 6:58:00 AM8/22/03
to
Tony Marston:

>> > My code does not have any of the problems you listed.
>>
>> Well, I guess that marks the end of this discussion. If you can't address
>> the problems and say *why* your code doesn't suffer from them there
>> really isn't any discussion, it's just you making unsupported claims.
>
> Just as you are making unsupported claims that my software has problems.

This is getting ridiculous. I wrote LOTS to support my claims. Maybe I
should have used a bullet list to get it through :P

EOD.

André Næss

Tony Marston

unread,
Aug 25, 2003, 8:14:04 AM8/25/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bi4lm2$qa6$1...@maud.ifi.uio.no>...

I disagree with all of your claims because you stated in your first
post in this thread:-

<quote>
The information is typical formatting information. I think it would be
much
cleaner if you allowed for two more arguments to getData() that
defined how
many rows to retrieve, and what offset to start at. The organization
of
data into pages belongs in presentation code.
</quote>

Many other posters agree with me that those particular variables are
nothing to to do with formatting but to do with the retrieval of data.
They are used to construct the SQL 'select' statement are are
therefore SELECTION critera, not formatting. They serve a similar
purpose to the 'where column=value' clause of the SELECT ststement.
Formatting is a term which is used to describe HOW the data is
presented to the user, not HOW MUCH. In my methodology the formatting
of data to the user is not done within any object, it is not even done
within any PHP code - it is all done with XML files and XSL
transformations.

Even so, there are NO rules in OOP that say what kind of data that you
can or cannot hold in variables, just as there are NO rules that say
"you cannot create an object for this" or "you must create an object
for that". It is up to the individual programmer to make use of the
available commands as he sees fit in order to achieve a result. It is
the result that counts, not the methodology that was used to create
it. That is what that old saying: "the proof of the opudding is in the
eating" is all about.

I also disagree most strongly with another of your statements:-
<quote>
I think it would be much
cleaner if you allowed for two more arguments to getData() that
defined how
many rows to retrieve, and what offset to start at.
</quote>

The request that comes from the client is simply "get me page x", and
that request is picked up by my presentation layer component and
passed through the business layer to the data access layer. The
calculation is done just once in the data access layer and not in
every presentation layer component. That is called "efficient
programming", something which you OO types cannot seem to grasp. You
are too busy following an artificially restrictive set of rules in
order to notice that what you are producing is bloated, slow and
unmanagable.

As someone pointed out in another thread there are no *right* and no
*wrong* ways, just *efficient* and *inefficient* ways, or perhaps
*maintainable* and *unmaintainable* ways.

You keep telling me that my method is *wrong* simply because is it
different from your way. Who says that *your* way is the *best* way? I
certainly do not claim that my way is the *only* way or the *best*
way. If anyone can come up with an alternative methodology that has
advantages over mine then I will say "well done", not "that is
cheating because you are breaking the rules".

Tony (a legend in his own lunchtime) Marston
http://www.tonymarston.net/

André Næss

unread,
Aug 25, 2003, 1:18:33 PM8/25/03
to
Tony Marston:

> André Næss <andrena.spa...@ifi.uio.no> wrote in message
> news:<bi4lm2$qa6$1...@maud.ifi.uio.no>...
>> Tony Marston:
>>
>> >> > My code does not have any of the problems you listed.
>> >>
>> >> Well, I guess that marks the end of this discussion. If you can't
>> >> address the problems and say *why* your code doesn't suffer from them
>> >> there really isn't any discussion, it's just you making unsupported
>> >> claims.
>> >
>> > Just as you are making unsupported claims that my software has
>> > problems.
>>
>> This is getting ridiculous. I wrote LOTS to support my claims. Maybe I
>> should have used a bullet list to get it through :P
>

> I disagree with all of your claims because you stated in your first
> post in this thread:-

It sounds like you basically saying that because you disagreed with my first
post you simply ignored every other argument I made, even as the discussion
moved along. But I'll assume that that was not what you meant, and leave it
at that.



> In my methodology the formatting
> of data to the user is not done within any object, it is not even done
> within any PHP code - it is all done with XML files and XSL
> transformations.

As tempting as it is, let us not get into that discussion again :)

> Even so, there are NO rules in OOP that say [...snip rest]

How many times are you going to repeat that? OOP currently has no formal
theory to back it up, and there aren't any formal methods, and hence any
rules. Yes. We know that. It's been clear since the beginning of this
thread. There is however a significant body of so called Best Practices. My
opinions here have been based on my knowledge of these. We clearly have
different opinions about what these Best Practices are, and how to apply
them.

> As someone pointed out in another thread there are no *right* and no
> *wrong* ways, just *efficient* and *inefficient* ways, or perhaps
> *maintainable* and *unmaintainable* ways.
>
> You keep telling me that my method is *wrong* simply because is it
> different from your way. Who says that *your* way is the *best* way? I
> certainly do not claim that my way is the *only* way or the *best*
> way. If anyone can come up with an alternative methodology that has
> advantages over mine then I will say "well done", not "that is
> cheating because you are breaking the rules".

If I have ever said that your solution is wrong it has been a bad choice of
words, but to the best of my knowledge I do not think I have ever done so.
I have on the other hand used words like cleaner and better, and explained
why I feel a cleaner and better approach is possible. I have listed what I
belive are weaknesses in your solution, in particular why I believe you
could have achieve better reusability and ease of maintenance. I've never
contended the fact that your software works.

But as it stands we probably won't ever agree. So I'm happy to call it a day
here. (And this time I mean it ;)) Let us just hope that readers of this
thread feel it was worth the read.

André Næss

matty

unread,
Aug 25, 2003, 11:34:10 AM8/25/03
to
André Næss wrote:
>
> But as it stands we probably won't ever agree. So I'm happy to call it a
> day here. (And this time I mean it ;)) Let us just hope that readers of
> this thread feel it was worth the read.
>
> André Næss

It was an interesting dicussion at first, but it seems to be have a
plain-and-simple flamewar for the past week...

Personally, I'd say that some of Andre's opinions have been a touch dogmatic,
and failed to recognise that different people will factor a system into
different classes; Tony's tutorial was good as a tutorial, but the code wasn't
generic enough for my liking (although that can be a good thing when you're trying
to teach OO).

There - you can *both* flame me now!!!

Matt

André Næss

unread,
Aug 25, 2003, 1:43:04 PM8/25/03
to
matty:

> There - you can *both* flame me now!!!

ARRRRRRRRRGH! ;)

André Næss

Tony Marston

unread,
Aug 26, 2003, 3:17:06 AM8/26/03
to
matty <matt...@askmenoquestions.co.uk> wrote in message news:<85q2b.1400$O57.4...@wards.force9.net>...

Why should I flame you? My tutorial was not meant to define the ONLT
TRUE way that something could be achieved, just a way that I had
devised based on past experience in other languages. Other people may
look at my work and say "no, that's not for me" or perhaps "there are
some interesting ideas there that I may be able to incorporate into my
own work". It is the same for me when I look at other people's work -
sometimes I see something useful, sometimes I do not.

If you found what I wrote to be of interest, that's fine. If you did
not find it interesting that's also fine. Just don't tell me that I am
*wrong* simply because my approach is different to yours. It is my
God-given right to be different and not have to conform to somebody
else's idea of perfection.

BTW, if you think that my code was interesting but not generic enough
for your liking you might like to take a copy of my complete
development environment, which contains quite a bit of working
software, just to see how it all hangs together. E-mail me if you are
interested.

Tony Marston
http://www.tonymarston.net/

matty

unread,
Aug 26, 2003, 8:21:57 AM8/26/03
to
Tony Marston wrote:

>> Matt
>
> Why should I flame you? My tutorial was not meant to define the ONLT
> TRUE way that something could be achieved, just a way that I had
> devised based on past experience in other languages. Other people may
> look at my work and say "no, that's not for me" or perhaps "there are
> some interesting ideas there that I may be able to incorporate into my
> own work". It is the same for me when I look at other people's work -
> sometimes I see something useful, sometimes I do not.
>
> If you found what I wrote to be of interest, that's fine. If you did
> not find it interesting that's also fine. Just don't tell me that I am
> *wrong* simply because my approach is different to yours. It is my
> God-given right to be different and not have to conform to somebody
> else's idea of perfection.
>
> BTW, if you think that my code was interesting but not generic enough
> for your liking you might like to take a copy of my complete
> development environment, which contains quite a bit of working
> software, just to see how it all hangs together. E-mail me if you are
> interested.
>
> Tony Marston
> http://www.tonymarston.net/

I wasn't trying to flame - it was more of a joke, bearing in mind the
somewhat heated exchanges between you and Andre!... It *is* your God-given
right to be different, I'm sure I worte a long posting the other week defending
this point of view (and your approach) in general.

And I didn't say you were wrong. Really, I didn't...

I might follow up on the offer of a peek at your code (just for curiousity's sake)
- always interesting to see how other people do things. The last time I worked
at a webdev firm, I was horrified to see the level of cut-and-paste that went
on, so it's always good to see the better stuff!

Tony Marston

unread,
Aug 27, 2003, 8:16:14 AM8/27/03
to
matty <matt...@askmenoquestions.co.uk> wrote in message news:<WmI2b.1907$O57.5...@wards.force9.net>...

I know that *you* didn't, but there are *some* out there in newsgroup
land that did. Shame on them!



> I might follow up on the offer of a peek at your code (just for curiousity's sake)
> - always interesting to see how other people do things. The last time I worked
> at a webdev firm, I was horrified to see the level of cut-and-paste that went
> on, so it's always good to see the better stuff!

I will send you via email a copy of my development environment as it
was in June this year. It is fully functional, with its own menu and
security system, and a series of sample transactions which show how I
deal with various database structures. This requires the DOM XML and
Sablotron extensions as all output is via XSL stylesheets (all
provided).

I am currently improving this environment in the following ways:-

1) Allowing each subsystem to reside in its own sub directory, thus
keeping one subsystem's files separate from another. This also allows
each subsystem to have its own CSS and XSL files.

2) I am splitting up my abstract database class so that the code which
deals with the generation and execution of all DML statements is in a
separate class.

3) My next task will be to do the same with the code which deals with
standard field validation (declarative checking).

You should be pleased to see that my style is not to have code
duplicated anywhere - I try to put such code into reusable libraries,
such as functions, include files, and even classes.

Enjoy!

Tony Marston
http://www.tonymarston.net/

André Næss

unread,
Aug 27, 2003, 3:13:06 PM8/27/03
to
Tony Marston:

> I am currently improving this environment in the following ways:-
>
> 1) Allowing each subsystem to reside in its own sub directory, thus
> keeping one subsystem's files separate from another. This also allows
> each subsystem to have its own CSS and XSL files.
>
> 2) I am splitting up my abstract database class so that the code which
> deals with the generation and execution of all DML statements is in a
> separate class.
>
> 3) My next task will be to do the same with the code which deals with
> standard field validation (declarative checking).

So you're doing pretty much what I suggested, yet you continued to argue
that my ideas were no good. Nice.

André Næss

Tony Marston

unread,
Aug 28, 2003, 3:44:34 AM8/28/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<biioj7$6cs$1...@maud.ifi.uio.no>...

All I am doing there is rearranging the same code. I am still
including the original code that you (and others like you) have
objected to:-

a) My class variables which store data used for pagination, which you
seem to think is *formatting* and therefore does not belong in the
class at all.

b) I still use a separate class for each individual database table to
hold the validation rules for that database table. Each of these
classes is a subclass of my abstract database class.


BTW, you have not slammed me yet for my obvious sin of not using
getters and setters in each class to deal with each individual column
in a table. I prefer to get my row data in and out using simple arrays
instead. I have sound technical reasons for doing what I do, yet it is
against all the *rules*. Would you care to comment on that?

Tony Marston
http://www.tonymarston.net/

Tony Marston

unread,
Sep 1, 2003, 6:50:20 AM9/1/03
to
I have just spotted this post in my newsreader at home (I have been working
abroad for 2 months where I have been limited to google groups) and I feel I
cannot let it pass without comment.

"André Næss" <andrena.spa...@ifi.uio.no> wrote in message

news:bhnnu7$i1i$1...@maud.ifi.uio.no...

I have been a software engineer for 25 years using a variety of 2nd, 3rd and
4th generation langages, I have worked on many projects for many
organisations, and I have observed that every different organisation has its
own idea of what constitutes "best practice" as every organisation has its
own version of a "development standards" document. Sometimes I have even
found different groups within the same organisation which have their own
version of the development standards. These "standards" were usually written
by a senior member of the project team, or in some cases handed down by a
project manager from the last project he worked on, and they do not identify
"best practice" across the industry as a whole, they simply reflect the
(in)experience or (in)competence of the individual author. In a great deal
of cases the authors of these documents regard them as being perfect and
will not discuss changes even if you show them a better way of doing
something, something which is faster to develop or which removes a common
cause of bugs.

So when you say "each language has it's collection of common knowledge known
as best practice" I must disagree. Each GROUP OF DEVELOPERS has its own
collection of common knowledge. The only way that standards from one group
are adopted by another is when developers change groups. In my experience
there are very few developers who have the ability to actually create high
quality development standards. They simply use what they are given without
question. When they move to a new project they simply take the previous
project's standards with them and carry on using them "as is" without the
slightest attempt to introduce improvments.

You (and others like you) seem to imply that there is a set of development
standards which applies to the industry as a whole and not just a particular
group. Have these standards been published anywhere? What is the level of
competence of the authors? What is their justification for their "rules"?

When I develop in any particlar language the only rules I wll accept are
contained within the language's Reference Manual. It tells me what commands
are available and what they do. How I use those commands is entirely up to
me. At the end of the day it is the results which I achieve and not the way
that I achieved them which is most important. I will NEVER put methodology
in front of results.

> A) I'm so much smarter than all the people who have worked with this
> language before, I can do it better, because I *really* know how it should
> be done. Screw the best-practices and the knowledge they have collected
> through decades of experience, I'll do it my way.

A lot of development standards that I have seen have not been devised after
careful consideration of all the options, of comparing the pros and cons of
different techniques to see which one offers the most advantages or the
least disadvantages, they have simply produced a document which says "this
is the way I do it, now everybody must do the same".

> B) I'll better listen to the masters if I want to be an expert in this
> language.

The only "masters" I have come across in my long career are "master baters".
A few years ago I worked on a large contract for a UK government department
in which the project designers insisted on an approach based on a
combination of OO techniques and the 3 tier architecture. They were so
engrossed in producing something that met their particular interpretations
of the rules that they lost sight of the real objective - to produce a
workable solution in a timeframe and to a budger which is acceptable to the
client. To cut a long story short these clowns spent 3 man years developing
an infrastructure, then when it came to building the first two components, a
screen into which you could enter selection criteria followed by a screen
which listed the rows which met that criteria, it took TWO developers TWO
weeks. The original development estimates were based on days per component,
so when these were recalculated using WEEKS instead of DAYS the client
realised that the project would be six months too late and £2 million over
budget. The entire project was immediate cancelled.

It turned out that half of the team had never used the development language
in question, and the other half had only used a previous version. I had used
the current version ever since it had been released and I had created my own
development environment which used the features of that language to achieve
the best results. I warned them that in my experience their approach was all
wrong and would not be acceptable to the client, but they refused to believe
me. "These methods are acceptable to us, they are the way of the future"
they said.

When the project was cancelled these people blamed the language for the
failure and not their methodologies. Just to make a point I went back to my
Head Office and converted my original 2 tier development environment into 3
tier and created the same two components (select and list). It took me just
TWO WEEKS. Not only that, within those two weeks I also created additional
components for insert, update, enquire and delete. When I showed the results
to my former workmates all they could say was "Unacceptable - your methods
are wrong". But guess which method would have been more acceptable to the
client?

Another organisation I visited a few years later advertised themselves as
"innovators" in this particular language, but when I got there and examined
their development standards I just could not believe it. I ended up by
writing a 17 page, 9000 word document which highlighted all the areas where
what they considered to be "best" practice was in fact the "worst" because
they were making the developer do extra work without any discernable
benefit, or in some cases to great disadvantage. I identified all the
different ways in which they could make improvements, but they refused to
believe me. As I had a copy of my own development environment on my laptop I
was able to show them. I took a component which they estimated would take
1.5 days using their methods and built it in 20 minutes using mine. They
were shocked on two counts - first because someone had the balls to tell
them that their methods were crap, and second because that same someone had
the means to prove it.

So when I say that I can take somebody else's development standards and make
drastic improvements I am not just blowing smoke. I have been creating my
own developments standards in different languages for the past 20 years, and
in every case I have knocked all comptetition into a cocked hat. Whatever
somebody says is "best" practice I come along and show them a way which is
"better".

> Guess what approach I prefer.
>
> > And then TMTOWTDI in a given language environment. Some people like to
> > have generic base classes, which they subclass to use in a generic
> > application. A lot of GUI frameworks (MFC, Borland's, QT) seem to be
based
> > around this idea. Others like to write generic classes, which handle any
> > given situation within
> > their stated problem domain. I like this method: Kind of a "Write
Once,
> > Forget Anywhere" method, where the class implementation is not important
> > once coded, and (hopefully), you can use the same class in a wide
variety
> > of projects, without having to change the class code.
>
> There are of course different ways of doing things that apply to different
> circumstances. That's why we have so many different programming languages.
> There is no language to end all languages, nor is there a single
> methodology that always works.

I agree entirely.

> Best-practices always apply within a
> context, nobody ever said that you should always use them,

That is why I choose not to follow what you consider to be "best practice"
because I have discovered something which I consider to be "better".

> although newbies
> tend to do that. But they are best-practices for a *reason*.

When a newbie joins an organisation he/she uses that organisation's
development standards because they are told to. If a newbie is learning a
language at home then he/she may use somebody else's standards simply
because they have got to start somewhere. But that should not prevent
anyone, after gaining experience in the language, from trying out different
methods to see if better results can be achieved. Anyone who follows a set
of standards without question will always be a second-rate programmer, and I
have seen many of those in my long career.

Tony Marston
http://www.tonymarston.net/


André Næss

unread,
Sep 1, 2003, 2:28:02 PM9/1/03
to
Tony Marston:

Ask a few Lisp developers and I'm sure they will tell you a lot about what
is/is not considered good code. It's quite interesting too, seeing as Lisp
is one of the most flexible languages we have today. Each programmer is
basically free to twist the language to his needs.

> The only way that standards from one
> group are adopted by another is when developers change groups. In my
> experience there are very few developers who have the ability to actually
> create high quality development standards.

Nobody create them, they emerge by the collective work of thousands of
developers. We are not talking about things like the Java Code Conventions
(http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html), although
they are useful too.

> They simply use what they are
> given without question. When they move to a new project they simply take
> the previous project's standards with them and carry on using them "as is"
> without the slightest attempt to introduce improvments.

Some people are bad craftsmen, I'm not going to argue that.

> You (and others like you) seem to imply that there is a set of development
> standards which applies to the industry as a whole and not just a
> particular group.

No I said language. Not the industry as a whole. And of course the lines
here are very fuzzy, some best-practices apply one to a narrow collection
of languages (e.g. how to write good macros in Lisp and derivates), whereas
others apply to many languages, like the best-practices we know for OOP.
Other things apply to functional languages, yet other to scripting
languages or loosely typed languages. It's a jungle out there.

> Have these standards been published anywhere?

No and yes. There is no bible, but there is a large body of books and
articles and newsgroup discussions that all taken together is the collected
knowledge. Certain books becomes classics, classics are considered such
because a large number of people view them as such. They might of course
all be wrong, which is why we have the occasional paradigm shift :)

> What is
> the level of competence of the authors? What is their justification for
> their "rules"?

Well since nobody creates the standards I can't answer that very well. All I
can say that I assume nobody come up with practices because they want to be
*worse* programmers, so I think it's safe to assume that they do so to
produce better software, to be better at their craft.

> When I develop in any particlar language the only rules I wll accept are
> contained within the language's Reference Manual. It tells me what
> commands are available and what they do. How I use those commands is
> entirely up to me. At the end of the day it is the results which I achieve
> and not the way that I achieved them which is most important. I will NEVER
> put methodology in front of results.

We are not talking about rules in such a strict sense. We've been talking
about common practices, things that developers have discovered during their
many years of trial and error. Look at "Design Patterns" by Gamma et. al.
This is just a collection of ideas that many many different designers had
known for years, many of which discovered them all by themselves. Hell,
when I read it for the first time I even recognized stuff that I had
understood while learning to program Java.

Of course one shouldn't put methodology in front of results, methodologies
were created for to achieve better results. But "better results" is not a
very precise metric. If you can save 10 hours on a 40 hour project then
that might be tempting to do. But if this results in a total of 40 extra
maintenance hours for the lifetime of the system then the total result is
negative. Most best practices are concerned with making system stable,
bug-free and maintainable, not fast to write. After all, a systems
lifecycle is normally dominated by the time *after* deployment, not before.

>> A) I'm so much smarter than all the people who have worked with this
>> language before, I can do it better, because I *really* know how it
>> should be done. Screw the best-practices and the knowledge they have
>> collected through decades of experience, I'll do it my way.
>
> A lot of development standards that I have seen have not been devised
> after careful consideration of all the options, of comparing the pros and
> cons of different techniques to see which one offers the most advantages
> or the least disadvantages, they have simply produced a document which
> says "this is the way I do it, now everybody must do the same".

Some examples would be very enlightening.

>> Best-practices always apply within a
>> context, nobody ever said that you should always use them,
>
> That is why I choose not to follow what you consider to be "best practice"
> because I have discovered something which I consider to be "better".

If you discover better ways to do things than what the current population of
developers seem to prefer you'd better publish it. I'll say one thing,
there are a lot of terrible programmers working with PHP, I guess mostly
because it is a widespread language for doing something a lot of people
seem to want to do. Just looking at a lot of the questions here makes you
realize that the level of competence is rather low, and that there
certainly is a long way to go before the best practices start to
crystalize. But arguments like this thread are an important factor as it
brings different developers practices under scrutiny.

André Næss

Tony Marston

unread,
Sep 3, 2003, 9:24:46 AM9/3/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bivrpi$do8$1...@maud.ifi.uio.no>...

Programming is an art, not a science, and different programmers, given
the same program to write in the same language, may produce acceptable
results but in a totally different style. The only way to say if a
program is badly written or well written is to evaluate it on certain
points:-

- does it do what it is supposed to do?
- does it do it efficiently?
- is it well structured?
- can you follow the structure?
- is it well documented?
- is it maintainable by any member of the development team?

This does not mean that you insist that everybody does things in a
rigid fashion as this stifles creativity and prevents improvements
from being discovered.

I have seen programs which ran like greased lightning rejected on the
grounds that the programming style was so obtuse that it copuld not be
maintained by anyone but the author. This is not acceptable.


> > The only way that standards from one
> > group are adopted by another is when developers change groups. In my
> > experience there are very few developers who have the ability to actually
> > create high quality development standards.
>
> Nobody create them, they emerge by the collective work of thousands of
> developers. We are not talking about things like the Java Code Conventions
> (http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html), although
> they are useful too.

But somebody must write them down and publish them, otherwise how are
the rest of us supposed to know about them?

> > They simply use what they are
> > given without question. When they move to a new project they simply take
> > the previous project's standards with them and carry on using them "as is"
> > without the slightest attempt to introduce improvments.
>
> Some people are bad craftsmen, I'm not going to argue that.
>
> > You (and others like you) seem to imply that there is a set of development
> > standards which applies to the industry as a whole and not just a
> > particular group.
>
> No I said language. Not the industry as a whole. And of course the lines
> here are very fuzzy, some best-practices apply one to a narrow collection
> of languages (e.g. how to write good macros in Lisp and derivates), whereas
> others apply to many languages, like the best-practices we know for OOP.
> Other things apply to functional languages, yet other to scripting
> languages or loosely typed languages. It's a jungle out there.

Best practices as defined by one group may be totally different to
those being used by another group. I refuse to accept that any one
group, however large, can enforce its viewpoint on the rest of the
community.

OOP is not a language, just a set of principles, and different
languages may implement these principles in a different manner. The
principles of OO say that I *can* create objects with methods and
properties - they do not say that I *must* create objects for this, or
I *must not* create objects for that, or I *must* use object
properties for this purpose and *not* that purpose, or that I *must*
use inheritance in this way and *not* that way. I am free to implement
the principles of OOP in any way I see fit. At the end of the day it
is the results that count, not the method that I used to obtain them.


> > Have these standards been published anywhere?
>
> No and yes. There is no bible, but there is a large body of books and
> articles and newsgroup discussions that all taken together is the collected
> knowledge.

But even among all this collected knowledge I bet you will find
disagreemnet and different interpretations. Just because one method is
right for one person does make make it automatically right for
everyone else.

> Certain books becomes classics, classics are considered such
> because a large number of people view them as such. They might of course
> all be wrong, which is why we have the occasional paradigm shift :)

For every book you find which advocates one particular theory or
method you will find others which support a contradictory theory or
method. They cannot all be right, and they cannot all be wrong. Each
theory will find its own group of supporters, and each group may have
success while following their chosen path. If there is room in the
universe for all these different methods and theories to co-exist,
then why cannot I be allowed to choose my own method of implementing
the principles of OOP?

> > What is
> > the level of competence of the authors? What is their justification for
> > their "rules"?
>
> Well since nobody creates the standards I can't answer that very well. All I
> can say that I assume nobody come up with practices because they want to be
> *worse* programmers, so I think it's safe to assume that they do so to
> produce better software, to be better at their craft.

If these "standards" are not published, then how are us mere mortals
supposed to know what they are? If each statement or rule is not fully
qualified and quantified then how do we know that the rule has been
properly evaluated against the alternatives and proven to be the best?
Quite often I have demolished other people's rules in the past simply
because they could not offer any justification for those rules. Unless
someone can prove to me the benefits of their set of rules then I see
no benefit in following them.

> > When I develop in any particlar language the only rules I wll accept are
> > contained within the language's Reference Manual. It tells me what
> > commands are available and what they do. How I use those commands is
> > entirely up to me. At the end of the day it is the results which I achieve
> > and not the way that I achieved them which is most important. I will NEVER
> > put methodology in front of results.
>
> We are not talking about rules in such a strict sense. We've been talking
> about common practices, things that developers have discovered during their
> many years of trial and error. Look at "Design Patterns" by Gamma et. al.
> This is just a collection of ideas that many many different designers had
> known for years, many of which discovered them all by themselves. Hell,
> when I read it for the first time I even recognized stuff that I had
> understood while learning to program Java.

But what may be common to one group of developers may be uncommon to
another. Or different groups of developers may have found different
solutions to the same problem. Trying to force one solution upon all
groups of developers is out of order.

> Of course one shouldn't put methodology in front of results, methodologies
> were created for to achieve better results. But "better results" is not a
> very precise metric. If you can save 10 hours on a 40 hour project then
> that might be tempting to do. But if this results in a total of 40 extra
> maintenance hours for the lifetime of the system then the total result is
> negative. Most best practices are concerned with making system stable,
> bug-free and maintainable, not fast to write. After all, a systems
> lifecycle is normally dominated by the time *after* deployment, not before.

You seem to imply that just because I use different methods from yours
that my code is automatically full of bugs and difficult to maintain.
That is a false assumption. I write code to high standards because it
has to be held up as an example to all other programmers in my team.
If you take a look at
http://www.tonymarston.net/php-mysql/dateclass.html you will see an
example of my coding style. Notice how I break up groups of code with
blank lines, notice that I use lots of comments. Also notice how I
break up the regular expressions into their component parts so that
even someone new to regular expressions has a chance to understand
them.



> >> A) I'm so much smarter than all the people who have worked with this
> >> language before, I can do it better, because I *really* know how it
> >> should be done. Screw the best-practices and the knowledge they have
> >> collected through decades of experience, I'll do it my way.

Unfortunately all of the "best practices" I have encountered in the
past have been the best that a particular individual or small group of
individuals can do, and not the collective knowledge of the whole
programming community. These people do not have decades of experience,
and their personal best can often be bettered by someone else. They
simply stop at the first method that works and stick to it, while I
like to experiment and try to find a better method, somthing which is
faster or has fewer bugs or has more options.

> > A lot of development standards that I have seen have not been devised
> > after careful consideration of all the options, of comparing the pros and
> > cons of different techniques to see which one offers the most advantages
> > or the least disadvantages, they have simply produced a document which
> > says "this is the way I do it, now everybody must do the same".
>
> Some examples would be very enlightening.

Take a look at http://www.marston-home.demon.co.uk/Tony/uniface/standards.html
which contains some examples of bad practices which I have encountered
in my long career.



> >> Best-practices always apply within a
> >> context, nobody ever said that you should always use them,
> >
> > That is why I choose not to follow what you consider to be "best practice"
> > because I have discovered something which I consider to be "better".
>
> If you discover better ways to do things than what the current population of
> developers seem to prefer you'd better publish it.

I have discovered a *different* way, not necessarily a *better* way.
Yet some people seem to think that I am not allowed to be different.

> I'll say one thing,
> there are a lot of terrible programmers working with PHP, I guess mostly
> because it is a widespread language for doing something a lot of people
> seem to want to do. Just looking at a lot of the questions here makes you
> realize that the level of competence is rather low, and that there
> certainly is a long way to go before the best practices start to
> crystalize. But arguments like this thread are an important factor as it
> brings different developers practices under scrutiny.

There are bad programmers in every language, and these programmers
will always be bad regardless of which language they use or which
methodology they follow. Some programmers have the potential of being
very good if only they can get the right sort of training or
instruction at an early stage. But telling them that there is *only
one way* to do things is quite wrong, just as it is wrong to say that
there is *only one true religion*. It is correct to identify the
difference between different methods, such as "this is faster to
implement" or "this has fewer bugs" or "this is easier to maintain",
but it is wrong to say "there is only one way, and this is *it* and
you must not deviate from the path". An individual's creativity must
be allowed to shine otherwise everything will remain the same and
there will never be any progress.

My motto is "innovate, don't immitate".

Here endeth the lesson.

André Næss

unread,
Sep 3, 2003, 12:58:02 PM9/3/03
to
Tony Marston:

>> > I have been a software engineer for 25 years using a variety of 2nd,
>> > 3rd and 4th generation langages, I have worked on many projects for
>> > many organisations, and I have observed that every different
>> > organisation has its own idea of what constitutes "best practice" as
>> > every organisation has its own version of a "development standards"
>> > document. Sometimes I have even found different groups within the same
>> > organisation which have their own version of the development standards.
>> > These "standards" were usually written by a senior member of the
>> > project team, or in some cases handed down by a project manager from
>> > the last project he worked on, and they do not identify "best practice"
>> > across the industry as a whole, they simply reflect the (in)experience
>> > or (in)competence of the individual author. In a great deal of cases
>> > the authors of these documents regard them as being perfect and will
>> > not discuss changes even if you show them a better way of doing
>> > something, something which is faster to develop or which removes a
>> > common cause of bugs.
>> >
>> > So when you say "each language has it's collection of common knowledge
>> > known as best practice" I must disagree. Each GROUP OF DEVELOPERS has
>> > its own collection of common knowledge.
>>
>> Ask a few Lisp developers and I'm sure they will tell you a lot about
>> what is/is not considered good code. It's quite interesting too, seeing
>> as Lisp is one of the most flexible languages we have today. Each
>> programmer is basically free to twist the language to his needs.
>
> Programming is an art, not a science

Indeed.

> , and different programmers, given
> the same program to write in the same language, may produce acceptable
> results but in a totally different style. The only way to say if a
> program is badly written or well written is to evaluate it on certain
> points:

Certainly. But in every language there are things you simply should avoid.
Style guides always say "You really shouldn't do this unless you have a
good reason", and they do so because years of practice have shown why doing
so is not a good idea. But they don't disallow it completely. One of the
best guidelines I know of is that whenever you do something which is
considered bad practice you comment it (thoroughly) to explain your
rationale. I think this is a pretty universal "best practice".

> This does not mean that you insist that everybody does things in a
> rigid fashion as this stifles creativity and prevents improvements
> from being discovered.

Nobody has ever threated with the use of force, or in any way insisted on
anything. This thread has been a simple discussion about design. If I
believe that a certain way of designing something is better than a
different way, then of course I will try to explain my view! I've never
claimed that "best practices" are anything more than *guidelines*.

> I have seen programs which ran like greased lightning rejected on the
> grounds that the programming style was so obtuse that it copuld not be
> maintained by anyone but the author. This is not acceptable.

What is not acceptable? That the code was unreadable or that it wasn't
accepted due to it's unmaintainable nature?


>> > The only way that standards from one
>> > group are adopted by another is when developers change groups. In my
>> > experience there are very few developers who have the ability to
>> > actually create high quality development standards.
>>
>> Nobody create them, they emerge by the collective work of thousands of
>> developers. We are not talking about things like the Java Code
>> Conventions
>> (http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html), although
>> they are useful too.
>
> But somebody must write them down and publish them, otherwise how are
> the rest of us supposed to know about them?

They are written down and published of course, through the WWW, through
books, through Usenet etc. As a beginner in language X it will of course
take you some time to master all these things. In general I think it takes
something like 10 years to become a good programmer (I think this is common
to most crafts), and it probably takes quite a while to become a good
programmer in language X, even after 10 years of general programming
experience.

>> > They simply use what they are
>> > given without question. When they move to a new project they simply
>> > take the previous project's standards with them and carry on using them
>> > "as is" without the slightest attempt to introduce improvments.
>>
>> Some people are bad craftsmen, I'm not going to argue that.
>>
>> > You (and others like you) seem to imply that there is a set of
>> > development standards which applies to the industry as a whole and not
>> > just a particular group.
>>
>> No I said language. Not the industry as a whole. And of course the lines
>> here are very fuzzy, some best-practices apply one to a narrow collection
>> of languages (e.g. how to write good macros in Lisp and derivates),
>> whereas others apply to many languages, like the best-practices we know
>> for OOP. Other things apply to functional languages, yet other to
>> scripting languages or loosely typed languages. It's a jungle out there.
>
> Best practices as defined by one group may be totally different to
> those being used by another group. I refuse to accept that any one
> group, however large, can enforce its viewpoint on the rest of the
> community.

Of course they can't, and that is not the point. The point is that certain
things are fairly universally agreed, whereas others may be more debated.
It always pays to listen to the community when you are new to a language.

> But even among all this collected knowledge I bet you will find
> disagreemnet and different interpretations. Just because one method is
> right for one person does make make it automatically right for
> everyone else.

Err... The *point* of collective knowledge is that it is not the ideas of a
single person. Unless a method is right for many people it simply isn't
collective, by definition! This is not a one-to-many relationship, where
the guru sits at the front of his class disclosing his wisdom. This is more
like a many-to-one relationship where a huge bunch of mini-gurus sit at the
front of a neophyte and explain the Tao to him.



> If these "standards" are not published, then how are us mere mortals
> supposed to know what they are?

See above.



>> > When I develop in any particlar language the only rules I wll accept
>> > are contained within the language's Reference Manual. It tells me what
>> > commands are available and what they do. How I use those commands is
>> > entirely up to me. At the end of the day it is the results which I
>> > achieve and not the way that I achieved them which is most important. I
>> > will NEVER put methodology in front of results.
>>
>> We are not talking about rules in such a strict sense. We've been talking
>> about common practices, things that developers have discovered during
>> their many years of trial and error. Look at "Design Patterns" by Gamma
>> et. al. This is just a collection of ideas that many many different
>> designers had known for years, many of which discovered them all by
>> themselves. Hell, when I read it for the first time I even recognized
>> stuff that I had understood while learning to program Java.
>
> But what may be common to one group of developers may be uncommon to
> another. Or different groups of developers may have found different
> solutions to the same problem. Trying to force one solution upon all
> groups of developers is out of order.

Yes yes yes :P The point was simply that almost *everyone* I've encountered
have agreed with a fairly large percentage of the ideas put forth in
"Design Patterns", so there must be some good ideas there. "Don't kill
other people" is more universally agreed upon than "Don't drink beer". Of
course there are people who even disagree with the idea to not kill other
people, but they generally wind up in prison.



>> Of course one shouldn't put methodology in front of results,
>> methodologies were created for to achieve better results. But "better
>> results" is not a very precise metric. If you can save 10 hours on a 40
>> hour project then that might be tempting to do. But if this results in a
>> total of 40 extra maintenance hours for the lifetime of the system then
>> the total result is negative. Most best practices are concerned with
>> making system stable, bug-free and maintainable, not fast to write. After
>> all, a systems lifecycle is normally dominated by the time *after*
>> deployment, not before.
>
> You seem to imply that just because I use different methods from yours
> that my code is automatically full of bugs and difficult to maintain.
> That is a false assumption.

It certainly is a false assumption on your part. I imply no such thing. In
this thread I argued why I thought a better design was possible, and I
think I spent some time explaining *why*. You disagreed. So it goes.

> I write code to high standards because it
> has to be held up as an example to all other programmers in my team.
> If you take a look at
> http://www.tonymarston.net/php-mysql/dateclass.html you will see an
> example of my coding style. Notice how I break up groups of code with
> blank lines, notice that I use lots of comments. Also notice how I
> break up the regular expressions into their component parts so that
> even someone new to regular expressions has a chance to understand
> them.

Those are merely style issues. While they are certainly important, I don't
think they are that relevant to this discussion.

> Unfortunately all of the "best practices" I have encountered in the
> past have been the best that a particular individual or small group of
> individuals can do, and not the collective knowledge of the whole
> programming community.

If you have had no experience with the best-practices I've been talking
about, then why do you still seem so hostile against them? It's a bit like
arguing if X is a good language without having ever experienced X in any
way.

> But telling them that there is *only
> one way* to do things is quite wrong, just as it is wrong to say that
> there is *only one true religion*. It is correct to identify the
> difference between different methods, such as "this is faster to
> implement" or "this has fewer bugs" or "this is easier to maintain",

But saying "This is better because it leads to better maintainability/faster
code/fewer bugs" presumably isn't.

> An individual's creativity must
> be allowed to shine otherwise everything will remain the same and
> there will never be any progress.

But it is certainly a shame when an individual's creativity is wasted on
rediscovering stuff that has been known to fellow craftsmen for decades.
Reinventing the wheel doesn't exactly generate much progress.

André Næss

Tony Marston

unread,
Sep 9, 2003, 11:26:32 AM9/9/03
to
André N?ss <andrena.spa...@ifi.uio.no> wrote in message news:<bj4v8e$scv$1...@maud.ifi.uio.no>...
> Tony Marston:
>
<snip>

>
> > Programming is an art, not a science
>
> Indeed.
>
> > , and different programmers, given
> > the same program to write in the same language, may produce acceptable
> > results but in a totally different style. The only way to say if a
> > program is badly written or well written is to evaluate it on certain
> > points:
>
> Certainly. But in every language there are things you simply should avoid.

Then take the matter up with the authors of those languages.

Every language has its own set of commands which are there for each
programmer to use as he sees fit. Some commands are better at
achieving certain results than others, but the purpose of the
programmer is to string together a series of commands in a particular
sequence to achieve a certain result. There is no "right" series or
sequence of commands, just a "right" result. The skill in programming
comes in choosing the most efficient series of commands, eliminating
the possibility of any bugs, and writing code that can be read,
understood and maintained by others as well as by yourself.

Some people may decide to ban certain commands for totally ridiculous
reasons. As an example many years ago I joined a COBOL project team
and read in their development guidelines that the COMPUTE verb was not
to be used. Having used it successfully on previous projects I asked
the project leader the reason why, only to be told "because it is
inefficient". It turned out that he had discovered some junior
programmers were using this verb for simple incrementing (as in:
COMPUTE A = A+1) instead of for complex calculations, but instead of
educating them on how to use the verb efficiently he issued a total
ban. That shows the level of competence I have encountered in people
who are supposed to be my "masters".

In my 25+ years of programming there has only ever been one command
that I have banned from my repertoire and have urged other people to
avoid, and that is the ALTER verb in COBOL. Why? Because it allows an
instruction to be alterered at runtime. Why is this a problem? Have
you tried debugging a program where the instruction that you see in
the source code is different from the one actually being executed? All
I had to do when a fellow programmer thought of using this command was
to explain the potential problem and inform them that if anything went
wrong with the program they would be given the task of debugging it
and their enthusiasm for using it would suddenly evaporate. Issuing a
blanket ban on something without giving a proper explanation,
especially one that can be challenged, is something I find
unacceptable.

So when someone tells me that I must NOT create classes for so-and-so,
and I must NOT use class variables for so-and-so, and I must NOT use
subclassing for so-and-so, I demand to know why. Where are these rules
published? Who wrote them? What is the logic behind them? Where do I
go if I want to challenge this logic?


> Style guides always say "You really shouldn't do this unless you have a
> good reason", and they do so because years of practice have shown why doing
> so is not a good idea.

I have seen too many style guides which simply say "Do it *this* way
because I don't like *that* way". Yet when I work with another group
their attitude is "Do it *that* way because I don't like *this* way".
There is no one style which is universally accepted by all groups as
each group chooses its own style based on the limited experiences of
the members of that particular group. Some groups simply latch onto
the first method they come across that works and never bother
experimenting with other methods to see if there is a *better* way.

In any language (and I have used quite a few in my time) there can be
more than one method of achieving a certain result, and no method can
be said to be either *right* or *wrong*, merely *different*. Each
method may have its own set of advantages and disadvantages, and it is
down to the skill of the individual programmer to exploit the
advantages and reduce the disadvantages of any chosen method.

I have come across several cases where a particular group has chosen
method "A" over method "B" simply because they have difficulty in
implementing method "B". I choose method "B" because it produces a
better result, and my skill as a programmer gives me the ability to
overcome any "difficulties" in its implementation. So just because
method "A" is right for them does not mean that method "B" is wrong,
and just because method "B" is right for me does not mean that method
"A" is wrong. Both methods work so neither of them can said to be
"wrong". Any group should be entitled to choose whatever method they
see fit as there is no single method which is "right" for everybody.

When you say that style guides represent "best practice based on years
of experience" I have to disagree. Every particular style guide that I
have ever encountered has represented nothing more than the limited
experience of its authors and not the total experience of the wider
programming community. You will never get all the programmers in any
particular language or methodology to universally agree that any
particular method is either "right" or "wrong", so don't waste your
time trying.

Each programmer or group of programmers should be free to choose
whatever method they see fit to achieve the expected results, and
these programmers should also be free to experiment with new methods
in search of something which may be "better". Any new methods they
discover they may decide to keep secret so that they can gain a
advantage over their competitors, or they may decide to publish them
so that the world at large may benefit from their inventiveness. That
is what I attempted to do when I published my article, only to be told
"WE are the masters, WE have already invented the perfect solution,
HOW DARE YOU think that you could possibly invent something better".
THAT is the attitude that I am fighting against.

> > This does not mean that you insist that everybody does things in a
> > rigid fashion as this stifles creativity and prevents improvements
> > from being discovered.
>
> Nobody has ever threated with the use of force, or in any way insisted on
> anything. This thread has been a simple discussion about design. If I
> believe that a certain way of designing something is better than a
> different way, then of course I will try to explain my view! I've never
> claimed that "best practices" are anything more than *guidelines*.

Then why is it that certain people out there have not said "your
method may work, but here is a method which I think is better" but
"whether it works or not is irrelevant because it breaks OUR set of
rules". They have given no justification for their rules, just simply
said "this is the way that WE do it, and you are NOT allowed to do it
differently". As I do not see any merit in their so-called "rules" I
see abolutely no reason why I should abide by them. I think they are
just as much rubbish as most of the other "rules" I have encounered in
my long career as a software engineer.

> > I have seen programs which ran like greased lightning rejected on the
> > grounds that the programming style was so obtuse that it copuld not be
> > maintained by anyone but the author. This is not acceptable.
>
> What is not acceptable? That the code was unreadable or that it wasn't
> accepted due to it's unmaintainable nature?

The code was rejected because none of the other team members could
understand it and none was prepared to maintain it. The author chose
to use a particular set of commands in a rather obscure fashion just
to prove how clever he was, and none of the other team members could
understand how it worked. That is why for the past 20 years I have
favoured a style called "ego-less" programming in which it should not
be possible to determine the author of a piece of work just by looking
at how it is written. Every team member, from the highest to the
lowest, should be able to look at the source code for any program and
think to himself "I might have written that".



> >> > The only way that standards from one
> >> > group are adopted by another is when developers change groups. In my
> >> > experience there are very few developers who have the ability to
> >> > actually create high quality development standards.
> >>
> >> Nobody create them, they emerge by the collective work of thousands of
> >> developers. We are not talking about things like the Java Code
> >> Conventions
> >> (http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html), although
> >> they are useful too.
> >
> > But somebody must write them down and publish them, otherwise how are
> > the rest of us supposed to know about them?
>
> They are written down and published of course, through the WWW, through
> books, through Usenet etc.

That is the problem. There is too much information out there, and a
great deal of it is conflicting and contradictory, so which do I
choose?

<snip>



> > Best practices as defined by one group may be totally different to
> > those being used by another group. I refuse to accept that any one
> > group, however large, can enforce its viewpoint on the rest of the
> > community.
>
> Of course they can't, and that is not the point. The point is that certain
> things are fairly universally agreed, whereas others may be more debated.
> It always pays to listen to the community when you are new to a language.

Nothing is universally agreed. Different groups will always have
different viewpoints. None is either "right" or "wrong", merely
"different". Even in the OO community there are some who say that
things like multiple inheritance are the best thing since sliced bread
while others say that they are more trouble than they are worth. There
is yet another group which says that OOP is on its way out and that
AOP (Aspect-Oriented Programming) is the new paradigm.

> > But even among all this collected knowledge I bet you will find
> > disagreemnet and different interpretations. Just because one method is
> > right for one person does make make it automatically right for
> > everyone else.
>
> Err... The *point* of collective knowledge is that it is not the ideas of a
> single person. Unless a method is right for many people it simply isn't
> collective, by definition! This is not a one-to-many relationship, where
> the guru sits at the front of his class disclosing his wisdom. This is more
> like a many-to-one relationship where a huge bunch of mini-gurus sit at the
> front of a neophyte and explain the Tao to him.

But just because a particular method may be accepted by one part of
the community should not be used as an excuse to prevent anybody from
experimenting with new and different methods. Without experimentation
there will be no innovation and no progress.

<snip>

> >> We are not talking about rules in such a strict sense. We've been talking
> >> about common practices,

But what is common practice to one group may not be common practice to
another. So how do I know which group to follow?

> >> things that developers have discovered during
> >> their many years of trial and error.

But different groups of programmers have discovered different
solutions to similar problems. So how do I know which group to follow?

> >> Look at "Design Patterns" by Gamma
> >> et. al. This is just a collection of ideas that many many different
> >> designers had known for years, many of which discovered them all by
> >> themselves.

But the things which are known to one group of programmers may be
different from the things which are known to another, so which group
do I follow?

> >> Hell, when I read it for the first time I even recognized
> >> stuff that I had understood while learning to program Java.
> >
> > But what may be common to one group of developers may be uncommon to
> > another. Or different groups of developers may have found different
> > solutions to the same problem. Trying to force one solution upon all
> > groups of developers is out of order.
>
> Yes yes yes :P The point was simply that almost *everyone* I've encountered
> have agreed with a fairly large percentage of the ideas put forth in
> "Design Patterns", so there must be some good ideas there.

Just because a large number of programmers have decided to use a set
of design patterns which someone has published does not mean that
everyone else should accept them without question. I have my own
patterns which I have been using successfully for the past 10 years,
so why should I switch?

<snip>

> > You seem to imply that just because I use different methods from yours
> > that my code is automatically full of bugs and difficult to maintain.
> > That is a false assumption.
>
> It certainly is a false assumption on your part. I imply no such thing. In
> this thread I argued why I thought a better design was possible, and I
> think I spent some time explaining *why*. You disagreed. So it goes.

But you argued that by having a separate class for each database table
I was introducing a maintenace problem because I would have to change
the class each time I changed the structure of the table. This
presents no more of a maintenace problem than with any other method. I
don't know how you write programs, but for the past 20 years I have
never written a program which accesses an external file without that
program having some idea of the structure of that file being built
into the code. If you change the structure of the file then you must
change the structure in the code otherwise there will be problems.
Even if you use a language with a data dictionary (and I have been
using such a language for the past 10 years) you cannot change the
structure of the file without changing the reference to that file in
the data dictionary.

> > I write code to high standards because it
> > has to be held up as an example to all other programmers in my team.
> > If you take a look at
> > http://www.tonymarston.net/php-mysql/dateclass.html you will see an
> > example of my coding style. Notice how I break up groups of code with
> > blank lines, notice that I use lots of comments. Also notice how I
> > break up the regular expressions into their component parts so that
> > even someone new to regular expressions has a chance to understand
> > them.
>
> Those are merely style issues. While they are certainly important, I don't
> think they are that relevant to this discussion.

But that demonstrates that I can write code which is just as readable,
and therefore maintainable, as anyone else. This should be the major
issue here and not "you cannot use that feature of the language in
that way". I must be free to use whatever features of the language
that are available in whatever combination I choose in order to
achieve a result. Provided that the code I produce is well structured,
well documented and can be read, understood and maintained by others
should be the only yardstick. If someone can point to a piece of my
code and say "if you used this bit of code instead of that it would be
more efficient" or "are you aware of a poptential bug in this area"
then I would be prepared to listen. Constructive criticism is always
welcome, but non-constructive criticism is a waste of time.

> > Unfortunately all of the "best practices" I have encountered in the
> > past have been the best that a particular individual or small group of
> > individuals can do, and not the collective knowledge of the whole
> > programming community.
>
> If you have had no experience with the best-practices I've been talking
> about, then why do you still seem so hostile against them?

Because I see no reason to believe that the "best practices" you are
talking about are any better than the examples of "best practice"
which I have encountered in the past 20 years. My idea of "best
practice" is what produces the best results in the shortest possible
time, while others seem intent on creating a set of innefficient rules
and sticking to them regardless of how long it takes to produce the
results.

> > But telling them that there is *only
> > one way* to do things is quite wrong, just as it is wrong to say that
> > there is *only one true religion*. It is correct to identify the
> > difference between different methods, such as "this is faster to
> > implement" or "this has fewer bugs" or "this is easier to maintain",
>
> But saying "This is better because it leads to better maintainability/faster
> code/fewer bugs" presumably isn't.

If one method has more advantages and less disadvantages than another
then it can certainly be said to be better. But as far as ths thread
goes nobody has offered me any proof that my method is worse than
theirs. They just assume that just because it is different it is bound
to be inefficient and unmaintainable. Some people have suggested
alternative methods, but I have yet to see any advantage in adopting
them. I will not change my methods unless I see a distinct benefit in
doing so.

> > An individual's creativity must
> > be allowed to shine otherwise everything will remain the same and
> > there will never be any progress.
>
> But it is certainly a shame when an individual's creativity is wasted on
> rediscovering stuff that has been known to fellow craftsmen for decades.

But different groups *know* different solutions to similar problems,
and my point is that there will never be just one solution to any
given problem. Every solution is *right* and no solution is *wrong*.
Just because there are 100 possible solutions already out there should
not prevent me, or anyone else, from creating solution 101.

> Reinventing the wheel doesn't exactly generate much progress.

I am not reinventing the wheel, just devising a different process for
making one, and I am receiving abuse from certain quarters just
because I have created a methodology which is different from theirs.
The fact that the results of my design are just as efficient and
maintainable as anyone else's does not seem to enter the equation.

Tony (you do it your way and I'll do it better) Marston
http://www.tonymarston.net/

lawrence

unread,
Sep 9, 2003, 5:32:30 PM9/9/03
to
"Tony Marston" <to...@NOSPAM.demon.co.uk> wrote in message news:<biv89e$6pq$1$830f...@news.demon.co.uk>...>


You should send this story to Robert Glass, who does all those books
on software projects gone bad. Maybe he'll use your story in his next
book.

lawrence

unread,
Sep 9, 2003, 5:42:11 PM9/9/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message

I think Andre sums it up well. The legal equivalent would be English
Common Law, or perhaps, in general, case law. A civil society will
generate standards with input from every group in the community. The
process is chaotic and contradictory, but as time passes certain
themes repeat, and the themes that repeat become the conventional
wisdom of that society. And sometimes the society is wrong, as Andre
says, and later a paradigm shift occurs.

Now assume "society" above refers to the community of programmers that
work wtih a particular language and you'll see the analogy.

However, some books do a good job of really writing down the core
wisdom of a community. For Java I suggest "Effective Java" by Joshua
Block, which contains 57 rules for writing good Java code. An example
rule: #14 Favor composition over inheritance.

lawrence

unread,
Sep 9, 2003, 5:45:09 PM9/9/03
to
André N?ss <andrena.spa...@ifi.uio.no> wrote in message
> If you discover better ways to do things than what the current population of
> developers seem to prefer you'd better publish it. I'll say one thing,
> there are a lot of terrible programmers working with PHP, I guess mostly
> because it is a widespread language for doing something a lot of people
> seem to want to do. Just looking at a lot of the questions here makes you
> realize that the level of competence is rather low, and that there
> certainly is a long way to go before the best practices start to
> crystalize. But arguments like this thread are an important factor as it
> brings different developers practices under scrutiny.

Inevitable with an easy to learn script language, no? The whole point
is to allow non-programmers to do some programming. And this is the
wave of the future, yes?

lawrence

unread,
Sep 9, 2003, 6:26:40 PM9/9/03
to
to...@marston-home.demon.co.uk (Tony Marston) wrote in message news:<7588a50f.03090...@posting.google.com>...

> André N?ss <andrena.spa...@ifi.uio.no> wrote in message news:<bj4v8e$scv$1...@maud.ifi.uio.no>...
> > Tony Marston:
> > Certainly. But in every language there are things you simply should avoid.
>
> Then take the matter up with the authors of those languages.

There is often nothing to be taken up because the flaws of one
language are often a part of its strengths. There is no perfect
language. Should I go to the authors of Java and say "Hey, using Java,
I can't write simple programs as quickly as I write them in PHP!" That
would be a stupid complaint, and they would be right to responsd,
"Then go use PHP!"

What Andre is saying is that you should know the strengths and
weaknesses of a language, and use it for its strengths, and avoid its
weaknesses. For instance, don't try to write 5 line programs in Java.
For something that small, a script language will give you many
benefits and no disadvantages.


> Some people may decide to ban certain commands for totally ridiculous
> reasons. As an example many years ago I joined a COBOL project team
> and read in their development guidelines that the COMPUTE verb was not
> to be used. Having used it successfully on previous projects I asked
> the project leader the reason why, only to be told "because it is
> inefficient". It turned out that he had discovered some junior
> programmers were using this verb for simple incrementing (as in:
> COMPUTE A = A+1) instead of for complex calculations, but instead of
> educating them on how to use the verb efficiently he issued a total
> ban. That shows the level of competence I have encountered in people
> who are supposed to be my "masters".

Why are you calling this manager a master? Was he internationally
recognized as such? Did the worldwide community of COBOL programmers
follow his lead and give up using the COMPUTE verb? If not, then
you're talking about something quite different than what Andre was
talking about. Andre is talking about those practices which are so
clearly beneficial that all the programmers of a language, once
exposed to those ideas, tend to use them. You are bringing up a
subject completely unrelated to what Andre was talking about. You have
now written several posts and all of your posts have the same theme.
In all of your posts you talk about bad managers. But Andre is very
clearly not talking about bad managers. He is talking about those
practices that seem so obviously intelligent that everyone will do
them once they are taught them.

An example: in PHP it is possible to break encapsulation by directly
referencing a class variable, rather than getting the value through
an accessor method. If you teach people why this is stupid, then only
the stupid people will continue to do it. Thus, preserving
encapsulation, even when a language allows it, is cleary a practice of
such merit that we can without reservation call it a "best practice."

Your stories of bad managers are entertaining and perhaps you should
send them to Robert Glass. Perhaps he'll use them in his next book.
But you can stop telling such stories in this thread. They are not
relevant. They have nothing to do with what is under discussion. We
are discussing best practices and you keep raising worst practices.

Tony Marston

unread,
Sep 11, 2003, 3:32:06 AM9/11/03
to
lkru...@geocities.com (lawrence) wrote in message news:<da7e68e8.03090...@posting.google.com>...

> André Næss <andrena.spa...@ifi.uio.no> wrote in message
>
> > We are not talking about rules in such a strict sense. We've been talking
> > about common practices, things that developers have discovered during their
> > many years of trial and error. Look at "Design Patterns" by Gamma et. al.
> > This is just a collection of ideas that many many different designers had
> > known for years, many of which discovered them all by themselves. Hell,
> > when I read it for the first time I even recognized stuff that I had
> > understood while learning to program Java.
>
> I think Andre sums it up well. The legal equivalent would be English
> Common Law, or perhaps, in general, case law.

At least the laws of the land, regardless of their origin, are all
documented and are available in law libraries. These so-called
theories of "best practice" are not maintained in any sort of a
central library where individuals can refer to them. They exist all
over the place and often one set of theories contradict another, so
how is anybody to know which theory to follow? I consider these
different theories to be analogous to religions where the acolytes
always believe that *their* brand is the one true religion and
everybody else is a blasphemer or a devil worshipper.

The only "laws" that can be applied in any programming language are
documented in that language's reference manual. All these different
methodologies are nothing more than "religions" that any individual
may choose to follow (or not) as he/she sees fit.

> A civil society will
> generate standards with input from every group in the community.

I am not interested I "standards" that may vary from group to group, I
am talking about "laws" that one group tries to impose on another.
Standards can vary from one group to another, but laws apply to
everybody.

> The process is chaotic and contradictory, but as time passes certain
> themes repeat, and the themes that repeat become the conventional
> wisdom of that society. And sometimes the society is wrong, as Andre
> says, and later a paradigm shift occurs.
>
> Now assume "society" above refers to the community of programmers that
> work wtih a particular language and you'll see the analogy.

The only analogy that I can see is that one group in society has a set
of "standards" which it now wants treated as a set of "laws" which it
can impose on others.

As far as I am concerned the only "universal standard" that I am
prepared to follow is *how* to write code, not *what* code to write.
Good code should be well structured, well documented, readable and
readily maintainable by other programmers. When it comes to the
commands that I use, or how I use them, that is nobody's business but
mine.

> However, some books do a good job of really writing down the core
> wisdom of a community. For Java I suggest "Effective Java" by Joshua
> Block, which contains 57 rules for writing good Java code. An example
> rule: #14 Favor composition over inheritance.

I have read the Java Code Conventions at
http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html and they
seem quite reasonable to me. But notice how the emphasis is on "how to
write code that is readable" and not "what code to write". It does not
say "you must use classes in *this* way and not *that* way" or "you
must use class variables for *this* purpose and not *that* purpose" or
"you must use subclassing and inheritance in *this* way and not *that*
way".

Tony (do you want it done your way, or do you want it done properly?)
Marston
http://www.tonymarston.net/

Tony Marston

unread,
Sep 11, 2003, 11:01:59 AM9/11/03
to
lkru...@geocities.com (lawrence) wrote in message news:<da7e68e8.03090...@posting.google.com>...
> to...@marston-home.demon.co.uk (Tony Marston) wrote in message news:<7588a50f.03090...@posting.google.com>...
> > André N?ss <andrena.spa...@ifi.uio.no> wrote in message news:<bj4v8e$scv$1...@maud.ifi.uio.no>...
> > > Tony Marston:
> > > Certainly. But in every language there are things you simply should avoid.
> >
> > Then take the matter up with the authors of those languages.
>
> There is often nothing to be taken up because the flaws of one
> language are often a part of its strengths. There is no perfect
> language. Should I go to the authors of Java and say "Hey, using Java,
> I can't write simple programs as quickly as I write them in PHP!" That
> would be a stupid complaint, and they would be right to responsd,
> "Then go use PHP!"
>
> What Andre is saying is that you should know the strengths and
> weaknesses of a language, and use it for its strengths, and avoid its
> weaknesses. For instance, don't try to write 5 line programs in Java.
> For something that small, a script language will give you many
> benefits and no disadvantages.

All this has got nothing to do with my original argument, which is
that I have been told:
a) I must not create a separate class for each table in my database.
b) I must not create an abstract database class and have each table
class as a subclass.
c) I must not use class variables to hold the components of the sql
LIMIT clause.



> > Some people may decide to ban certain commands for totally ridiculous
> > reasons. As an example many years ago I joined a COBOL project team
> > and read in their development guidelines that the COMPUTE verb was not
> > to be used. Having used it successfully on previous projects I asked
> > the project leader the reason why, only to be told "because it is
> > inefficient". It turned out that he had discovered some junior
> > programmers were using this verb for simple incrementing (as in:
> > COMPUTE A = A+1) instead of for complex calculations, but instead of
> > educating them on how to use the verb efficiently he issued a total
> > ban. That shows the level of competence I have encountered in people
> > who are supposed to be my "masters".
>
> Why are you calling this manager a master? Was he internationally
> recognized as such?

When you are learning a language your superiors at your place of
employment are supposed to be “the masters” based upon their
supposedly superior experience. When they give you their ideas of
“best practice” in the form of project development standards you are
supposed to believe everything that they say and follow it religiously
without question. You are not allowed to go to outside sources for
their ideas on what consitutes “best practice”.

> Did the worldwide community of COBOL programmers
> follow his lead and give up using the COMPUTE verb?

You have hit the nail on the head! The worldwide community of COBOL
programmers did not follow his lead simply because his idea of “best
practice” was totally different from theirs. But if that version of
“best practice” can be treated as rubbish, then why can’t others? Who
is to say that somebody else’s version of “best practice” is not just
as much rubbish as that one? Just because something is labelled “best
practice” does not necessarily make it so. THAT is my point.

> If not, then
> you're talking about something quite different than what Andre was
> talking about. Andre is talking about those practices which are so
> clearly beneficial that all the programmers of a language, once
> exposed to those ideas, tend to use them.

Most programmers follow standards because they are told to, not
because they choose to. This should prevent them from examining those
standards in detail to find out if the logic behind them is actually
sound, or if any parts have been superseded by updates to the
language. When it comes to designing solutions to a problem they
should not be prevented from trying alternative methods as they may
discover new methods which are actually superior. Just because
somebody has found a method that works does not give them
justification to enforce that method on everybody else.

> You are bringing up a
> subject completely unrelated to what Andre was talking about. You have
> now written several posts and all of your posts have the same theme.
> In all of your posts you talk about bad managers.

You are missing the point. All these managers produced development
standards and methodologies which were supposed to be examples of best
practice but which were clearly no such thing. There are a multitude
of different methodologies and practices out there, and how many of
them are actually worth less than the paper they are written on? If
most of the standards that I have been exposed to have been rubbish,
then what percentage of the standards that I have not yet been exposed
to will turn out to be just as much rubbish.

> But Andre is very
> clearly not talking about bad managers. He is talking about those
> practices that seem so obviously intelligent that everyone will do
> them once they are taught them.

Obviously intelligent to who? These managers and project leaders all
thought that their ideas were the best thing since sliced bread, but
they clearly were not. How many of the ideas floating around today are
equally as bad? What I am objecting to is that some people think that
their ideas are absolutely brilliant and they think that everybody
else should follow them without question. Well I *DO* question them
because I think the logic behind them is unsound.

> An example: in PHP it is possible to break encapsulation by directly
> referencing a class variable, rather than getting the value through
> an accessor method.

This “problem” is not limited to PHP as every language ever written
which supports OO has included support for both public and private
variables. If it breaks encapsulation as you suggest, then why does a
methodology which is supposed to support encapsulation provide the
means to break it?

> If you teach people why this is stupid, then only
> the stupid people will continue to do it. Thus, preserving
> encapsulation, even when a language allows it, is cleary a practice of
> such merit that we can without reservation call it a "best practice."

Your description of the problem as “it breaks encapsulation” is a load
of technical mumbo-jumbo that has absolutely nothing to do with the
real facts. The correct definition of the “problem” goes something
like this: If you access a class variable directly instead of through
an accessor method then this *MAY* lead to maintenance problems in the
future if it is decided that the variable requires extra processing
after it has been input or before it is output. By routing all
accesses through a method means that changes need only be made to that
method rather than all those numerous other places where the variable
is accessed.

Note that this MAY lead to a problem, not WILL. Also note that the
potential “problem” is one of simple maintenance and not any sort of
program failure. If all variables were accessed this way then the
potential maintenance problem could be quite large, but if few
variables are accessed this way then the potential problem is greatly
reduced.

I have accessor methods for most of my variables, but there are some
cases where I simply don’t bother because it is not necessary. An
example is where I inject a series of values into an object then
immediately call a method to process them. If I need to change the way
in which these variables are handled all I need to is change the
existing method ? I do not have to go back to any of the code which
injects those variables.

So you see that there MAY be a problem with public variables if they
are used indiscriminately, but there MAY NOT be a problem if they are
used wisely. Just as with the COMPUTE verb which is only inefficient
when used unwisely.

So your statemement that public variables are stupid and should never
be used is just as shortsighted as that project leader who told me
that the COMPUTE verb is inefficient and should never be used.

> Your stories of bad managers are entertaining and perhaps you should
> send them to Robert Glass. Perhaps he'll use them in his next book.
> But you can stop telling such stories in this thread. They are not
> relevant. They have nothing to do with what is under discussion. We
> are discussing best practices and you keep raising worst practices.

But these worst practices were promoted as best practices by their
authors. If they were clearly no such thing, then how much of what is
promoted today as best practice will be eventually consigned to the
rubbish bin?

André Næss

unread,
Sep 12, 2003, 8:35:12 AM9/12/03
to
Tony Marston:

>> But Andre is very
>> clearly not talking about bad managers. He is talking about those
>> practices that seem so obviously intelligent that everyone will do
>> them once they are taught them.
>
> Obviously intelligent to who? These managers and project leaders all
> thought that their ideas were the best thing since sliced bread, but
> they clearly were not. How many of the ideas floating around today are
> equally as bad? What I am objecting to is that some people think that
> their ideas are absolutely brilliant and they think that everybody
> else should follow them without question. Well I *DO* question them
> because I think the logic behind them is unsound.

We have all the time been talking about the community of programmers.
Developers. Techies. Geeks. We who feel like we are artists, trapped in a
world of pin stripe suits. The logic (or rather lack thereof) in the
software industry is of little interest to this discussion. The gap between
programmers and their managers is covered in "The Career Programmer:
Guerilla Tactics for an Imperfect World" by Christopher Duncan. I just
bought it, and I like it so far, and since you brought it up I just wanted
to tell you about it.

The fact that managers are clueless when it comes to technology is news to
none :) And it really isn't what we've been discussing here. The sort of
best practices we have been talking about are those that most developers
nod their head at in recognition, maybe they have already come to the same
conclusion through their own experience, or maybe the truth of the idea
hits them right away.

André Næss


Tony Marston

unread,
Sep 12, 2003, 10:27:27 AM9/12/03
to
André Næss <andrena.spa...@ifi.uio.no> wrote in message news:<bjs76b$7be$1...@maud.ifi.uio.no>...

> Tony Marston:
>
> >> But Andre is very
> >> clearly not talking about bad managers. He is talking about those
> >> practices that seem so obviously intelligent that everyone will do
> >> them once they are taught them.
> >
> > Obviously intelligent to who? These managers and project leaders all
> > thought that their ideas were the best thing since sliced bread, but
> > they clearly were not. How many of the ideas floating around today are
> > equally as bad? What I am objecting to is that some people think that
> > their ideas are absolutely brilliant and they think that everybody
> > else should follow them without question. Well I *DO* question them
> > because I think the logic behind them is unsound.
>
> We have all the time been talking about the community of programmers.
> Developers. Techies. Geeks. We who feel like we are artists, trapped in a
> world of pin stripe suits. The logic (or rather lack thereof) in the
> software industry is of little interest to this discussion. The gap between
> programmers and their managers is covered in "The Career Programmer:
> Guerilla Tactics for an Imperfect World" by Christopher Duncan. I just
> bought it, and I like it so far, and since you brought it up I just wanted
> to tell you about it.
>
> The fact that managers are clueless when it comes to technology is news to
> none :)

But all of these people were senior programmers, project leaders and
such, not just pin-striped geeks from the admin department. As such
they should have been imparting best practices from their own
experience, but what they were actually teaching was very limited and
in most cases nowehere near what should have been considered as best
practice.

Because these technicians were capable of producing crap standards I
am immediately suspicious of everybody else's until I can personally
put them to the test and verify them, and in a lot of cases compare
them with what I have encountered in my own experience.

> And it really isn't what we've been discussing here. The sort of
> best practices we have been talking about are those that most developers
> nod their head at in recognition, maybe they have already come to the same
> conclusion through their own experience, or maybe the truth of the idea
> hits them right away.
>
> André Næss

There is a great deal of difference between best practice when it
comes to avoiding common errors and best practice when it comes to
designing a solution. Provided that a particular design or methodology
produces a workable solution then it is wrong for others to tell me
that I must not design that way or use a methodology that is different
from theirs. I am allowed to use what ever design I see fit and to use
whatever methodology I see fit without some nerd leaning over my
shoulder and say "you must not do it that way". Unless you can point
out a genuine problem with my work then any criticism is unfounded.

I choose to use public variables because the language allows me to,
and because I don't have a problem with them.

I choose to create a class for each database table because the
language allows me to, and they work very well thank you very much.

I choose to have my individual database table classes inherit lots of
standard variables and methods from an abstract database class because
the language allows me to, and because it enables me to have a great
deal of standard code which I can write once and use many times.

All these arguments about what different groups of programmers may
consider to be best practice is a smoke screen. If you can point out
genuine problems with my methodology or my design then I will be in
your debt, but please stop telling me that what I am doing is wrong
because it is different from the way you would do it. My software
works therefore it cannot be wrong.

Tony (go on punk, make my day) Marston
http://www.tonymarston.net/

Gerhard Fiedler

unread,
Sep 12, 2003, 1:37:44 PM9/12/03
to
On 12 Sep 2003 07:27:27 -0700, Tony Marston wrote:

>> The fact that managers are clueless when it comes to technology is news to
>> none :)
>
>But all of these people were senior programmers, project leaders and
>such, not just pin-striped geeks from the admin department. As such
>they should have been imparting best practices from their own
>experience, but what they were actually teaching was very limited and
>in most cases nowehere near what should have been considered as best
>practice.

there is a certain confusion here, it seems to me. i agree with the
one side of the argument that there is a certain, somewhat imprecisely
defined though, set of rules that make up those best practices. it is,
however, not well-defined enough to be a good guideline for any team
(or individual).

therefore a team leader usually has to come up with a certain subset
(or superset) of thore practices, defined enough to make the team work
consistently and understand each other. this set of rules has a
somewhat different objective, and therefore it might diverge from some
commonly accepted best practices -- and definitely often diverges from
individual's preferences -- and still be adequate for the team.

i don't know about the situation around the earlier cited cobol case
with the compute verb. but let's assume that 50% of the team members
were not capable of using that verb reliably, then it might make sense
in the context of that project and that team to set up such a rule.
(might not be the best example, but you get the idea: the rules
necessary for a team are quite different from the rules for an
individual.)


>I choose to use public variables because the language allows me to,
>and because I don't have a problem with them.
>
>I choose to create a class for each database table because the
>language allows me to, and they work very well thank you very much.
>
>I choose to have my individual database table classes inherit lots of
>standard variables and methods from an abstract database class because
>the language allows me to, and because it enables me to have a great
>deal of standard code which I can write once and use many times.

since i put in here some cents of mine, i jut wanted to mention that i
for my part don't have a problem with this design :)

in general i tend to create an abstraction when i add another layer,
which usually would lead to classes that do not 100% reflect the
underlying tables. but then, there are all kinds of situations where
something like what you do makes sense...

in any case, i wouldn't know of a PHP best practice that says that you
shouldn't wrap your tables into classes :))

lawrence

unread,
Sep 15, 2003, 1:33:59 PM9/15/03
to
to...@marston-home.demon.co.uk (Tony Marston) wrote in message news:<7588a50f.03091...@posting.google.com>...> You are bringing up a

>> subject completely unrelated to what Andre was talking about. You
have
>> now written several posts and all of your posts have the same
theme.
>> In all of your posts you talk about bad managers.
>
>You are missing the point. All these managers produced development
>standards and methodologies which were supposed to be examples of
best
>practice but which were clearly no such thing. There are a multitude
>of different methodologies and practices out there, and how many of
>them are actually worth less than the paper they are written on? If
>most of the standards that I have been exposed to have been rubbish,
>then what percentage of the standards that I have not yet been
exposed
>to will turn out to be just as much rubbish.

At this point we're simply repeating ourselves. Your point was that
there are bad managers in this world who promote bad practice and call
it good practice. I understood you the first time you made that point,
as well as the 2nd, 3rd, 4th, and 5th time you made that point. Once
would have been enough.

I pointed out that your point wasn't germane to the discussion because
we weren't talking about what managers do, we were talking about what
the programmers using a language do. If all the programmers using one
language adopt some practice because it seems great then that becomes
a "best practice" for the language. Look around and you'll see dozens
of examples of this everyday. "Don't break encapsulation" is a good
example of a "best practice". As Andre said, these are guidelines, not
hard rules, but everyone using a language usually is admonished to use
the guideline when they can.

As I said before, your examples of bad managers are entertaining, and
I enjoyed reading them, but they are not what we are talking about. We
are talking about those practices that programmers tend to pick up and
imitate. If a company (or, more likely, individual programmer)
develops a practice and it catches on worldwide, and most of the
programmers using that language adopt it as one of the loose rules to
live by, the it can be considered a best practice for that language.
If a company comes up with a rule and the rule does not catch on
worldwide, then the rule is not a best practice for the language.

I've repeated myself in the 3 different posts now, which is perhaps
foolish on my part. I'll let this thread die now.

It is loading more messages.
0 new messages