Fog Creek Software
Discussion Board




Academics vs. Engineers

I want to share a frustration I experience with other developers and see if it's a greater problem or is just my twisted take.

The way I see it, there are two fundamentally different types of classes:

A.  Those meant to be reused (common libraries, APIs, etc.)
B.  "Internal" classes, such as implementing a particular UI dialog, passing data around within a single class, etc.  Most classes written fall into this category.

My issue comes when developers use "A" coding standards, when they're really writing "B" code.  Some instances of this:

- Long lists of getters and setters for member variables that perform only basic gets/sets.
- Overgeneralization.  A "one off" class has an inheritance hierarchy.
- Templates (generics).  Mostly, app code should consume templates, not expose them.
- Sophisticated exception handling.  Does an exception (let alone a custom exception) really need to be thrown when someone forgets to enter a date in a dialog?
- Creating multiple, very short source files for tightly coupled processes.
- Using COM when static linking is sufficient.
- Gracefully handling "fatal" errors (out of memory, heap corruption, handle creation failure)
- Gracefully handling internal logic errors (developer passes in a null reference, etc.)
- Overuse of "data <--> object" classes when DataTables or Recordsets would suffice.

Granted, ALL of these are "good practice".  What I find frustrating is the 5 field dialog that ends up as a 600 line source file or the one-time query that someone maps to a custom object.  This costs money in both the coding and maintenance phases and doesn't make the product any better.

I tend to see this more with younger developers who want to do it "the right way".  I have empathy for their goal, but not the end result.  It's a difficult point to argue, though, as they can back up their way as "proper coding practice".  The pessamistic truth is that their classes aren't going to reused.  Reuse needs to be dictated by the project manager in order to happen effectively.

Does this frustrate anyone else?  If not, why not?  If so, how do you deal with it?

Bill Carlson
Tuesday, October 28, 2003

The XP folks have a great name for this: YAGNI, or You Ain't Gonna Need It.

To be blunt, I think it often comes with experience. When I was starting out, the people I learned from were "smarter than the average bear" programmers: they were interested in particular techniques or tricks, and when to use them. Cynically, I think that they sometimes did this to maintain a feeling of being on top, by "knowing more".

It took me a while to learn to be simple and straightforward, and I think it was *after* I'd mastered any number of APIs. I'd "been there, done that", so I didn't have anything to prove.

In short, while I think Best Practices are to keep things simple, I can't completely blame young pups who just wanna have at it and gain some chops. After all, that's the way I was.

Portabella
Tuesday, October 28, 2003

Except for the "gracefully handling" part of the argument, I fully agree.

I'd say: "always code defensively".  It adds some bloat, but I've never been disappointed by the extra time spent handling errors and exceptions properly.

nat ersoz
Tuesday, October 28, 2003

" Overuse of "data <--> object" classes when DataTables or Recordsets would suffice."

This is the only one I have to strongly disagree with you on!!!!

If you are not using your own classes which represent business objects you are NOT programming OOP. Using recordsets right in the UI = hack programmer......

GenX'er
Tuesday, October 28, 2003

I worked in one organization (one which I'll always savour as the "house of bad examples") where such a cargo-cult mentality was absolutely rampant - a long litany of marginally useful (or actually detrimental), often labour intensive, practices that simply did not fit within the maturity of the project and the stage of the development. There was an almost religious adoration and adoption of anything that any old documentation writer (who often are individuals who's soul creation has been said documentation, and have never been involved in actual projects) deep in some orifice of Microsoft pronounced as the One True Way. A quick and example would be "CRUD" - a golden rule for database interaction that harkens back to the days of dbase. Generally the most complex and step-intensive processes was adopted as The Word, and there was a seeming sense of accomplishment and pride in the level of processing complexity derived from the most trivial of operations. Words like "scalability" were used to justify vast component models that in actuality absolutely devastated performance (humorously making said "horizontal scalability" absolutely mandatory for basic functioning at the outset).

This is not to say that there isn't a place for highly componentized and generalized development, and the whole slew of processes, however when you're developing an internal R&D prototype that is changing at a rate of 80% or more per month and is largely conceptual, such a process is a _waste_of_time_ - the entire inheritence model is a house of cards that makes implementation presumptions that will likely dramatically change, rendering all of that work irrelevant, and costing time (and reducing quality) while trying to shoehorn the new model onto it.

Dennis Forbes
Tuesday, October 28, 2003

