Re: Critique of Robert C. Martin's "Agile Principles, Patterns, and Practices"



On 2007-01-27 00:39:50 -0600, frebe73@xxxxxxxxx said:

Then I would hide that SQL statement behind an interface so that the
rest of my application was unaware of it.
And the benifits are?

1. Separation of concerns makes both sides more readable.

Do you have something to back this up?

I think it's self evident:

retirableEmployees = findAllEmployeesEligibleForRetirement();
foreach e in retireableEmployees
e.sendLetter(retirementOptions);

========

List<Employee> findAllEmployeesEligibleForRetirement() {
DataRows rows = sql("Select * from employees where DOB>1952 and
salary > 90000 and ...;");
return rowsToEmployees(rows);
}

======

In both cases the code is easier to understand than the following:

DataRows rows = sql("Select * from employees where DOB>1952 and
salary > 90000 and ...;");
List<Employee> employees = rowsToEmployees(rows)
foreach e in employees
e.sendLetter(retirementOptions);

In this latter code some of the intent has been lost. Why ware we sending this particular set of employees the retirement options letter? Are they eligible, pre-eligible, overdue for retirement? What?


2. Both sides can be tested independently of the other.

I don't understand why OO people insits testing their application
without the database.

Because it's faster.
Because we can control the data more easily.
Because the tests can be kept independent (no accumulation of data from one test to the next.)
Because we can run the tests on our local laptops without a database.
Because we can run the tests before we have chosen a database.
Because we can simulate *any* kind of malfunction.
I could go on...

Most business applications are a rather thin
layer babysitting a database. Testing that layer without the database
is rather useless.

That may be true for some tiny little applications. It is certainly not true for small, moderate, or large systems.


3. Either side can be deployed independently of the other (meaning at
differen times) allowing me to fix bugs, or add features, to one side
without redeploying the other.
etc.

Views (and stored procedures) are deployeable indepentently of the
application. But I not sure I understand why deploying different parts
of the application indepently is so very important.

1. I can fix a bug in one component without having to redeploy the whole system.
2. I can sell different components of the system to different customers.
3. I can create different configurations of the system by mixing and matching different components.


There is no need for passing data structures around the application.
Relations are the only needed data structures. (Sometings performance
issues might force you to use low-level collection classes likes arrays
and hastables, but this is normally not the fact for business
applications.) The application should ask the database for the needed
data, using set theory and predicates, when the data is needed, not
before.
I agree with everything you say there.

Ok, so you finally agree that using classes as data structures is a bad
idea?

Isn't "finally" a wonderful word. Isn't it great to be able to throw that word into an argument just to make is seem like you've made a point. Isn't it great that you've finally stopped beating your wife.

Did you clip the part where I said that objects were relations? Yes, I agree that relations are the only needed data structures. I happen to like passing them around as objects. It's so much more convenient than passing them around as table rows, once they've been extracted from the database.

An object is a relation, and it is very convenient to use.

Oh! There it is!


From http://en.wikipedia.org/wiki/Relational_model:
"A relation is defined as a set of n-tuples". Do you claim that "an
object is defined as a set of n-tuples". (Or maybe you claim that an
object is one n-tuple?) How do you apply joins, projections and
selections to objects? Now you are trying to do the same as Lahman:
After realizing that set operations and predicate logic are superior to
the network model, you are trying to hijack the relational model.

I don't do joins on objects (usually). I let the DB handle all that work. And then I load the tuples into a nice convenient object and pass them around to the business rules, and to the user interface, etc.

--
Robert C. Martin (Uncle Bob)  | email: unclebob@xxxxxxxxxxxxxxxx
Object Mentor Inc.            | blog:  www.butunclebob.com
The Agile Transition Experts  | web:   www.objectmentor.com
800-338-6716                  |



.



Relevant Pages

  • Re: deleting row from dataset
    ... For example, if I deleted row 10, would row 11 now be pointing at the old row 12? ... BUT only after a resychronisation, NOT immediatly: If it was to simply delete it, from your side, BEFORE making any synchronization with the database, how would ADO Net be aware of that it has to delete it! ... Furthermore, if ever you re-execute again your loop after a first "delete" pass, BEFORE you resynchronize it with the database, you will likely get an error trying to read a field from a row marked as deleted! ... Sure, standard foreach do not allow standard delete, so, maybe it is more "by design" for uniformity, than for real need. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: deleting row from dataset
    ... For example, if I deleted row 10, would row 11 now be pointing at the old ... No, not even for standard list: when you start at index N, toward 1, so ... with the database, how would ADO Net be aware of that it has to delete it! ... I am clueless about why foreach does not allow the delete, ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: form post to database best practice?
    ... | info from database then using php doto create elements in form. ... text-align: right; ... foreach ... FROM roLaborCodes ...
    (comp.lang.php)
  • Re: dataset row count problem PPC - SQLCE
    ... After rearranging statements several times, I put them in the same sequence as in my other procedures. ... Just after I ExecuteReader, dtr returns a 'true' but once inside the 'if' statement, dtr returns false. ... interact with the database. ... foreach ...
    (microsoft.public.sqlserver.ce)
  • Default Value of field based on another field of same record
    ... Retirement Default value to be set to last day of the month when age is ... of date Batch field above). ... how can I extract the first four digits from the field 'OfficerID' ... I can post the database if required. ...
    (microsoft.public.access.gettingstarted)

Loading