• Anonymous (unregistered) in reply to Chris Lively

    If you suck as a developer, this is what n-tiered development and business logic layer appears to be all about. Everything described in this article that is "wrong" with a business logic layer are stupid things that developers that suck would do. Of course they are wrong! But it's not because they followed a paradigm; it is because they interpreted it too literally, likely due to their lack of experience.

    Compare the alternative in the given examples: static pages with probably a ton of server side includes. Embedded DB query strings that you have to "search and replace" when you find out your Access back-end database can't scale or your customer really wants Oracle instead of SQL. Good luck keeping your job if that is the way you roll.

    captcha: stinky

  • (cs) in reply to xboob

    Copy and paste is usually a bad thing. I hope you're exaggerating when you say you'd rather copy and paste 100 pages than have one that has a big switch in it. Of course, if you really need 100 different things to happen, you should probably step back and rethink what's going on. And learn the difference between "then" and "than."

    (If you're a non-native speaker of English, you're otherwise doing damn well, I have to say.)

  • (cs) in reply to poochner
    poochner:
    And learn the difference between "then" and "than."
    Don't forget principal versus principle. But we knew what he meant, didn't we.
  • (cs)

    Wait. You get specs???

  • eyrieowl (unregistered)

    there's some valid complaints buried in a load of rubbish in this article. c'mon, now, relying on text-search tools to guarantee your "even-more-licate" business logic all gets updated when the requirements change? maybe...MAYBE if a single developer developed all the duplicated business logic up front, a search tool might find all the instances of that same logic when it needs changing. but if you have multiple developers implementing that same logic all over the place, some better than others, in different languages (javascript, java/c#, sql, etc), almost certainly with different spellings and variations, how in the world do you realistically expect to manage that with text search tools? thank god you don't design standards for any of the systems i interact with....

  • will (unregistered) in reply to zompist

    Not duplicating logic leads to horrid experiences for the user. There is no reason the average user should have to hit a submit button then wait for a response from a server to tell them that what they entered needed to be a number not a character. A system that does not provide a real-time validation,excluding a requirment not to, and then does not verify the entry at the server level(will ignore the database doing checks) is just asking for problems and is just plain user unfriendly.
    While having to go around and make changes at all the levels because a field changed from 5 to 10 characters is pain it does provide a better experience for the user.

  • sf (unregistered) in reply to IceFreak2000
    IceFreak2000:
    Sorry Alex, this article is complete rubbish. I've worked on enough large scale application development to know that not only is a Business Logic Layer a nicety, in a large number of cases its practically a requirement.

    And as for 'Persistance Plague' - bollocks. Use a persistance engine like Hibernate/NHibernate, but take your time and design your database properly - preferably with a good DBA in tow.

    A well designed system should never, ever, have "no choice but to duplicate, triplicate, or even-more-licate business logic". If you even have to duplicate business logic, you should be asking yourself where you've gone wrong.

    I agree. A few good points are made, but there are so many thing wrong with this article I don't know where to start. Although the examples given in the article are true examples of WTF'ery, they should not be viewed as indictments of the good practice of separating and encapsulating domain, presentation, and persistence concerns. Ignoring proper layering when developing one-off applications for small to mid-sized companies may not pose that big of a problem, but this approach won’t scale in a large enterprise environment with numerous applications interacting with a sophisticated business domain.

  • barf indeedy (unregistered) in reply to zompist
    zompist:
    If I found a large application that followed Alex's advice to "duplicate, triplicate, or even-more-licate business logic", I'd submit it to the WTF.

    Ha, sounds like this legacy VB global-madness application I'm working on...

  • MAV (unregistered)

    sniffle it was like the voices of a thousand angels just sang a song of redemption at my front doorstep.

  • Jess Sightler (unregistered) in reply to will
    Not duplicating logic leads to horrid experiences for the user. There is no reason the average user should have to hit a submit button then wait for a response from a server to tell them that what they entered needed to be a number not a character. A system that does not provide a real-time validation,excluding a requirment not to, and then does not verify the entry at the server level(will ignore the database doing checks) is just asking for problems and is just plain user unfriendly. While having to go around and make changes at all the levels because a field changed from 5 to 10 characters is pain it does provide a better experience for the user.

    Yes, implementation of the validation should obviously be duplicated on the client. But a smart framework will do a lot of this for you.

    Ie, implement the validation on the server and have it generate javscript form validation automatically.

    There are off-the-shelf frameworks that do this pretty well.

  • tamosius (unregistered)

    hmm.. am I not getting something, or you haven't read article? What I understood (knew) were:

    • do not over architect (over complicate) solutions
    • business layer is a wrong term

    simple as that, right Alex? ;-)

  • I can has clue? (unregistered)

    Excellent article.

    My personal pet peeve are people who think database constraints such as column names, type constraints, foreign key constraints, etc. are NOT business logic. WTF?

    I always tell them, if the DB doesn't contain business logic, then why can't I just point our app to a different app's DB and still have it work? You know, like swapping a class implementation.

    I guess they think that business logic is procedural code. Business logic can be declarative too!

    That's another pet peeve: so much in IT is just made-up words with fuzzy meaning. It's like, you know how doctors or engineers "dumb things down" when talking to laypeople? Well, these IT professionals talk that way TO EACH OTHER too. Yeesh.

  • Beau "Porpus" Wilkinson (unregistered)

    Will you marry me?

  • Developer (unregistered)

    Last time I checked (3 years ago) the "do not over-engineer" principle was explicitly set out in Extreme programming. So there is nothing new here.

    Still there is obviously a benefit. Principle duplication does a good job of educating people who just scratch the surface, because they have no free time for in-depth digging (perhaps, busy with over-engineering or have too many kids to support).

  • hd (unregistered) in reply to gabba
    gabba:
    It's "we software developers". Not "us software developers". The rest of the story was OK I guess.

    Good lord, get a life.

  • Zygo (unregistered) in reply to Andrew
    Andrew:
    Each language is different. Java throws SQLException objects. C reads a global SQLSTATE variable.

    You say that like there was only one C implementation.

    Maybe somewhere in the ANSI standard there is a definition of such a variable for an ancient, evil, preprocessor-based embedded SQL language.

    In my experience, though, every RDBMS access library, as well as every ODBC-like layer on top of such a library, including ODBC-like generic data access layers built out of other ODBC-like generic data access layers, puts its SQL error state in a different place, even if these libraries are all written for the same language.

  • JOHN (unregistered) in reply to IceFreak2000
    IceFreak2000:
    Sorry Alex, this article is complete rubbish. I've worked on enough large scale application development to know that not only is a Business Logic Layer a nicety, in a large number of cases its practically a requirement.

    And as for 'Persistance Plague' - bollocks. Use a persistance engine like Hibernate/NHibernate, but take your time and design your database properly - preferably with a good DBA in tow.

    A well designed system should never, ever, have "no choice but to duplicate, triplicate, or even-more-licate business logic". If you even have to duplicate business logic, you should be asking yourself where you've gone wrong.

    I agree completely. My company right now has an amazingly flexible BLL which allows us to have a turnaround time of mere hours for any of our hundreds of customers.

    The love it, we love it. We're raking in cash like there's no tomorrow.

    Don't write an article bashing a concept just because you're not good enough to figure out how to make it work.

  • Corporate Cog (unregistered) in reply to xboob
    xboob:
    When you write your systems it should solve the problem directly. I would rather create (copy paste) 100 pages then make 1 big page with a stupid swiss army knife switch/select statement.

    I would rather work on a project that has 100 pages that are basically all the same then a project that has 1 page that does 100 different things. Sure those 100 pages might look stupid when you first create the system , but after some time the system will grow and those pages will look very different.

    I agree with alex. Duplication is a good thing when it solves the problem directly.

    Coders should really try to reduce the amount of code they write. Usually that means you make one page/form and then use it as a template for all the others. So what if their is duplicate code in each form to validate the account number. You most likely copy pasted it anyway and there is a find a replace feature every editor since the stone age. Furthermore, what happens if the logic for one form should be a bit different? You will have to write another validation script anyway or modify the existing one to do something that is only used in one place. Case exceptions are not good in programs. They are the sign of a bad programer that doesn't know how to keep his logic simple.

    Many of the comments here bring to mind Martin Fowler's quote in his book Refactoring: "by eliminating duplicates, you ensure that the code says everything once and only once, which is the essence of good design."

  • JOHN (unregistered) in reply to Dividius
    Dividius:
    IceFreak2000:
    A well designed system should never, ever, have "no choice but to duplicate, triplicate, or even-more-licate business logic". If you even have to duplicate business logic, you should be asking yourself where you've gone wrong.
    So... how do you address the issue Alex raised re: the order number? Does your well-designed application just use varchar(50) for the column definition and blindly pass in any user input to realted BLL methods? Or does it define char(7) not null, and do server+client-side validation of the data entry?

    capthca: craaazy

    Validation is a mathematically simple operation. In our analysis of software, we've determined that over 80% of all validation is simply requiring a field to be filled in, or be a certain length.

    As such, it is incredibly easy to put together a code factory that relies on given rules defined in the database which automatically generates javascript code for the client tier, and C# code for the business tier.

    No duplication needed. Want to change a business rule? Pop into the database, change a field, voila, done in 10 seconds.

  • Fedaykin (unregistered) in reply to JOHN

    See:

    Ruby on Rails Grails Some other Java frameworks

    Most new frameworks will generate validation code directly from database constraints and/or from annotations on data objects.

  • 8===> O-X (unregistered)

    8===> O-X

  • AdT (unregistered) in reply to gabba

    There are ridiculous extremes but to me it seems these extremes derive from a lack of understanding (or odd understanding) of what separation of concerns is good for. Separation of concerns decreases coupling and thus improves maintainability. If you've ever had to fix a bug that was copy&pasted into 60 different source files, or ever had to change the type of a member variable (or remove it entirely) that 29 other classes access directly, you know what I mean.

    Another important advantage of separation of concerns is re-usability. I had once written a file utility that used a textual user interface (similar to curses) and one day I decided to make a GUI version of it. Because I hadn't spent any effort separating presentation and logic (or processing if it makes you happy, Alex), I failed spectacularly despite intense efforts. At one point I decided that a complete rewrite would be easier, but I never got around to that, so ultimately there was no GUI version .

    The problem is that re-use can be misunderstood as "every component of your application has to be designed to be usable in another application, too" - you could call it the Kantian approach. This will inevitably lead to confusing and outright bad software. Instead, the goal should be to separate the parts that can be re-used cleanly from the parts that you probably will not be able to re-use anyway. The generic components should not depend in any way on the specialized components, but the converse is permissible and to some degree inevitable. (This means it is still a good idea to make the specialized component depend only on the generic component's well-defined interface, and not its implementation.)

    When it comes to the three-tier application design, which I consider invaluable, the goal should be to separate the code into:

    1. General persistence code, example: ADO.NET, NHibernate etc.
    2. General business logic code, example: undo/redo manager
    3. General UI code, example: WinForms and custom but generic widgets
    4. Specialized persistence code, example: database abstraction layer for a specific database layout (most likely application-specific)
    5. Specialized business logic code, example: bank account processing
    6. Specialized UI code, example: Forms and views for a certain application

    As you can see, some of the examples include code that's part of the .NET framework (and similar components are found in almost any application development environment) or existing add-on libraries. This is intentional, and it is intended to show that unless you have something generally useful to add to these layers, you do not need to write components of this category, you can just use what's already available.

    Incidentally, among other things, I am developing a web interface for administrating certain HTTP-based server software, and about two weeks ago I decided to separate business logic and HTML presentation from one of the dynamic pages into two different modules, one which does the "processing" and one which generates an XML document and transforms it to HTML using an XSLT stylesheet (the module I had previously hacked together just printed HTML code while doing the processing). A week later, my boss asked me to provide an XML web service for this functionality. If presentation and business logic were still in the same module, I would have to separate them now because I need to use the same logic for two different interfaces (one which is HTML-based and one which is XML-based). Moreover, since I am now using XML with a stylesheet to display the result, I can simply make the web service return the same XML document without applying the stylesheet. This will make it easy to parse in the remote component that will be using the web service.

    While in this case, layering was more of an afterthought, I think there's a certain limit to the complexity of any one component beyond which post facto layer separation requires more work than rewriting the whole thing to use separation of concerns from the start, and of course the rewrite gets more expensive too. So while you can sometimes afford to have components that span more than one layer and separate them only when needed, if you miss the opportunity to refactor the code before it grows out of hand, the component can become an impediment to project growth, maintainability and extensibility.

    As a final note (I promise!), you seem to be confusing "business logic" with "application-specific". These are orthogonal concepts. A parser for a certain language, for instance, would be a business logic component, but not necessarily application-specific (in fact, if it's well-designed, it will be application-neutral). On the other hand, a preferences dialog would be an application-specific presentation layer component.

  • (cs)

    So the WTF is that a web site owner thinks he is the world expert of software design?

  • Anonymous (unregistered) in reply to nwbrown
    nwbrown:
    So the WTF is that a web site owner thinks he is the world expert of software design?

    I think that pretty much sums it up.

    Now I have to wonder if the URLs on this site really go through some sort of re-write engine or if all these pages really are static .aspx pages.

  • Farmie (unregistered) in reply to nwbrown
    nwbrown:
    So the WTF is that a web site owner thinks he is the world expert of software design?
    Lots of people think they're the world expert of software design, but it's not until they come up with idiotic ideas and proclaim them as genius that it becomes a WTF.

    But seriously, I totally agree with you Alex. In fact, I have an idea for your next article. You need to dispel the myth of this useless "Object Oriented" junk. I mean, we waste all our time creating and managing objects when we should just get down to business and write the code, plain and simple!

  • John not John (unregistered)

    Annonymous: Now I have to wonder if the URLs on this site really go through some sort of re-write engine or if all these pages really are static .aspx pages.

    No, but most of the comments are.

  • (cs) in reply to FredSaw
    FredSaw:
    poochner:
    And learn the difference between "then" and "than."
    Don't forget principal versus principle. But we knew what he meant, didn't we.

    Yes, I did, and that one doesn't make my skin crawl like then/than does so I don't notice it nearly as often when it's there.

    back to the topic ... So how do we create a central business rule to validate this? Some horrible regex WTFery that looks for comparatives and either then or than shortly afterwards? Who wants to sign up for that one?

    Don't everyone raise their hands at the same time ...

  • JarFil (unregistered)

    Great article... and some amazing comments. Not all of them the good kind of amazing, though.

    Some people seem to get mixed up about two terms:

    • specification
    • implementation

    While any kind of duplication at specification level would prove catastrophic when trying to make any changes, duplication at implementation level is a MUST for both a good user experience and a well secured application (aka: good software). That leads to a third element: tests, which are the correct way to join a specification with no duplication, to an implementation with more or less duplication. Any time specification logic changes, all tests should fail. Any time some implementation logic changes, it's test should tell you if it complies with specifications. It's as simple as that.

    All this talk about having a "good" framework -or whatever- in order to get rid of logic duplication at the implementation level, for some kind of "big enterprise applications"... it just gives me the creeps.

    Of course, if your "specification" is actually your implementation, you may be in bigger trouble already. That is, unless your project is some kind of free software with more developers than you actually need (think: linux).

  • (cs) in reply to gabba
    gabba:
    It's "we software developers". Not "us software developers". The rest of the story was OK I guess.
    We software developers, we happy software developers, we band of brethren....
  • Jeb (unregistered)

    Lay off the crack pipe grandpa and get on with the funnies.

  • Abraxis (unregistered)

    As "Enterprise IT architect" (WTF job-title ;-)) I found this somehow little misleading. For me BLL is layer of code between DB (persistence layer) and presentation layer (typically some web framework with simple validation rules for fields like "email", "int x; 0 < x < 10" etc.).

    OF COURSE that DB and pres.l. has business logic - but what I mean by BLL is "everything else" - "grey-validation-logic" (e.g. inter-screen), service orchestration (on submit of this form call this web-service and according to the result display this or this form) etc. The whole idea is, that DB should contain ONLY data-related BL (in ideal world only table constrains with no triggers) and pres.l. ONLY field-validation-BL.

    By using this 3-layer approach you can prevent having complex BL in javascript validation rules or DB stored procedurs - which is sometimes maybe easier to develop, but nightmare to maintain and extend.

    But as all in IT - it's about people and how work...

  • Zygo (unregistered)

    There's lots of stuff that annoys me when people who try to create abstract models of real world systems.

    The definitions of the layers are relative. All systems that grow eventually grow to the point where they all have all three layers within them. For example, an RDBMS has a persistence layer (this writes data on disks in a way that survives crashes and power failures), a presentation layer (this allows you to cast a timestamp to a string and catenate it with other text), and a business logic layer (this implements things like foreign key constraints on tables). Just to make life interesting, most of the time the business logic layer is programmable by end-users (an RDBMS's end-users are DBA's and software developers). As soon as you're writing a web application, all of the RDBMS's layers instantly compress into something some people call "the persistence layer," and some people refuse to use the other two thirds of the RDBMS's capabilities even at the expense of maintainability or performance.

    The real practical problem with business logic is that it wants to run all over the place, and those places speak different languages. You can build a three-tier application that does all input validation at the database--it'll work, but the user will often be stuck with little error feedback beyond "an error occurred." To get a text field length limit constraint on a web-based order form, you may need to express the constraint in SQL, C++, and Javascript simultaneously; however, you often don't want to literally do this as it raises the system's maintenance costs by a factor of three (and increases the probability of a bug by 0.3% per line of code that you do this with, if you have the industry average 1:1000 bug:line-of-code ratio).

    Of course, programming in the small is different from the large. A 1000-line application is so easy to maintain and debug that it's probably OK to mix the layers so thoroughly that you'd need a centrifuge to separate them again. Your application will probably have one or two bugs, so you just fix them and you're done. For large programs life is not so easy.

    One tempting solution to this problem is to force the constraint code to actually live in one of the three layers (which aren't really "layers" so much as just where the physical barriers between the system components happen to be). That leads to things like security holes from Javascript forms implementing the one and only data validation in a system, or awful performance because the only part of the system that can do validation is the database, or awful interoperability because all interactions with anything have to be forced through a middle-tier C++ library (which implies you have to support a C++ runtime in your code, which might or might not be easy to do) that contains the validation code. It's a really bad idea to do this--each layer is good at doing some things and not doing others (if that wasn't true, you wouldn't bother with the hassle of having the layer in the first place), so it's an obviously bad idea to pick one of the layers and force it to do everything.

    Another more practical solution to this problem is to create a compiler for a fourth language that generates code in the other three, or write an interpreter for a fourth language that runs in the other three. When amateurs attempt this, you get one or more WTF postings (usually because it's the first time the amateurs have tried to wrap their heads around the rigors of writing compilers or interpreters, not because it's a bad idea in general). When professionals do this, you get enterprise software development tools (although sometimes you also get a WTF posting anyway).

    Regardless of the quality of its implementation, by following this approach you end up with a fourth programming language, and you were probably going insane from having to manage three languages before, so it doesn't sound like a very good idea. Actually, it really isn't a good idea, unless you can refactor your project so it is mostly coded in the fourth language except for well-defined, stable libraries of code in the other three. Frankly, if you are actually capable of successfully achieving this, then you might as well get out of whatever business you are in, remove all the "business logic" from your code, and start selling it to people as an enterprise software development toolkit--everyone else, just buy it from those who succeeded in building it.

    Alex's "solution" of simply coding the business logic everywhere and anywhere it touches program control flow is akin to programming all your applications in assembly language because the only C++ compilers you've ever seen are a bunch of students' CS467 projects (and not from the students who passed the course, mind you).

    Now, there's nothing wrong with assembly language per se, but it's not for everyone or for every project. There are lots of programming tools available which, although not as flexible as assembly language, do provide increased developer productivity through automation. Every higher-specialization language that does this removes some generality from the lower-specialization language that it was implemented in, and constrains developers somewhat--but it also frees them from having to cope with some of the implementation issues that are irrelevant to specialized problem domains. Taken to the extreme, we would expect every problem domain to end up with its own programming language--and to some extent this is what happens. Just look at the number of large, mature applications in the field that have some kind of scripting automation in them.

    At the moment many developers only have access to tools for "business" applications that are akin to assemblers or LISP/FORTH interpreters. It's no wonder they think there's no better way, because they've either seen nothing better, or seen only early failed attempts at doing better. The privileged few who actually do have something better either developed it themselves for interal use, or they are using an enterprise toolkit that most developers have never heard of.

  • Fred M. (unregistered) in reply to T604

    I second that.

  • wake (unregistered) in reply to xboob

    Oh no. Copy-paste programming. Sure, sometimes you can't get out other way, esp. in hurry, but with decent time and budget it soon pays off to refactory and reduce/eliminate duplicities. WhY? Changing thing at multiple places increases (geometrically) the risk of forgetting one occurence or changing the same thing differently on different places. Consequences apply too. Today, with all the ORMs, smart widget libraries, opensource (so you can hack the tool if it doesn't fit and the blame is positively on the tool) there's no reason for hand-coding. Or, better, hand-coding more then once. Just my two eurocents...

  • Abraxis (unregistered)

    I think that's the point - just use technology the way it's meant to be.

    Just because it's possible to write your complete project as PL/SQL functions, it doesn't mean that it's really good idea ;-) And believe me - we got few of these projects in our company (not so small bank) and maintaining those is really pain in the ass, I mean in the wallet ;-)

  • (cs)

    "Layers" and "Tiers" are an extension of people that understand Seperation of Concerns trying to explain to newbies how to design their applications.

    You end up with two types of WTFs in "Enterprise App" design:

    1. The newbies that follow golden rules but not understanding why (and the rules can sometimes be incorrect or unsuitable for the situation).
    2. The Great Masters of Theoretical Architecture (that dont realise that while in theory it might be nice for the software to cope with the sun going supernova, it probably doesnt matter).

    In fact you can pretty much tell these people by:

    1. They use the Microsoft Data Access Block, because its from the Enterprise Library - however the only function they ever call is .ExecuteDataSet(...), sometimes putting the results in a hacked up "Business Object".
    2. They use some ORM tool* thats more difficult to use that the space shuttle... but its THEORETICALLY IDEAL.

    I'm not enjoying my current contract, 2 months maintaining a category 1 system. Specific instructions not to change any of their "best" practices. Oh, and for those that recall - I am back at the contract which has a "Kleptography" library - written by a self professed "Klepto" expert who has implemented a bloody Turning Grille^ cipher to protect critical business data. Hilariously I found some of my RSA based shit "refactored" to use the "Enhanced Klepto" library :(

    • This doesnt include the good ones like Diamond Binding which I have used and loved in the past... mainly because they keep their Goddamn Shit out of the other parts of my application and just let me get to my data in plain objects in a sane fashion, without me having to a) write any code and b) have my app crapped up with codegen.

    ^ A cipher which is basically used to teach noobs cryto visually - and is considered weak as fuck.

  • mustapha (unregistered)

    This article fails because it makes n-tier design the issue, and not the cargo cultists littering the world with stupid un-tiered systems. I've worked on innumerable 'enterprise' applications where the tools in charge have created a supposed n-tier system but which was in reality a god awful mashing together of different strains of shit. I've also worked on some good systems. The problem is the idiots, not the principle.

    Making the design the focus over the idiocy has negative implications for the authors competence and experience.

  • Muddy Mudskipper (unregistered)

    Wow. This site just dropped about 20 points in my mind. "Complete rubbish" sums it up nicely.

    There's a pattern for this recommendation, and it's very common -- The Big Ball of Mud http://www.laputan.org/mud/

  • (cs) in reply to Bob
    Bob:
    And perhaps a little investigation into things like constraints, triggers, and using the proper data types might help with all that duplicate logic you think is necessary...

    How are those concepts going to implement javascript code to provide client-side validation?

    Client side validation isn't required (as the back end should have the final say as to whether something is valid), but it sure does make for a much more usable UI. This means duplication of logic...

  • Jon Gilkison (unregistered)

    This is brilliant on so many different levels. Death by design patterns.

    The ERE article was brilliant too.

  • Anon (unregistered)

    I can understand where the author is coming from. However, I use a domain model and service layer for every project now -- I don't think I could ever go back. No matter what the size of the application, I find it a ridiculously easy way to quickly evolve an application that I know can scale and will be robust indefinitely.

    http://martinfowler.com/bliki/AnemicDomainModel.html

    No, my domain model isn't anemic, but it's close since I usually can't be bothered with data transfer objects as well as business objects. Regardless of where you decide to balance your business logic, the key is that you have a service layer. This becomes the API for your application, defining the set of operations any external concern can use. Nothing touches your database directly, nothing is done to your system without going through the interface your team has designed. This includes your primary interface, whether it's a web site, windows forms, or mobile device, and any external applications integrating with yours.

    http://martinfowler.com/eaaCatalog/serviceLayer.html

    This doesn't preclude having business logic in the UI. It's virtually essential for a user friendly UI to know that a field is required and must be five characters long before the user hits the submit button. However that logic needs to exist in the service layer or domain model as well, for a number of reasons...

    o When there's 15 pages that use that part of your domain model and service layer, but only 14 check that particular field has been provided and is five characters long. An exception is still thrown, albeit not as nicely as it could have been. o When another concern wants to talk to your application, the rule isn't forgotten simply because the original UI isn't involved. o When your interface is thrown away, redesigned, or completely new sections are tacked on, you can be assured that no business logic is lost and that no matter how roughly the new interface is done, the application will still continue to work perfectly. (Well the UI might not work perfectly, but no data is getting lost or corrupted.)

    Once you have frameworks in place to support this kind of design, which ideally use some of the fantastic tools out there like NHibernate to run your persistence, there's virtually nothing to do except write your business logic once and then get to work on your UI. You can copy some of the business logic into the UI later to get rid of some of those unfriendly service layer exceptions, but the important thing is that a rough version is up and working quickly, ready for the user to fiddle with and start providing feedback on, without compromising what I consider to be essential enterprise application features right from the start.

    The OP might cry, "Aha! See I told you! No single layer can hold all the business logic." I guess I would have to agree. The domain model and service layer do share the business logic between them, and the UI will duplicate some of the business logic. My point would be to never rely on the business logic in the UI. It's there for user friendliness only, not to protect the application.

    One last thing I'd like to say... Why use an OODB or something that tries to make a RDBMS into an OODB? There are fantastic tools out there that map a domain model to a RDBMS perfectly well. Searching for all A objects with B property like 'C' when the objects are stored as blobs just makes me shiver.

  • Ata (unregistered) in reply to Anonymous coward
    1. Article is there for people to read and comment, otherwise why the comment section.

    2. If you agree on some point, doesn't mean you agree on all other points too.

  • spikeless (unregistered)

    Dear god Alex, what a poorly informed, out of touch article.

    The primary reason for a domain layer is ease of maintenance.

    How on earth do you maintain or debug an application with business logic scattered throughout the solution? If you have to make a change to one business rule how do you know when you have changed every instance? Duplicate code is a code smell, triplicate is an outright stench.

    The open source community has embraced persistence engines in Hibernate/NHibernate and many others. Microsoft has also embraced this paradigm in their Entity Framework. Either they are wrong or you are. I know where I am putting my money. Some persistence engines are better than others but none that I have seen will encourage you to store all business objects serialized in a single table and most recommend using other retrieval methods for reporting. In my opinion most actually encourage better database design by pushing the design to match the actual data being stored.

    It's poor programmers with this attitude which keep the good programmers in business - cleaning up other peoples unmaintainable crap. I dearly hope I never encounter any of yours.

  • (cs)

    The whole thing about blobs in database records and OODB's/Persistence, is that its basically an unsolveable problem.

    There is no way to deal with transmission (be it over a network or to and from a database) of an object except via serialization. You can try splitting the object into fields and writing 'translator' methods that move the object class to and from a relational form - and you will go insane.

    However, there are times where even with OO schemes you really do need the advantages that relational DB's bring - indexing for one thing!

    There is no path except compromise in this particular minefield, you have to decide which fields are going to be broken out and made fields in the record, and which are to remain purely part of the class.

    One design goal that helps is to try and make sure that the only place the two meet up again is in memory - but then you also have to serialize the 'external' fields when you transmit the object over a network, that's one of the gotchas.

    One interesting approach is to use a relational database as a 'viewer' into a persistent OO system, but again it depends on things, eg. is it essential to have covered ALL cases (eg. when making an airline booking) or just SUFFICIENT cases (eg. when finding storage bins with space).

    Veery interesting area, many papers written and no doubt many wrists slashed over this. %^]

  • Andrew (unregistered)

    As an infrastructure architect I see what Alex is talking about all the time. My simple rule is that nothing but validation and display should be processed at the presentation (client) level. All else should either be database contraints, stored-procedures (although I'm not keen on these unless there is a damned good performance reason) or in a "middle-tier" which ideally should (or be able to) be on a separate server to the database.

    The key driving point behind this attitude is that then you can pretty much deploy an application to anyone in any place without much effort (aside from security). Bandwidth is still expensive over the long haul.

    CAPTCHA: onomatopoeia . Bang!

  • MichaelR (unregistered) in reply to Fedaykin
    Fedaykin:
    Finally, the controller is the heart of the program, and does contain most of the business logic. In essence, it is the puppeteer, and the model and view are the puppets. It handles control flow, validates input from the view, directs the view on what to display (though in some cases the model will directly control this), and directs the operation of the model. It also handles errors from the view or model, and most of the other nitty gritty details.

    With MVC, the controller handles the lion's share of the business logic, but there is no attempt to handle all of it.

    (Thanks for the article Alex....)

    I don't agree with you, Fedaykin. Here's the way I think about the Business Layer:

    1. If you wanted to move a (well-written) fat client application with basic file storage to a web application with database, the business logic is the part that you can reuse without_modification.
    2. The business logic probably doesn't depend on any frameworks (except collections or maybe a rule engine).
    3. The business logic is the part of the application that a businessman would be able to explain how it works.
    4. The "Model" in MVC is the core of the business logic, but usually also includes persistence logic. When fetching data from the persistance layer, the result (in a proper OO implementation)

    I agree that the Controller contains some elements of business logic, but the difference is that the Controller does not "understand" what the business objects mean, and how they relate to each other. For example, it has no logic to determine when a customer might be a gold or platinum customer. If it somehow receives that information from the View, it should pass it directly on to the Model. If it then needs to make som controller-type decision based on whether the customer is platinum, then it should ask the Model for that information. (because the model might specify that e.g. email confirmation needs to take place before a customer is really a platinum customer.

    The problem is that most frameworks nowadays are VC frameworks - it is up to you to build the M, and to keep it seperate from both V and C (and persistance). Many frameworks we use today make it hard to do MVC separation, without a lot of extra effort.

    It's easier to think about for, say, a mathematical graphing app with no persistance. Calculating what the wavy graph will look like is the model. Calculating where the lines will go on the screen is of course the View. What the buttons do to the Model and the View is Controller logic.

    /Michael

  • W (unregistered) in reply to Dividius

    The problem is that the database code and the validation code is written separately; it does not have to be. Code generation is an important part of larger projects that uses disparate systems. Whether it's XML, classes in an OO programming language, or relational database tables, the info set, the rules for what is allowed and not allowed, is the same, and can be encoded once and only once, then used to generate the needed create table statements, XML schemas, or classes.

    What do you do when the requirements change? Search through all the different systems with its different rules and hope you catch everywhere you need to change the rules?

  • phx (unregistered) in reply to W

    Codegen is an archaic concept thats been made obsolete by proper use of metadata, like attributes and AOP techniques.

  • Darkstar (unregistered)

    Might have been a bit of a preach, might have been a bit on the serious side, but stuff like this has spawned so many WTFs.

    Like a previous commenter has mentioned, I've been in a situation where I had to code a system like this, horrendously complex, supposedly future proof, nightmare logic and code to carry out simple tasks (where and IF .. ELSE .. ENDIF would have done just as well), and a year down the line when the company changed one of it's core working practices the application failed them.

    Faced with the prospect of another year of major development work to get the application up and running again, the company decided to "let the developers go" and buy off the shelf products.

    I was fortunate enough to be working closely with the database manager and he saved my neck by requesting that I change departments as he needed help managing the mess.

    We still have the application and the code round here somewhere, if I could just dig it out, I could keep this site supplied with WTFs for years, lol.

  • ThomL (unregistered)

    I think a lot of the problem is that the logical layering of a software design has been equated with the physical deployment of an application into (n-)tiers. These should be orthogonal concepts - there's no reason that (for example) a bit of your business logic layer can't run on your presentation tier.

    Layering is an essential concept in software design and has been successfully applied so that you and I can program in Java and not assembly. I would argue that a layered approach will be found in most successful software and that you can and SHOULD reduce or eliminate the need for duplication of information between these layers. Well structured error handling between layers is your friend here.

    Tiers are a deployment concept and may or may not be necessary or even possible depending on the precise requirements of your project. Let's stop confusing these two concepts.

    ThomL.

    P.S. Alex - just because one effort to reduce duplication between layers (the ERE) resulted in a huge WTF does not mean that the exact opposite (duplicate logic everywhere) is the right answer. System design is not binary ;)

Leave a comment on “The Mythical Business Layer”

Log In or post as a guest

Replying to comment #:

« Return to Article