I would agree with most of what Bill says especially now that I am mainly using higher level languages (VB or C#).  I quite often create internal classes with public data members knowing full well that if I need more ecapsulation I can promote this data member to be have a getter and setter methods.  Most times I do not need them. 

Unfortunately alot of my peers disagree with this.  My last formal code review did not go that well, I think about half of the senior programmers got it, perhaps a third of the juniors and none of the project managers.  (Yes there are far too many people in these meetings, no we never agree on anything but that another topic).

Where I disagree with Bill is in the 'graceful handling' comments.  I still assert all of the input parameters and the state of the class for all methods.  I still add as much error handling for graceful exits as possible.  I have found that both of these save me time in the long run -- the first allows me to find some logic errors while I am still debugging, the latter allows testers to give me more information to find my logic errors.

Billy Boy
Tuesday, October 28, 2003

Nat and Billy Boy,

I think that asserts are a graceful way to handle "errors that cannot happen".  I use an assert macro that logs a message to a file reporting the source code and line number of the assert.  This is graceful and defensive programming.

XYZZY
Tuesday, October 28, 2003

xyzzy,

Agreed, for errors which should not or cannot happen, assert is perfect.

nat ersoz
Tuesday, October 28, 2003

> If you are not using your own classes which represent business objects you are NOT programming OOP.

In general, I agree with you... but if you've ever dealt with a horrible internal database layer that someone added "because they were sure we would need it", you might appreciate the other point of view.

Put it this way: if code is simple, clear and easy to change, then whether or not "it's a hack" is a lot less important.

Portabella
Tuesday, October 28, 2003

"If you are not using your own classes which represent business objects you are NOT programming OOP. Using recordsets right in the UI = hack programmer......"

What an absolutely ridiculous and naive statement - without knowing the context you are proving yourself such a cargo-cultist proclaiming such a purportedly always applicable rules (I would say the same about anyone who proclaimed that all abstraction objects are bad) -- topping it off with that classic "those who do other than the One True Way are hacks!".

Dennis Forbes
Tuesday, October 28, 2003

I humbly apologize for sounding dogmatic.

When exactly does a DataTable or Recordset  suffice over a business object?

GenX'er
Tuesday, October 28, 2003

This is an intersting topic you've started. Let me speak for myself about the vices I have. In general I wouldn't be  so religious about the detail if I were only writing a class but when I am designing a component, however small, I  do sit a day or two just to plan with pencil and paper.

>- Long lists of getters and setters for member variables that perform only basic gets/sets.>
I must confess I still do this as a matter of habit.

>- Overgeneralization.  A "one off" class has an inheritance hierarchy.<
On the contrary, until I was raw, I never knew nothing about Design Patterns and never for that matter could  envisage object heirarchies and thier need. With experience, this is one thing that has been creating more  space for itself in my code, but only where needed, a very to-the-point architecture. No extra flab.

>- Templates (generics).  Mostly, app code should consume templates, not expose them.<
I never did a template when I was writing commercial code that had to be sold. I restricted my templates for  R&D.

>- Sophisticated exception handling.  Does an exception (let alone a custom exception) really need to be thrown  when someone forgets to enter a date in a dialog?<
I hate exceptions and I'll just stop at that.

>- Creating multiple, very short source files for tightly coupled processes.<
My code usually has the following modules almost always:
API.bas
Main.bas
Global.bas

Apart from these, I mostly have classes and they are just as lean or stout as the proportion of the onus of  functionality that they pregnate themselves with in relation to the whole project. So I am not in favour of  innumerous lean modules but I won't consciously refrain from having them if they were meant to be needed. If I  had to read from the Registry, and from INI files and also do some string parsing and make a connection to the  Internet, I'd have four classes, very lean and lanky with only the necessary interface points and as much code the  FPs require. The Internet class may just be 12 lines long (without counting the myriad of API declare statements  of course)

>- Using COM when static linking is sufficient.<
Makes the two of us. I always bind static unless I am implementing interface inheritence. I wonder how much  speed matters in between a COM GetObject (CoGetClassObject) call and using the New keyword. And there  will be a bunch of guys who'd just want to make their code as esoteric as possible and will use the Automation  interfaces even for instantiating the Dictionary object in FSO. I hate thier fascism in that. I like your way, our way,  simple and straight-forward static binding.

>- Gracefully handling "fatal" errors (out of memory, heap corruption, handle creation failure)<
I woudn't bother unless I was using two versions of the same API, for instance one to support a Long as a direct  pointer and the other to pass the StrPtr of a BSTR. Or if I was passing a far pointer into an Any datatype and I  still wanted to preserve it as a string for another routine.

>- Gracefully handling internal logic errors (developer passes in a null reference, etc.)<
As a matter of habit, I love to close recordsets, then destroy them by setting them to nothing. VB doesn't  complain but I as a matter of habit just end up doing the finalization and decrementing reference counts even if it  means a few extra lines at the bottom. If I don't find them, I feel my feet off the ground.

>- Overuse of "data <--> object" classes when DataTables or Recordsets would suffice.<
Never. No use of extra work for free. But I remember doing something similar when I was just begining. When I  was a newbie, I had no one I could look up to as a mentor so I started the hard way - experimenting and  pretending I was Rob Thayer when I read VB6 Unleashed and began writing COM components.

One thing you missed out is documenting code. I loved writing comments when I was just starting. I always  protested in favour of strong verbiage in the commented code to those who didn't do it at all. But now, slowly I am  begining to hate it. I just write no comments at all. Code, I believe, is supposed to be read. And especially with  the language that I am working with, Visual Basic, its so English like and I try to make my code look English-like  too leaving out the need for them.

For eg. one of my routines would look like this:

Public Sub FileNew()
   
Dim IntReply As Integer
    If ChangesMadeToContent Then
        IntReply = UserRequiresSaveChanges
        If IntReply = vbYes Then
            If FileUntitled Then
                Call FileSaveAs
            Else
                Call FileSave
            End If
        ElseIf IntReply = vbCancel Then
            Exit Sub
        End If
    End If

End Sub


Public Function UserRequiresSaveChanges() As VbMsgBoxResult
   
Dim StrFileName As String
Dim IntReply As Integer
   
    StrFileName = ExtractFileNameFromMDICaption
   
    IntReply = MsgBox("The contents of the file " & StrFileName & " have changed. Would you like " & _
    "to save the changes you've made to the file?", vbYesNoCancel Or vbQuestion, App.Title)
   
    UserRequiresSaveChanges = IntReply
   
End Function


Public Sub FileSaveAs()

Dim IntReply As Integer

If IsCanvasBlank Then
    MsgBox App.Title & " cannot save a blank Workflow Design Area." _
    , vbCritical, App.Title
    Exit Sub
End If
   
    frmSaveFile.Show vbModal
     
End Sub


Public Sub SetCaptionNewFile()

  MDI.Caption = App.Title & STRING_APPLICATION_TITLE_FILE_NAME_SEPERATOR & _
  STRING_FILE_NAME_PREFIX & CStr(GetLastFileID + 1)

End Sub


I also try making the functions very lean and bare where each one of them will do just one and only one simple  thing. When I started off, I had this habit of writing functions that wound so badly around each other where one  function called another which called another and there were a dozen or so of them on the call stack. I had this  ambition of breaking up into functions but didn't quite know how to go about and so I wound it round and round  like the pretzel. Gradually things got clearer and the thought process evolved. And now each function is like "one"  single task. I will usually write the story for one big functional unit and follow a top-down approach and granularize  after having written the english-like sentences.

Still there are some in my office, especially some moronic guys who shouldn't have been programmers at all,  who write oodles of green grass all over the place, especially when they are not required. When they are most  required, they leave it because chances are that they do not understand it themselves. If you read the code  around here for those guys, it'll mostly have huge green boxes with the pedigree (:)) on each of those morons  and then it'll have lines like

