|
Posted by Jerry Stuckle on 04/13/07 13:00
amygdala wrote:
> "Jerry Stuckle" <jstucklex@attglobal.net> schreef in bericht
> news:UbydnbDR174eZYPbnZ2dnUVZ_tOmnZ2d@comcast.com...
>> amygdala wrote:
>>> "Jerry Stuckle" <jstucklex@attglobal.net> schreef in bericht
>>> news:_L2dncAv8ZxOfIPbnZ2dnUVZ_sOknZ2d@comcast.com...
>>>> amygdala wrote:
>>> <snip>
>>>
>>>
>>>> Definitely properties should be private. They're part of the
>>>> implementation.
>>>>
>>>> However, I often have lots of public methods. For instance, I'll have a
>>>> getXXX method to fetch 'xxx'. And I may have a setxxx method to set it,
>>>> if that makes sense - the latter doing validation on the parameter
>>>> passed, if necessary.
>>>>
>>>> So potentially in a table with 25 columns I can have 25 getXXX and 25
>>>> setXXX methods (and 25 private variables, one for each column), database
>>>> related methods, etc. This can easily come out to 60-70 public
>>>> methods - and often I'll have some private ones, also.
>>> Well, this is just exactly what I am trying to avoid. I have (unfinished)
>>> __get and __set methods in the base class DB_Table that should take care
>>> of this in one go.
>>>
>>>> But don't try to put all of your variables in one 'fieldspec' array.
>>>> While it will work, it will also be almost impossible to understand
>>>> later and even worse to maintain.
>>> Hmm, you are no doubt much more experienced in this field, but my
>>> gutfeeling says I have to disagree on this one. The whole point of
>>> creating this framework for me is to avoid the cumbersome task of
>>> creating getter and setter functions for each and every table field. Thus
>>> I'm declaring one generic fieldSpecs array that provides properties for
>>> the fields so that the generic getters and setters as well as the generic
>>> Validator will take care of the rest. I don't see the fieldSpecs array
>>> becoming to difficult to understand quickly for me in the future.
>>>
>>> Still, this leaves me wondering: why doesn't a child class just simply
>>> inherite the 'getFieldSpecs' function and let self::$fieldSpecs refer to
>>> the $fieldSpecs in the child class? Should this not be the basics of OOP?
>>> What am I missing here? Or better yet: how can this be achieved?
>>>
>>> Thanks for your time people. Much appreciated!
>> OK, now how are you going to validate the entry? For instance - if you
>> have a date field, ensure they put a date in there? Or an integer?
>
> Well, I would use a generic Validator class for that. Something along the
> lines of:
>
> class Validator
> {
> public function validateField( $fieldName, $fieldValue, $fieldSpecs )
> {
> switch( $fieldSpec [ 'type' ] )
> {
> case 'boolean':
> // validate boolean
> break;
> case 'string':
> if( isset( $fieldSpec[ 'subtype' ] ) )
> {
> switch( $fieldSpec[ 'subtype' ] )
> {
> case 'email':
> // validate email
> break;
> case 'url':
> // validate url
> break
> etc.. etc...
> }
> }
> case 'int':
> etc.. etc...
>
And as you add more types and subtypes, this gets longer and longer.
And slower and slower. And harder to maintain and more subject to errors.
>
> For dates I _would_ probably use a custom setter which would convert three
> form elements (dd, mm, yyyy) to a unix timestamp (I like those better then
> SQL dates) first, but then I would validate its outcome with the generic
> Validator also. I could even have some minimal and maximal date values in
> $fieldSpecs to check that the date doesn't exceed a certain time span.
>
And you'll have to add more custom validators plus hooks for them.
> For integers I would define some minimal and maximal values in the
> $fieldSpecs, and check it directly in the generic Validator. Use is_numeric
> and the likes.
>
And what about cases where you need non-consecutive numbers? Such as
those from the set (1, 2, 3, 5, 8, 13, 21...)? Another custom validator...
>> Classes also need to be responsible for their own variables. There should
>> be no way you can ever set an invalid value in any member.
>
> Of course, I agree with you totally. But I don't see how my approach would
> lead to this happening. I would validate each entry just like you do. But
> with a generic __set instead of custom setters.
>
The generic will be much larger, much slower and much harder to maintain.
>> So you might as well get used to writing the set and get functions. They
>> go pretty quickly (unless you have some extensive validation), and in the
>> long run it's a much better way to go.
>
> Maybe you're right. I might be stubborn here. ;-) And off course, I have
> thought of the fact that exceptional situations _will_ occur. Probably more
> often then I'm thinking off right now. But then that leads me to the
> somewhat black and white conclusion stated under your following opinions:
>
Yes, it's easy to get one idea in your mind as the best way and stick to
it too long. You need to be flexible. Even after 40 years of
programming I sometimes have to change my approach because someone shows
me a better way.
>> I've been doing OO programming for almost 20 years now, and yes, I've seen
>> your way before. It ends up being cumbersome and highly prone to errors.
>> It also creates a maintenance nightmare. You *really* don't want to go
>> that route.
>>
>
> I see where you are coming from Jerry, but this point of view then almost
> leads me to believe that there is no point in creating DB table objects
> whatsoever. Cause then it pretty much comes down to the same old 'linear'
> routines again. What then, in your opinion, is the surplus value of creating
> DB table classes?
>
>
I create db objects all the time. But they have get and set functions
for each field (at least the appropriate ones). They are quite handy
for a number of purposes - the biggest one being abstracting the
database access. But then that's their major purpose.
For instance - one I'm on right now. I have a site coded in VBScript
using Access. I want to change it to PHP and MySQL. However, for
various reasons this needs to be done in stages. The Access database
has over 30 tables, ranging from 2 columns to over 40 columns per table.
We're (others are involved - it's a big site) creating DB objects to
interface the Access tables. These will handle the actual SQL calls and
isolates the program from the database being used (or even flat files,
if necessary).
Next we'll creating business objects - these objects translate between
the program and the database objects, and convert what's in the tables
to a format the rest of the program needs. This isolates the rest of
the code from the database table design (i.e. if we need to change one
or more tables, this and the db objects are all that will need changing).
We'll then convert sections of the site at a time. Once we get a
section converted, we'll bring it online.
When we're done and can change from the Access database to MySQL, we'll
change the Database layer and move the data. If at the same time we
need to change some of the table design, this will be handled between
the database and business object layers. But any changes will be
isolated to those layers.
Note the business object layer isn't always needed. But due to the
complexity of the site and how many tables are interrelated, we decided
it would be better to use them here.
These are the benefits of database objects (and OO in general).
But I would hate to use your fieldspec idea in this case. It would
make things much harder to troubleshoot, and we'd end up with a lot of
specialized validators. The result would rapidly become unmanageable.
So we're putting in the set and get functions for several hundred table
columns. Additionally, we're doing a similar number on the business
object end. And depending on the data, it may be validated in either level.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
Navigation:
[Reply to this message]
|