One problem I see with object oriented programming as it's typically used today is that you can't have objects that have "required partners" in different tiers of your system.

In other words, let's say you've got a business logic tier that accesses your data services tier (the rdbms), and you want to hook up to a GUI in the presentation layer/tier. Well, you don't want, in theory, to have to have any one tier to build any of the others, at least not more than a stubbed reference API to build against (at the very least, you want the interdependence to be absolutely minimized before you can feel good about your design). So though the business tier object to presentation tier logic is often going to have a lot of one-to-one and onto patners, there's no mechanism to relate the partners that doesn't, in turn, require that you start building the two layers together. Though in theroy you want to be able to run the business tier on a box that knows nothing about what presentation tier might be accessing it, practically you'd like to give warnings if your system has a particular sort of GUI object without a correndsponding partner in the business tier and vice versa.

If you had this relationship, you could build a "contract-based interface" for your programming staff to build towards. "Do we have the UI for Function X? Check. Do we have business tier logic to pull in intialization values for Function X's UI? Check. Do we have clearly referenced relationships between each data column type between UI and what the business tier is pulling back? Hrm, we've got a compiler warning that we don't, though it'll still build, of course."

You could make your n-tier system three dimensional in structure and pass another layer of interfaces that helped tie that together, but it'd be difficult to do so without killing your compile. I'm just asking for structure to facilitate linkages without demanding them, pointing out where you may have failed in an implicit contract, and have generic code to help back up those holes.