Unload Me    'Now unloading form

and you'll laugh your ass out reading it. When I have nothing better to do, and if I've tired myself out from reading  the web, I turn into these lines of code and read their stereotyped comments.

By and large, I don't do all the routine for small ones, but when its the turn to design a component which must  have a dozen or so classes, I do plan elaborately and go to the extent needed, but the object heirarchy even then  will be very succinct and to-the-point. I won't do it just for the heck of it.

Sathyaish Chakravarthy
Tuesday, October 28, 2003

When is a business object preferrable over a DataTable / XML document for read-only "object" communications?

Dennis Forbes
Tuesday, October 28, 2003

I completely disagree with most of the points here. When you will loose your $1.000.000 customer because somebody in your organization is too lazy to write 600 lines of code for a 5 field dialog you will have second thoughts.

I am at the opposite end in my company: nobody wants to write the code to handle errors, for instance, because they know better exceptions aren’t ever being thrown in their code. Guess what: exceptions do happen, and an unhandled exception in a VB event handler for instance means immediate application shutdown. Do this few times and you end up writing code for fun in your parent’s basement.

There is no such thing as waste of time as long as your customer pays for and expects well-written code.

19th floor
Tuesday, October 28, 2003

"When is a business object preferrable over a DataTable / XML document for read-only "object" communications?"

