20
votes

I suppose most of the developers have an idea of multi-layer architecture. We have DAL (Data access layer), we have BLL (business logic layer) and somewhere near the end of the road we have our UI. If you have a project which somehow follows these principles, do you keep (or at least try) to keep/put the things where they conceptually belong? I'm especially interested in big company applications where you work together with many other people. Clearly you can do whatever you want with your private toy project, invent any kind of an architecture and stick to it. It is not so easy with big projects where lots of people contributed to the software or overall mess.

For example, I happened to see things like UI components going directly to the database to fetch some "missing" extra data which BL does not supply, also both UI and BL working with low level elements like table fields where in my opinion they should delegate these operations to the lower level namely DAL. It was especially sad when after discussing the things with the senior developer guy I saw he didn't see a problem with this at all.

We can of course assume me and whoever shares my point of view are just being perfectionists, but I clearly saw a very disadvantegous consequence in that it took me prolonged periods of time in some of my tasks to trace all the "parallel" routes that the data is travelling to and from the database and to identify whoever and in which way may now be affected by the new functionality I implemented. The way I see it, these are increased further development / maintenance costs overweighting some savings when someone decided to quickly hack the stuff and close the task as soon as possible.

Are you projects "pure" or they abandoned the idea of keeping the clear line between layers a long time ago? If you still keeping it right, how do you deal with colleagues who do not understand these things or don't care about them just building "custom" solutions and hacking hacks all the time? Or at some point in time you stopped fighting with the windmill and accepted it as your punishment?

6

6 Answers

19
votes

The more complicated our application gets, the more important separation of concerns becomes.

At 100 klocs, the application was one big blob, as much business code in form classes as anywhere else and calls into form methods from the business classes. With much wailing and gnashing of teeth, we separated out the business logic from the display logic. Any class that needed to notify the user of its progress raised an event that was sunk by the UI. And, for a while, all was right with the world.

Around 200 klocs, we added a data layer. The architecture of our application was such that most of our data was processed as soon as it came in and immediately discarded. Most configuration information was stored in the third-party application with which ours shared a symbiotic relationship. But, settings were starting to accumulate in all sorts of odd corners. We wound up with three configuration management systems, all intricately woven into the business logic. With an extensive rewrite, we were able to separate out the configuration information into its own layer and the handling of streaming data into another layer.

Near the 250 kloc line, we decided to end our relationship with the third-party vendor and make our application stand alone. We began a massive rewrite and, for the first time, added an actual database to our application. Because we had clear lines between streaming information, data storage, and business logic, this was a fairly seamless integration.

Now, approaching 500 klocs, we're moving the application to a grid-based architecture. Not only will the UI be separated from the business logic on a different computer, the actual computation of the quotes and orders that the application sends out will be load balanced and spread out to maximize efficiency. This would be impossible without an n-tier architecture.

At each stage of growth, we were either aided by a clean separation or hindered by our own muddle of communication, data, business, and UI. There probably hasn't been a more important concern than that separation in the creation of this application.

6
votes

That's a great question! Something every ASP.Net developer needs to think about. You will probably get a lot of answers, I'd encourage these basic common-sense ideas.

--Consider simplicity and speed of delivery as a part of a "successful" architecture, not just "purity". Try to balance between holding to architectural ideals, and being practical.

--In general, it seems to make sense to divide the code out into layers as you mention. I would suggest though that for page-specific logic, it could be left in the page if it's simpler/faster--why create generic business objects for code which is just used in one place. As it's been said "Premature optimization is the root of all evil.”.

--Keep the layers and complexity to a minimum to reduce coding time and improve readability and maintainability.

There are many purists on this site who like to do architecture for architecture's site -- use architecture as a tool to deliver a solution to a business problem, not as just an art-form for it's own sake, let it be a useful tool rather than it using you.

2
votes

Keep the concerns seperate. It is very very important. Don't mix UI with Biz and Biz with data layer. Work with abstraction. Working with abstraction also makes the testing (unit testing) easier (Mock them). I strictly keep each layer where it belongs. Remember that the highest cost in any project is it's maintainance. If you mix the concerns then maintainance is gonna become a nightmare.

2
votes

We have a Winforms app, and an ASP.NET app. They both use the same Business Objects project (about 140 classes).

The Winforms project consists of about 350 form and user control classes, and a very few (<10) of these need metadata about themselves from the database.

The ASP.NET project has about 100 .aspx pages.

We have a data access layer consisting of 5 classes, which concern themselves with ADO.NET, threads and transactions. They convert requests from the Business Objects into SQL Server calls.

The UI layers (with the exception of the few classes that need metadata about form sizing) do no database access at all. Even the few exceptions go through the DAL like anything else.

The Business layer knows nothing about the internal workings of the data access layer, and when it needs data, only ever calls public methods on the DAL classes.

I'm not at all a fundamentalist when it comes to this kind of thing, but we've never needed to cut corners on this one.

So in short, 100% pure. It's simply always worked out better to do it right.

We'd have to have a hell of a good reason to move away from this now.

1
votes

Code Monkeys and Purists are a lot like any other extremist in life.

We have extreme right wing and extreme left wing. Very few people are exactly one or the other and they find a good middle ground where they sit. If it wasn't for the extremists we wouldn't know where the boundaries lie.

As far as the way I code goes. I listen to the purists way of doing it. I see the code monkeys going about their methods. I use my experience to choose a middle ground that gives me the right amount of flexibility and manageability along with the time I need to produce it and the amount of money I'm actually going to get for doing it.

1
votes

The bigger the code, the longer the lifetime, the more different people work on the code (both simultaneously or during the lifetime) the more important she separation in layers is. In the beginning, it seems to be a bit more unnecessary work, but in the long run it pays for itself several times over.

As for enforcing the separation: That is why your lead programmer or technical architect needs good soft skills as well as pure technical skills. You can try to enforce the separation technically (see below) but in the end, you need to convince (or coerce) your developers to keep the big picture clean.

But this is not to say that technical means to enforce the separation have no use. In fact, I found that ensuring that "cross border calls" are somewhat difficult to make will make people spend more time thinking about what they really need in the cross-border-interface, leading to cleaner interfaces. It doesn't matter if the difficulty is technical (because you have to use COM or CORBA) or something else (you have to fill out a 7 page form in triplicate).