To Me? Always!

GenX'er
Tuesday, October 28, 2003

> because somebody in your organization is too lazy to write 600 lines of code for a 5 field dialog you will have second thoughts.

I think the opposite point of view -- and one that I've frequently seen in practice -- is that someone writes 600 lines of code where 5, or maybe 50, would have done.

Because it's longer, you have more errors, and thus you still lose your zillion dollar customer.

I think it's really a change in focus: engineers are (rightly!) scared of the guy who writes 5 lines instead of 600 because he's *lazy*. But at a certain level you write 50 lines that you're absolutely sure of, instead of 600 lines that probably mostly work.

Portabella
Tuesday, October 28, 2003

I thought of 3 reasons:

1. Encapsulation
2. Inheritance
3. Polymorphism

Ever hear of them?

GenX'er
Tuesday, October 28, 2003

"When you will loose your $1.000.000 customer because somebody in your organization is too lazy to write 600 lines of code for a 5 field dialog you will have second thoughts."

In software there is a direct correlation between an increased line count and increased maintenance costs, reduced agility, and increased bug count. This isn't a 100% correlation, but if vendor A made a 10 line solution that can be totally remodelled in minutes and each line has been thoroughly vetted, and vendor B provides a 3000 line solution replete with false negative error checks, a highly componentized system that has an overhead so great that I require far more hardware, and for which a basic business shift requires a seismic rebuilding of the "generalized" class model, then I'll take vendor A thanks.

Dennis Forbes
Tuesday, October 28, 2003

> What an absolutely ridiculous and naive statement

Yes, in the sense that it's not 100% true.

But no, in that *most* of the time putting database objects in the UI is an Utter Hack.

Put it this way: it may be a hack or it may be Genius -- but, if you had to guess, which way would you bet?

Portabella
Tuesday, October 28, 2003

"Guess what: exceptions do happen, and an unhandled exception in a VB event handler for instance means immediate application shutdown."

Not to say that exception handling does not have a place, but tt is better to detect some types of errors and exit immediately than to pretend that you can handle the error gracefully.  Many errors are not recoverable, and it you try to continue you will just make a bigger mess.

XYZZY
Tuesday, October 28, 2003

"1. Encapsulation"

A recordset or XML document is a method of state communication. It is naturally encapsulated from the mechanism that populated it.

"2. Inheritance"

Feel free to add more elements/fields....

3. Polymorphism

...and the receiver can easliy adapt to different levels of state information.

Functional objects (stateful objects -- which rather hilarious are dissuaded nowadays in lieu of stateless objects) have value. Objects which are nothing more than read-only state repositories are of limited value in some cases, and are almost always a very large resource overhead.

Dennis Forbes
Tuesday, October 28, 2003

Dennis, seems like your upset because you've seen a bad implementation of data objects, complex class hierarchies, custom exceptions, and other professional programming practices, but it looks bad when you slam them.  I agree wholeheartedly with GenXer, with the possible exception of the DataObjects vs. DataTables.  I use data objects in j2ee, but sometimes its just really easy to use datatables in asp.net.  Which way is better? DataObjects.  In the long run, you'll get more code-reuse, encapsulation, and numerous other benifits.  Don't assume just cause one way takes a little more time to do, and takes a little more brainpower to think about, that its the "wrong way to do it".

Vince
Tuesday, October 28, 2003


Much of the "graceful" stuff is not really that hard to add to code as you are writing it. Often, the approach with the extra error checking code is to "add it later" (which is usually never done).

I've found that having this code early can make finding problems much easier in the early stages of development and later in production.

It's a hell of a lot nicer to get "memory allocation failed in file(line)" than to get a core dump.

njkayaker
Tuesday, October 28, 2003

1. Encapsulation

Ok, I'll humor you. In your design, where is the
getDatafromXML method? Normally I would have it in a Business Object. Please don't say right in the UI!!!!!!

GenX'er
Tuesday, October 28, 2003

"Dennis, seems like your upset because you've seen a bad implementation of data objects, complex class hierarchies, custom exceptions, and other professional programming practices, but it looks bad when you slam them"

Don't polarize my position (or claim emotion where there is none), and stating that it "looks bad when I slam them" strikes me as absurd (interestingly I said nothing about custom exceptions. I enjoy exceptions, though I can appreciate that there is a place where they aren't appropriate).

"Professional programming" is the act of evaluating all of the factors involved and making an educated, logical, and justifiable decision for that scenario. Unfortunately, to many (who shouldn't be in this industry) there is one single answer to all questions - if these people were home builders then every house would be a steel cube 40' x 40' x 40'.

Dennis Forbes
Tuesday, October 28, 2003

>I thought of 3 reasons:
>1. Encapsulation
>2. Inheritance
>3. Polymorphism
>Ever hear of them?

I've heard of all three of them in school (Academics).  In the real world I use encapsulation most of the time, inheritance and polymorphism when they are useful.

Are you trying to imply that the code for a dialog needs inherit from anything other than a class library or be polymorphic in any significant way? 

Most dialogs I create talk to a data class -- this may be an xml dom document, it may be a dataset/datatable and it may be a full blown object. 

In the dom doc and dataset cases, the UI usually has a 1:1 mapping of UI fields to data fields and have very few business rules. 

In the full blown object case there are many business rules. 

To say one is more correct is utterly stupid and limiting.  There are cases that easily support both.  Professional programmers should be able to recognize which case they are in.

Billy Boy
Tuesday, October 28, 2003

"One thing you missed out is documenting code. I loved writing comments when I was just starting. I always  protested in favour of strong verbiage in the commented code to those who didn't do it at all. But now, slowly I am  begining to hate it. I just write no comments at all. Code, I believe, is supposed to be read. And especially with  the language that I am working with, Visual Basic, its so English like and I try to make my code look English-like  too leaving out the need for them."

You should try a package that provides for self-documenting comments. In VB check out Document!VB, or try out XML comments in C#.

IMHO the issue about comments/documentation isn't so much "what does this piece of code do" as "where can I find the code that does [x]" - that's where self-documenting comments come in *really* handy.

And if you're doing contracting work, customers always appreciate a pretty package. :)

Philo

Philo
Tuesday, October 28, 2003

"You should try a package that provides for self-documenting comments."

I'll definitely second that. It is brilliant when you can run your code through a doc generator for the team to look at a HTMLHelp or WinHelp doc to see the api points and object model (and both are automatically in sync - There is no divergence as the documentation isn't upkept). Of course this applies at the object/function level, and not line by line "how to program" sort of documentation.

Dennis Forbes
Tuesday, October 28, 2003

Question is: Where do you populate your DataSet or XMLDOM object????

If you do it in the UI you break OOP.

If the DBA changes the name of the field, then you need to update the code that loads the DataSet & the code that fills your UI (List Box, Combo, etc etc).

If you use a business object to handle it - you only need to change the code in one place - the code that accesses the DB. The other code references the business objects' properties can stay the same.

GenX'er
Tuesday, October 28, 2003

Addressing specific points:

GenX'er:  Since when is OOP "always good" and non-OOP "always bad"?  A primary OOP goal is safety.  If you're the only consumer of your class, who cares?  It's your option whether to validate and restrict in the caller or the callee.  You shouldn't necessarily send a class to do a struct's job.

Error handling:  My point is that the effort expended to do error handling should be proportionate to the error's severity, recoverability, and likelyhood of occurance.  When you've worked with a certain type of app (web, client-server, mass-deployed windows) for a while, you know what's likely and what's just-not-gonna-happen.  Sure, someone could've pulled out their hard drive between OpenFile and ReadData, but is this worth the risk of false positives?  Quality is a relative term.  Most developers are not writing "void LaunchTheMissiles()".

Data access layers:  My experience has been that these tend to be either A. transparent and useless bloat or B. horribly obfuscated.  I freely admit this is a personal bias.  I have no problem putting raw SELECT statements in server side, or even client side code, where appropriate.  Sure, when the schema changes, you're in for some work.  But how often has a DAL _really_ helped here?  The idea that your DB people and your client-developers are loosely coupled seems a bit far fetched.  Sure, I'd like to be able to change schema and not have reprocussions.  Not going to happen in either case.

One ratio I like to look at is the percentage of LOC that actually "do stuff" (error handling counts).  If I'm wading through thousands of lines of wrappers, getters/setters, SPROCS that wrap a single, infrequently used SELECT, I question whether people just have too much time on their hands...

Bill Carlson
Tuesday, October 28, 2003

"If the DBA changes the name of the field, then you need to update the code that loads the DataSet & the code that fills your UI (List Box, Combo, etc etc)."

The dataset signature or XML schema is the contract - if the DBA changes the name of the field, the dataset population process (which could be a database view, a stored proc, or a data object) aliases the field - No one is saying that said static information is a 1:1 mapping with the underlying data. One piece of code is changed, just as in the situation where you've abstracted it through a business object.

Dennis Forbes
Tuesday, October 28, 2003

>You should try a package that provides for self-documenting comments. In VB check out Document!VB, or try out XML comments in C#.<

I think I did try that add-in DocumentVB or some VBDoc I guess, but correct me if I am wrong, it does require you to set a description in the Procedure Properties dialog. And also to fill in the remarks section.

Sathyaish Chakravarthy
Tuesday, October 28, 2003

What if you're not using XML?

GenX'er
Tuesday, October 28, 2003

And you're right about the adornment before the bride leaves for the client's. Almost a statutory requirement.

Sathyaish Chakravarthy
Tuesday, October 28, 2003

>>Question is: Where do you populate your DataSet or XMLDOM object????

The data is generally passed into the UI.  It is usually retrieved by a business object. 


>>If the DBA changes the name of the field, then you need to update the code that loads the DataSet & the code that fills your UI (List Box, Combo, etc etc).

I'm sorry, did you just graduate?  In the real world any DBA that made changes like that would be strung up by his nuts by the developers.  DBAs do our bidding, not the other way around.  BTW once you get ship version 1, its very impractical to change a schema even if it is completely necessary. 

Billy Boy
Tuesday, October 28, 2003

To answer GenX'er again:  We give each field in our database a unique name with a prefix indicating the table.  If a field changes, we do a search and replace in our main project directory (which contains client projects, server projects, schema information, and DB scripts).  If your DBA goes around changing field names without regard to code or reports, I feel for you.

SQL views and triggers are an easy way to achieve some amount of data encapsulation.  Don't throw more at a problem than it needs.

Bill Carlson
Tuesday, October 28, 2003

Ok, before I  answer, Bill, are you saying that the previously mentioned "pattern" is appropriate for most web applications, or that its just an "acceptable" business hack when having to do stuff really quick. 

Vince
Tuesday, October 28, 2003

To each his own.

You guys continue to program in a way that works for you. I prefer to program in an OOP way and take advantage of business objects which I can apply OOP techniques too.

I retract what I said before that you are hacks. You are professionals who choose to do things a different way. All the more power to you.

GenX'er
Tuesday, October 28, 2003

"DBAs do our bidding, not the other way around"

First of all I did not just graduate. Mid level (8 yrs exp) :-)

Second, the DBA's may do your bidding where you work, but at a lot of companies the DBA's set the policy and standards and the development groups do their bidding.......

Not sure why you guys are against simple business objects? Doesn't take long to code at all. Pretty simple....

{UI} {Business Objects} {Data Objects} {Data Sources}

GenX'er
Tuesday, October 28, 2003

> I retract what I said before that you are hacks. You are professionals who choose to do things a different way. All the more power to you.

Well, damn, that's the first time I ever heard *that* on this board!

If you can say stuff like that, and maybe even mean it, I'd say you have a bright future ahead of ya. :)

Portabella
Tuesday, October 28, 2003

>>Second, the DBA's may do your bidding where you work, but at a lot of companies the DBA's set the policy and standards and the development groups do their bidding.......


Then I feel for you.  Having an external person screwing up your work/schedule/etc and then expecting you to fix it is not fun. 

Perhaps its this DBA-centric environment that causes you to develop in your style.

Billy Boy
Tuesday, October 28, 2003

Bill, have you ever considered that you may have to work with other companies databases, that other applications are using the same database, and that you don't have control?  When things get complex like that, sometimes it helps to have a little more flexibility.

Vince
Tuesday, October 28, 2003

I think you are correct!!! Not only do I have to deal with evil DBA Groups (2 of them Oaacle & DB2) - but we also integrate with a lot of other systems that have their own dev teams and sometimes admins:

Specifically: DB2, Oracle, CICS COBOL Mainframe Programs, XML Returned from Web Services, Excel Files, Access MDB Files & LDAP.

For me it's easier to model my architecture to have business objects that call other DataClasses which then go get  the data from where they need to. Then I work with the various business objects and update the UI from there.

GenX'er
Tuesday, October 28, 2003

I can't find the reference, but I recently looked at a presentation by a microsoftie who used the term "recovering oopaholics". I think I followed a link from this site yesterday. (ok cut and pasted a link)

Sounds like some of them here, and not all are recovering yet.

Ah, found it: http://www.microsoft.com/seminar/shared/asp/view.asp?url=/seminar/en/20031022CLRPerf/manifest.xml&rate=2

pdq
Tuesday, October 28, 2003

Bill, I agree with your point.

I think there is indeed a certain orthodoxy among new graduates that's inconsistent with good design and good software.

I think this arises because lecturers often lack development experience - as opposed to programming experience.

It also occurs because this industry has no concept of experience being valuable. Thus, new methods are held to be superior jsut because they're new and the teachers would like them to be superior.

.
Tuesday, October 28, 2003

I think new graduates tend to over-engineer because colleges teach architecture and case studies of large-scale systems, not how to create a dialog box (which is what 90 percent of their job is going to be -- sorry, kid).

Ron
Tuesday, October 28, 2003

To answer Vince:  I see these practices as completely acceptable in production applications.  Of course, different situations will require different approaches.

My company makes vertical market financial management software.  Several hundred million dollars in billings each year flow through our product.  I feel confident in saying to my developers "here's an open database connection, don't screw anything up".

What makes this possible?  Most of our developers have been developing fault-tolerant financial software for 20 years (no, really).  All developers have been with the company for at least 3 years.  If I had a bunch of inexperienced hacks, I would insist that a senior developer wrap the database.  If we had inexperienced hacks, though, the point would be moot as we wouldn't exist as a company.

If we have a schema change, we talk about it and talk about reprocussions.  Granted, our schema is pretty small, about 40 tables and 700 fields, but the system works.

With regard to integrating databases from multiple vendors, don't underestimate the power of doing validation on the SQL side.  You can provide an API of sorts with triggers and views.  It's not always a question of anarchy vs. formal middleware wrappers.

We're fortunate to have been doing this long enough to know where problems really do crop up, rather than having to theorize.

Bill Carlson
Tuesday, October 28, 2003

Bill, I'm not insulting your intelligence, or your team's competence, and I apologize if I even suggested that.  OO and encapsulation though (and strictly adhering to it), makes my life a LOT easier.  In our application, we have over 300 "front end" files.  If we had database calls throughout them, i'd kill myself debugging database issues.  We have one file that encapsulates all of our database logic, so its very easy to find problems, nad reuse code. (insetad of typing out a long sql statement with 10 joins, we call DBManager.getFullUserList() ) .  Now, it will be even better when we split up the really large file into reader/writers for each section.    What if your application gets to big for SQL Server, and we want to use to oracle?  Piece of cake to switch over.  If we want one of our data objects to use XML/SOAP from another company, instead of from out database?  Easy, no problem.    All these things are just meant to make things simpler when life gets complicated.

Vince
Tuesday, October 28, 2003

Many of the practices we're debating here are "defensive", which begs the question of who you're defending against.  It can be:

1. Incompetant internal programmers
2. Evil internal programmers
3. Incompetant/evil programmers in partnering companies
4. Incompetant/evil deployment environments
5. Incompetant/evil end users
6. Competant hackers

This thread is basically debating how much effort goes into protecting against 1, 2, and 3.

These may well be important considerations with your project.  But say they weren't.  Say your programmers are quality and you have a handful of SPROCS for your partners to call.  Why spend the effort and LOC on issues that don't exist?  Why not add strings together on the client to produce a SELECT statement?

Sometimes effort spent on defensive programming is better spent on remedying 1, 2, and 3 rather than taking them as a given.

Instead of micromanaging permissions, hire people who won't write code to update "your" table without asking you first.  Again, not applicable everywhere, but generally true...

Bill Carlson
Tuesday, October 28, 2003

I've found defensive programming is mostly to protect you from future changes... e.g. everything TODAY is guaranteed to derive from CBase so why bother checking the dynamic_cast, but who knows three years from now?

Ron
Tuesday, October 28, 2003

There is a number of factors that will also effect the choice of using OO for application development. For example, much talk here has been of a 3 teir development approach.

One could start another whole debate on the issues of 3 tier Vs 2 tier.

It is interesting, but I had a ms-access application get bogged down in the development process until I started using class objects. My goal was not so much as to divide the user interface with the application, but only to take something that was getting far too complex for my comfort zone.  When I started moving some of the application into objects, then development rate got better.  For me, much of the use of objects was simply to deal with the number of variables and values for a given task. The application in question was medium size, and had 53 tables (quite nicely normalized I might add), and 160 forms, and 69 reports.

The whole application can be zipped onto a floppy disk! (Yup, I do love that VB p-code!).

You can read my notes and thoughts as to WHEN TO use a object in access, but I can’t say the answer is ALWAYS! Often, one is NOT served by using objects at all!

Much can depend on the ENVIRONMENT one is developing under.

That article:
http://www.attcanada.net/%7ekallal.msn/Articles/WhyClass.html

Albert D. Kallal
Edmonton, Alberta Canada
kallal@msn.com
http://www.attcanada.net/~kallal.msn

Albert D. Kallal
Tuesday, October 28, 2003

Ron is right.  Your protecting yourself against future changes,  and to *scale*.  To say you only need OO if you have incompetant programmers on the team is a joke.  Ebay just switched to an N-tier, MVC type framework using J2EE.  Why don't you go tell them that if they just hired competeant programmers, they wouldn't have to use a data access layer, Entity objects, and the like.  People didn't invent 3 and N-tier for fun, they did it for a reason. 

Vince
Tuesday, October 28, 2003

"Ebay just switched to an N-tier, MVC type framework using J2EE."

Might be a good time to short EBAY, methinks.

rz
Tuesday, October 28, 2003

"People didn't invent 3 and N-tier for fun, they did it for a reason."

Of course they did. By that same token, people didn't invent nuclear power for fun, either, but that doesn't mean that if I want to power my walkman I have to figure out how to build a nuclear power plant into it. I am not saying either monolithic, client-server, or n-tier is either the battery or the nuclear power plant, but rather that the existence of one doesn't preclude the applicable use of the other.

Using ebay as a sample is highly unreasonable, regardless. Could everyone developing ebay please put your hands up? Not many hands. Could everyone developing something that could be served with gusto to hundreds of intranet clients on a simple 2-way box with half decent efficient programming? Yeah, that's most of you.

Dennis Forbes
Tuesday, October 28, 2003

You can't just sprinkle magical OO dust on a product and make it better.

Ultimately software quality comes from a set of pragmatic decisions about what to use and not to use. Sometimes OO is the way to go, sometimes it isn't.

So what if EBAY wrote their application one way? That was a decision made by their engineering team to meet the needs of their specific product. A decision based on hundreds of factors that us armchair critics don't know about, as well as the ones we do.

The only way to determine the right way that gets the best possible results for the least possible resources. Any developer who doesn't weigh that up before starting the product, but rather charges in based on their preconceptions of what is the "one true way" is doing the project a great disservice.

People saying that such and such is "best practice" or some other meaningless term irk me. What they're doing is wrapping up "I do it this way and I'm sticking to it" into a statement that attempts to sound like an objective truth. Sorry, it's not, it's just your bias showing.

Sum Dum Gai
Tuesday, October 28, 2003

I truly hope ebay didn't switch to an N-Tier, J2EE system.

The fact that they own 99% of the online auction market WITHOUT using such a system is a good case study as to why such system architectures are rarely necessary.

rz
Tuesday, October 28, 2003

Thanks, Albert for chiming in on this.  Your presence legitimizes any thread.

The 2 vs. 3 tier debate is interesting.  Our approach has been, for lack of a better description, 2.5 tiers.  This was arrived at by analysing the kinds of calls we would be making over the wire and dividing these into:

1.  Calls that do a simple read or write of a DataTable or Recordset.
2.  "Chunky" calls that minimize round-trips or do complex processing.

The majority of instances were #1 for us.  We added two stateless server methods:

public DataTable Query(string sqlString);
public DataTable Update(DataTable changes);  // returns accepted & rejected rows, error information, etc.  Succeeds or fails as a unit.

Most dialogs and grids could represent themselves as a pair of Query/Update statements, with the query string constructed on the client.

More sophisticated client processes had dedicated server methods for their needs.  Anything that required two result sets would be a dedicated server method to minimize round-trips.

In our case, it works pretty well, as many dialogs have no need for anything other than Query/Update.  The code is straightforward and localized to one client source file.

Our company doesn't specialize development to much of an extent.  All developers are expected to know SQL, how and when to call and write a SPROC, how to program Windows Client apps, how to avoid screwing up server code.  We have non-critical path specialties, such as database modelling, domain knowledge, performance, UI standards, etc., but every developer touches all 3 tiers.

It may not be the "correct" way to do it, but the productivity per man-hour is amazing.  We seldom have one developer waiting on another or he said / she said type situations...

Bill Carlson
Tuesday, October 28, 2003

I agree with the sentiment that the approach of having generalists with some specialist knowledge is superior to having specialists with some generalist knowledge.

In my experience, the best approach is usually to have everyone do a bit of everything, but have each person have a primary focus on one area. This has the advantages that everyone gets to know the code and project inside out, as well as not compromising the design integrity of any area by having it being just a mish mosh of everyone on the project.

Sum Dum Gai
Tuesday, October 28, 2003

*  Recent Topics

*  Fog Creek Home