Layers, just cause



  • Everyone knows that the proper way to do .net applications is the three tiered approach right?  You have a presentation layer, a business logic layer, and a data access layer.  Well in order to satisfy this absolute truth my co-workers mindlessly create BLL classes like this (the only thing I changed was the project name):

    Namespace Project.BLL
        Public Class TableProperty
            Dim DAL As New Project.DAL.TableProperty

            Public Function CheckTableExists(ByVal TableInQuestion As String, ByVal strconn As String) As Boolean
                Return DAL.CheckTableExists(TableInQuestion, strconn)
            End Function

            Public Function ConvertValue(ByVal TableInQuestion As String, ByVal ColumnInQuestion As String, ByVal ValueInQuestion As Object, ByVal strconn As String) As Object
                Return DAL.ConvertValue(TableInQuestion, ColumnInQuestion, ValueInQuestion, strconn)
            End Function

            Public Function CheckColumnsExists(ByVal TableInQuestion As String, ByVal ColumnInQuestion As String, ByVal strconn As String) As Boolean
                Return DAL.CheckColumnExists(TableInQuestion, ColumnInQuestion, strconn)
            End Function

            Public Function GetpkTable(ByVal TableInQuestion As String, ByVal strconn As String) As String
                Return DAL.GetpkTable(TableInQuestion, strconn)
            End Function

            Public Function GetDataTypeLength(ByVal tableInQuestion As String, ByVal columnInQuestion As String, ByVal strconn As String) As String
                Return DAL.GetDataTypeLength(tableInQuestion, columnInQuestion, strconn)
            End Function
        End Class
    End Namespace

    So in this one project there are over 20 files/classes (because each file can only have one class, period) that do nothing but call the function in the DAL layer which does all the actual work.  When I asked one of the other senior programmers why they do this the answer was pretty much, "Well, because you're supposed to have a BLL layer."

     And while I'm here bitching I will go ahead and complain about the retarded variable names.  "TableInQuestion"  Really?  Why not be more precise and call it "TableImPassingAsAParameter".  And for fucks sake, choose a naming convention.  CamelCase?  camelCase?  camelcase?  Hungarian Notation?  Please, for the love of god, just choose something and stick with it.



  • Typical "best practices" based approach. Instead of understanding the benefits (and costs) of a three-tiered approach, just do what the book says. I have a co-worker that is constantly asking me how I know when to go with approach A vs. approach B. He can't handle it when I tell him "Go with A when the costs of A are less than the benefits of A, otherwise go with B".

    I also constantly find little nuggets of code in the middle of his that don't seem to belong. When I ask him what they are supposed to do he says "I don't know". Inevitably, he copied them from a similar class.



  • This abomination is probably familiar to many. I bet the "presentation" layer is actually doing all the business logic too.



  • @Jaime said:

    Typical "best practices" based approach. Instead of understanding the benefits (and costs) of a three-tiered approach, just do what the book says.

    Perhaps that's the fault of the book for not explaining why that approach should be followed, or when that approach is valid (or invalid). I have many technical books that concentrate upon the HowTo, but only my O'Reily ones examine WhyTo/WhyNot, WhenTo and WhyTheFuckDidThey.

    @Jaime said:

    I have a co-worker that is constantly asking me how I know when to go with approach A vs. approach B. He can't handle it when I tell him "Go with A when the costs of A are less than the benefits of A, otherwise go with B".

    I guess they're still struggling to see how to think for themselves and require clarification.

    Look, you're not really advancing their situation with an answer like that; at least they've taken the time to stop and question the sanity of their approach rather than ignorantly plough on until some external influence slams the brakes on. Why not take some time out to draw out the benefits and costs from their problem, showing them how you would tackle it? If they learned your analysis then they'd soon be able to answer that question on their own, right?

    @Jaime said:

    I also constantly find little nuggets of code in the middle of his that don't seem to belong. When I ask him what they are supposed to do he says "I don't know". Inevitably, he copied them from a similar class.

    .. and until [you take|someone else takes] the time out to educate him, he'll never learn. He's extended an olive branch, don't just dismiss it else you're complaining about the problem but not contributing to the solution.



  • @pjt33 said:

    This abomination is probably familiar to many. I bet the "presentation" layer is actually doing all the business logic too.

    I think this antipattern is increasingly prevalent due to many web-based systems where business logic (javascript) and presentation (HTML/CSS) appear in the same file. At least with JSP/ASP/PHP there is more of a physical separation, but some people have a problem with viewing the logical separation.



  • @Cassidy said:

    @pjt33 said:

    This abomination is probably familiar to many. I bet the "presentation" layer is actually doing all the business logic too.

    At least with JSP/ASP/PHP there is more of a physical separation

     

    Only in the hands of -very- capable people; all three technologies don't exactly advocate clean usage. For example JSP would have been great if since the invention of tag libraries and JSTL (standard tag library) the possibility for using scriptlets (Java code directly in the JSP) would have been completely disallowed. Alas, maintaining old applications is now hell itself.

     



  •  BLL layer, DAL layer...

    some nice RAS syndrome right there

    </offtopic>



  • @erikal said:

    Only in the hands of -very- capable people; all three technologies don't exactly advocate clean usage.

    Oh, true. True. I was merely commenting that it's easy to drop CSS and JS in the middle of HTML and people not able to visualise what statement lies within what domain. At least with PHP, most developers[1] on the whole concern themselves with functional development and leave the presentation to the template/CSS people. It's still not perfect by any means, just that people can distinguish between layers easier within a physical client-server (or n-tier) model.

    @erikal said:

    Alas, maintaining old applications is now hell itself.

    Business case for "Software Investment" (read: refactoring, code cleanup, imposing standards to facilitate more efficient change management in future, etc)...?

    Let's not forget that shoddy programming from the old days through lack of standards (and lack of understanding of the importance of standards) drove us to question if we were doing things the right way, and analysis of the impact (financial et al) of The Way Things Were justified the creation of standards and framework in an attempt to improve quality. There will always be older code, a legacy of a bygone era - what's important now is what we do with it today: deprecate it because it's no longer of any value to us, or update it to the modern standards because it's still in use (and provides value). The longer it remains in the "don't touch it - it still works" grey area, the more interest is accrued upon the Bank Account Of Awaiting Work.

    TL;DR: if you have ownership of said applications, then do something now to make ongoing maintanence easier in future.



  • @Cassidy said:

    @Jaime said:

    Typical "best practices" based approach. Instead of understanding the benefits (and costs) of a three-tiered approach, just do what the book says.

    Perhaps that's the fault of the book for not explaining why that approach should be followed, or when that approach is valid (or invalid). I have many technical books that concentrate upon the HowTo, but only my O'Reily ones examine WhyTo/WhyNot, WhenTo and WhyTheFuckDidThey.

    No, don't blame the book. If a book tells you to obfuscate all code and avoid documenting it (I've seen it), and you go and do it, it's your fault for not being able to think critically. You are a hazard to any company. Also, people shouldn't wait until someone comes and tells them why things are like they are, and what the best practices are in each case. Everyone should be responsible enough to seek proper education on their own. The company may help, as in paying for courses and giving training, but people who are not proactive and have no wish to learn should have no place in IT.


  • ♿ (Parody)

    @Cassidy said:

    Look, you're not really advancing their situation with an answer like that; at least they've taken the time to stop and question the sanity of their approach rather than ignorantly plough on until some external influence slams the brakes on. Why not take some time out to draw out the benefits and costs from their problem, showing them how you would tackle it? If they learned your analysis then they'd soon be able to answer that question on their own, right?

    You're right, but projecting my experience onto Jaime's comment, I suspect that your approach had already been tried on this guy, and he's still just as clueless. Some people are very successful at not learning things, and the best approach is often to just make them go back to their WTFery as quickly as possible. Explaining in more detail (again) is just wasting everyone's time.



  • @Renan said:

    No, don't blame the book....... Everyone should be responsible enough to seek proper education on their own.

    Yeah, I know, TRWTF is humans, not books - that's why I said "perhaps".

    However, the point of reading books is to further your education - whilst I know you can't learn everything from a book, it should give you a good enough grounding. I'm sure you've come across good and bad books - could you argue that some books are so badly-written that TRWTF is you for not realising it? We all had to start somewhere, and you don't know how good/bad a book can be until you've read a second, etc.

    @boomzilla said:

    You're right, but projecting my experience onto Jaime's comment, I suspect that your approach had already been tried on this guy, and he's still just as clueless. Some people are very successful at not learning things, and the best approach is often to just make them go back to their WTFery as quickly as possible. Explaining in more detail (again) is just wasting everyone's time.

    I've got this situation over on another forum at the moment where a clueless user refuses to follow instructions, ignores advice and half-answers questions (or rather, answers the question he imagines, rather than the one that's been asked). Despite all this, we're still offering him assistance because he's still requesting it, which means he's still interested in fixing his problem. At some point it'll be highlighted to him the reasons behind why it's taking so long to solve his problem (we're taking bets as to whether or not he'll figure it out by himself).

    So in Jaime's situation - if the guy keeps coming up, it shows he's still open to ideas - compare those to "IknowBESTdontTELLmeMYjob" perfect-perfects. Dismissing him can either discourage him asking Jaime, or asking anyone else, and he'll never better himself from anyone else's experiences, and Jaime will continue to find repeated WTFs in the codebase. Encouraging him to think differently and stimulating those thought processes can only shape his learning and outlook upon problem-solving; the WTFs won't go away overnight, but by discussing with Jaime why he took that route and what other avenues are possible, he'll learn.

    I know some effort is required on his part, and it may be an uphill struggle, and he may never learn. But one thing's certain: if you discourage him from seeking out a possible mentor, then he'll definitely WON'T learn. YMMV.


  • Discourse touched me in a no-no place

    @Cassidy said:

    whilst I know you can't learn everything from a book, it should give you a good enough grounding. I'm sure you've come across good and bad books
    Herbert Schildt provides exemplars of the latter.



  • @Cassidy said:

    So in Jaime's situation - if the guy keeps coming up, it shows he's still open to ideas - compare those to "IknowBESTdontTELLmeMYjob" perfect-perfects. Dismissing him can either discourage him asking Jaime, or asking anyone else, and he'll never better himself from anyone else's experiences, and Jaime will continue to find repeated WTFs in the codebase. Encouraging him to think differently and stimulating those thought processes can only shape his learning and outlook upon problem-solving; the WTFs won't go away overnight, but by discussing with Jaime why he took that route and what other avenues are possible, he'll learn.
    I'm three years into trying to teach him (I spent ten years as a successful IT trainer from 1995 to 2005).  The low point was recently when I tried to set him up for some tiny success...  I made an arrangement with him, we'd use his next check-in as a discussion opportunity.  I said "Next time you're going to check something in, be prepared to talk about what you did and why you did it."  The next day he checks something in.  I wandered over to his office and start to discuss what he did -- I start with "Why did you do it that way, what alternatives did you consider".  He had no answer.  I don't mean he couldn't articulate what he was thinking, I mean the room was silent.

    Yesterday, he checked in a script to create a table.  In the middle of it was a section that ran sp_helpindex and saved the results in a temp table.  The temp table wasn't used at any other point in the script.  I politely asked what that section was for.  He said he found it in a table script I had written a few weeks ago, that was the end of the explanation.  I asked "what were you trying to accomplish when you copied these lines"... no answer.  It turns out he copied half of my script that dumped the current indexes to a temp table, queried the temp table to find if a particular index was defined, and created it if it wasn't.  He copied it without any rational thought to what he was doing other than "Jaime's was right, so the closer mine looks to his, the righter I'll be".



  • This reminds me of a student from my first semester in college.  The class was intro to computer architecture and the first chapter was on non base 10 counting methods.  This included binary, octal, hexadecimal and the general theory of that you do not have to use numeric symbols to represent numbers.  She was so lost and confused (and was planning on being a Computer Science major).  I and several of my friends and other students did try to help her out, but after a month she realized that just maybe she should change her major and then dropped the class.  I have no problem with helping someone over and over again if they are constantly asking for help, but eventually they need to either have a moment of clarity where it all of a suddenly starts to make sense or they need to come to the realization that they might not be cut out for said line of work, and should try something less difficult or different.



  • @Jaime said:

    Typical "best practices" based approach. Instead of understanding the benefits (and costs) of a three-tiered approach, just do what the book says. I have a co-worker that is constantly asking me how I know when to go with approach A vs. approach B. He can't handle it when I tell him "Go with A when the costs of A are less than the benefits of A, otherwise go with B".

    I also constantly find little nuggets of code in the middle of his that don't seem to belong. When I ask him what they are supposed to do he says "I don't know". Inevitably, he copied them from a similar class.

    I used to work at a company where the official architecture group was very pro-.NET and also very much in favor of the three-layer-burrito architecture.



    We programmers didn't have to actually listen to these people. It was encouraged, of course, but the architecture group still had to basically put on a road show to all of our locations and try to sell the ".NET / three-tier" approach to a bunch of very scared client/server and mainframe developers.



    I would typically give the architecture group a hard time during these little dog-and-pony shows. They had a very difficult time talking about the code in their "BL" classes, or even just explaining why the BL layer existed. Eventually, the "party line" answer became "the BL layer is typically just a pass-through layer, with validation added."



    Of course, the DA layer methods were required to validate all their inputs anyway, so we all thought that having a BL tier was incredibly pointless. My real code at that place consisted of string-concatenated SQL statements running directly from event handlers.



    I was aware that my own approach was less than ideal... but the architecture group's failure to present a real, viable alternative only encouraged this result. Part of me wanted to do things The Right Way (a registered trademark of Microsoft Corporation)... but the "right" way at that place was laughable. The pace and tenor of application development that resulted from that architecture group's preferred methodologies was like something out of the early 1980s.



  • @bridget99 said:

    ...

    I would typically give the architecture group a hard time during these little dog-and-pony shows. They had a very difficult time talking about the code in their "BL" classes, or even just explaining why the BL layer existed. Eventually, the "party line" answer became "the BL layer is typically just a pass-through layer, with validation added." 

    ...

    My current program uses the 3 layers, and so I decided to peek at our BLL and it is -all- pass through one liner functions.  This is my first time having to work with the 3 layers, and I personally dont see the point of the BLL, I guess I probably need to do some research for why it even exists.



  • @SEMI-HYBRID code said:

     BLL layer, DAL layer...

    some nice RAS syndrome right there

    </offtopic>

    You've never heard of a layer layer?  I was clearly talking about some one who lays down layers.  Duh.



  • @bridget99 said:

    BL layer
     

    Business Layer layer?



  • Funny, I always thought the "A" was for "abstraction".



  • @Cassidy said:

    I think this antipattern is increasingly prevalent due to many web-based systems where business logic (javascript) and presentation (HTML/CSS) appear in the same file.

    What? If HTML/CSS/JS are in the same file something is fucked.

    @Cassidy said:

    At least with JSP/ASP/PHP there is more of a physical separation, but some people have a problem with viewing the logical separation.

    What? I've seen plenty of PHP/JSP apps where nobody understood that there even was a logical separation between logic and presentation. It's quite possible to shove everything into your PHP/JSP file.



  • @Jaime said:

    I made an arrangement with him, we'd use his next check-in as a discussion opportunity.  I said "Next time you're going to check something in, be prepared to talk about what you did and why you did it." 

    The next day he checks something in. 

    I wandered over to his office and start to discuss what he did -- I start with "Why did you do it that way, what alternatives did you consider".  He had no answer.

    I suppose the first question I would have asked was "didn't we agree that you would...." - but he clearly didn't prepare. Do you think his issue is impatience or ignorance?

    (and yup.. I understand that there's a time you've gotta cut them loose if despite everything, they're still a lost cause - it needs explaining to him in no uncertain terms that his own behaviour is holding him back)

    Wonder if paired programming would work in this case, or a mentoring programme. But I digress...

    @bridget99 said:

    I was aware that my own approach was less than ideal... but the architecture group's failure to present a real, viable alternative only encouraged this result. Part of me wanted to do things The Right Way (a registered trademark of Microsoft Corporation)... but the "right" way at that place was laughable.

    That's... probably once of the most sober things you've said that I agree with. It's a crying shame that not only is this "right way" not actually sold to you in terms of benefits (and advantages over the current way), but that you can spot the right way is .. just another way, and not even the most effective.

    Worse still is people that blindly buy into the religion without proper analysis to the reasons why (or any understanding of why not)



  • @Cassidy said:

    @bridget99 said:

    I was aware that my own approach was less than
    ideal... but the architecture group's failure to present a real, viable
    alternative only encouraged this result. Part of me wanted to do things
    The Right Way (a registered trademark of Microsoft Corporation)... but
    the "right" way at that place was laughable.

    That's... probably once of the most sober things you've said that I agree with. It's a crying shame that not only is this "right way" not actually sold to you in terms of benefits (and advantages over the current way), but that you can spot the right way is .. just another way, and not even the most effective.

    Worse still is people that blindly buy into the religion without proper analysis to the reasons why (or any understanding of why not)

    You must have missed this gem:

    @bridget99 said:

    My real code at that place consisted of string-concatenated SQL statements running directly from event handlers.

    Admittedly, a layer that just mindlessly passes through everything makes no sense (just like "let's add getters/setters to everything" antipattern in Java), but at least it's not spaghetti crap.



  • @Anketam said:

    This is my first time having to work with the 3 layers, and I personally dont see the point of the BLL, I guess I probably need to do some research for why it even exists.

    You don't see the point of that BLL, or having a BLL?

    @morbiuswilters said:

    What? If HTML/CSS/JS are in the same file something is fucked.

    Not necessarily. I included the lot into one file for an expenses form for our sales droids. They got used to firing it up and banging in the information, allowing it to do the calculations for them before printing it out.

    (yes, I did develop it as separate files originally, then consolidated it so they only had the one file to use)

    But this is an exceptional case, not the norm.

    @morbiuswilters said:

    What? I've seen plenty of PHP/JSP apps where nobody understood that there even was a logical separation between logic and presentation. It's quite possible to shove everything into your PHP/JSP file.

    *sign* yes, it IS possible to shove it all into one file, the same way that it's possible to shove HTML/CSS/JS all into one file. However, IME most of the PHP I've seen uses a smaller set of files to do processing and several helper functions to handle DAL and presentation (skins/themes). I'm not saying that this is a feature of the code, just a mindset of many coders I've experienced. YMMV, obviously.



  • @morbiuswilters said:

    You must have missed this gem:

    @bridget99 said:

    My real code at that place consisted of string-concatenated SQL statements running directly from event handlers.

    Oh, yup - I did miss it.Old eyes and everything.

    However, my point was more about those trying to encourage change weren't engaging those that needed to change.



  • @Cassidy said:

    Not necessarily. I included the lot into one file for an expenses form for our sales droids. They got used to firing it up and banging in the information, allowing it to do the calculations for them before printing it out.

    (yes, I did develop it as separate files originally, then consolidated it so they only had the one file to use)

    Why not just throw it on a server, then? You keep your separation and it gives you a single place to administer changes.

    @Cassidy said:

    sign yes, it IS possible to shove it all into one file, the same way that it's possible to shove HTML/CSS/JS all into one file. However, IME most of the PHP I've seen uses a smaller set of files to do processing and several helper functions to handle DAL and presentation (skins/themes). I'm not saying that this is a feature of the code, just a mindset of many coders I've experienced. YMMV, obviously.

    My point was more-or-less that the "shove-everything-into-one-file" mentality can exist anywhere. I really haven't seen it more prevalent in JS than other languages. At least, ever since JS became a "real" language in 2006 or so.



  • @Cassidy said:

    However, my point was more about those trying to encourage change weren't engaging those that needed to change.

    And my point is that if you feel like bridget99 is making sense, just dig a little deeper.



  • @frits said:

    Funny, I always thought the "A" was for "abstraction".

    Microsoft calls it a data access layer: http://msdn.microsoft.com/en-us/library/aa581778.aspx.  Abstraction would definately work too though.



  • @morbiuswilters said:

    Why not just throw it on a server, then? You keep your separation and it gives you a single place to administer changes.

    It was, originally (and in 3 files) on our intranet - which was inaccessible to the travelling sales girls, so I did a version they could drop onto their laptops.

    Further clarification necessary: this preceeded our remote-desktop system that we have now.  Erm.. can't remember how far back this was, but I remember at the time any company laptops had - by policy - an inbuilt modem so they could use phone lines in hotels. Probably only 10 or so years back? My memory fails meh.

    @morbiuswilters said:

    My point was more-or-less that the "shove-everything-into-one-file" mentality can exist anywhere.

    Ayup. *nods in agreement whilst shaking head at disbelief of the things he's witnessed. Which results in a creepy rotary movement*

    @morbiuswilters said:

    And my point is that if you feel like bridget99 is making sense, just dig a little deeper.

    Hey, everyone's entitled to statistical abnormalities once in a while, no matter how quick that eye in the midst of insanity fleetingly appears. Cherish these precious little moments.



  • @morbiuswilters said:

    My point was more-or-less that the "shove-everything-into-one-file" mentality can exist anywhere.
     

    Hey did I tell you about the .Net I modified today where the ascx had 1 line, and everything was in the codebehind using HtmlWriter objects?

    Or the duplicate method that was not an overload but nonetheless had the exact same code (also with HtmlWriter all around!) save for one line where it would add "active" state to some big menu button?

    GOOD TIMES.



  • @dhromed said:

    @morbiuswilters said:

    My point was more-or-less that the "shove-everything-into-one-file" mentality can exist anywhere.
     

    Hey did I tell you about the .Net I modified today where the ascx had 1 line, and everything was in the codebehind using HtmlWriter objects?

    Or the duplicate method that was not an overload but nonetheless had the exact same code (also with HtmlWriter all around!) save for one line where it would add "active" state to some big menu button?

    GOOD TIMES.

    We have an entire "admin tool" for all the customer service reps to use, it's a WS where this is almost exactly what they've done.  It's not one line, but you get to the code behind and it's like (pseudocode, I'm not looking at it atm):

    HtmlResponse.Write("<table format="SomeFormat"><tr>");

    HtmlResponse.Write("<td Name="Table Header 1"/><td Name="Table Header 2"/>...");

    foreach(object in something)

       HtmlResponse.Write("<td Name="" + object.FieldForTableHeader1 + "/>");

       HtmlResponse.Write("<td Name="" + object.FieldForTableHeader2 + "/>");

    ...etc



  • What troubles me is that these people didn't immediately recognize the potential for separation of presentation and business that .Net offers, because apparently they didn't miss it in classic ASP or PHP or whatever. They probably perceive ascx/cs files as some sort of nuisance.



  • @dhromed said:

    What troubles me is that these people didn't immediately recognize the potential for separation of presentation and business that .Net offers, because apparently they didn't miss it in classic ASP or PHP or whatever. They probably perceive ascx/cs files as some sort of nuisance.

    Many do see it as a nuisance. That's why I find a lot of pages with code half in the code-behind file and half embedded in the markup.

    BTW, the biggest WTF in the early comments here is not that some people screw up three tier design, but that a few posters don't seem to think there's any value in it (Anketam, bridget99), or that bridget99's architecture group couldn't make a rational case for it.



  • @Jaime said:

    ...but that a few posters don't seem to think there's any value in it (Anketam
     

    I'm still awaiting clarification on his case. Nonetheless, Anketam and Bridget have a common trait: if the benefits of a new way aren't explained, there is no incentive to follow.



  • @Jaime said:

    BTW, the biggest WTF in the early comments here is not that some people screw up three tier design, but that a few posters don't seem to think there's any value in it (Anketam, bridget99), or that bridget99's architecture group couldn't make a rational case for it.

    You must be new here. Of course if it's a good coding practice, Bridget99 is going to oppose it. I mean duh, it's Bridget99.


  • :belt_onion:

    @Anketam said:

    @bridget99 said:

    ...

    I would typically give the architecture group a hard time during these little dog-and-pony shows. They had a very difficult time talking about the code in their "BL" classes, or even just explaining why the BL layer existed. Eventually, the "party line" answer became "the BL layer is typically just a pass-through layer, with validation added." 

    ...

    My current program uses the 3 layers, and so I decided to peek at our BLL and it is -all- pass through one liner functions.  This is my first time having to work with the 3 layers, and I personally dont see the point of the BLL, I guess I probably need to do some research for why it even exists.

    This only makes sense if your application is a dumb front for a database. Or are you executing your business logic directly inline with your presentation logic? For example where do you test: if Timmy has no money in his account then he cannot withdraw any cash with his debit card? 


  • @bjolling said:

    This only makes sense if your application is a dumb front for a database. Or are you executing your business logic directly inline with your presentation logic? For example where do you test: if Timmy has no money in his account then he cannot withdraw any cash with his debit card? 

    Even in the first case, there is still some business logic (albeit a smaller amount) - rules of what is deemed acceptable input, direction to dealing with exceptions, etc.

    I'm sure, at some point, all coders involved in change and maintanence often look at the pile in front of them and think "could we split out the stuff I need to alter from the stuff I'll never touch?" and begin to categorise, maybe even only functioanlly.

    I think my first entry into MVC was refactoring a group of common pages, removing embedded style information and arrive at a common CSS across all, before I also began to separate database calls into a set of common functions. Soon after, I learned about MVC and understood not only what I had been trying to acheive, but the benefits of starting with that ethos from the get-go.

    I also learned that not all community-driven projects are particularly well-designed, well-written or well-maintained.



  • @Cassidy said:

    perfect-perfects

    SpectateSwamp... Is that you?


  • :belt_onion:

    @Cassidy said:

    @bjolling said:

    This only makes sense if your application is a dumb front for a database. Or are you executing your business logic directly inline with your presentation logic? For example where do you test: if Timmy has no money in his account then he cannot withdraw any cash with his debit card? 

    Even in the first case, there is still some business logic (albeit a smaller amount) - rules of what is deemed acceptable input, direction to dealing with exceptions, etc.

    Input validation logic is not necessarily the same as business logic. You mentioned MVC, so let me build further on that and become more concrete.

    Suppose you are developing an ATM. There is a screen that let's you enter the number of 5 dollar bills you want. The fact that the user will have to input a numeric value is not business logic because according to business logic it would be acceptable to type "three" instead of "3". This is purely validation logic that lives in the ViewModel on the presentation layer.

    When the user has entered a valid number and the user clicks "Withdraw", the presentation layer (Controller) contacts the business layer which instantiates the "BankAccount" class passing information from the debet card so that you are working on the correct bank account. Then it calls BankAccount.Withdraw(3) who raises a business exception that the PIN is empty.

    So the Controller catches this PinIsEmptyException and displays a View to prompt the user for the PIN. The validation logic verifies if the PIN is within the range of accepted values. When calling back into the business layer, this PIN is actually used and checked for correctness. Now the business layer calls BankAccount.Withdraw(3) and either it returns succesfully or raises the BalanceInsufficientException. The Controller knows how to deal with both situations and either instructs the machine to dispense money or shows a View with an error mesage

    The big advantage of not having any business logic in my Views is that I can unittest my business layer independently from my views. In above scenario, I can unittest for a missing PIN and an insufficient balance and I don't need to have my screen running on an actual ATM or emulator

    Edit: Above is not my design for a decent ATM software



  • @bjolling said:

    Edit: Above is not my design for a decent ATM software

    You seem to be spreading a lot of incorrect information. You mentioned ViewModel which implies you are doing developing using Microsoft's tools, so maybe they do things differently, but..

    @bjolling said:

    The fact that the user will have to input a numeric value is not business logic because according to business logic it would be acceptable to type "three" instead of "3".

    This statement is kind of silly. Strictly speaking I suppose you are right, but the use of numerals is an obvious constraint of any business system. I would say most data validation falls under the category of business logic, which is where it belongs. For example, if you require a valid first name, last name and email address then I would do that in the model layer. Otherwise your model isn't encapsulating your constraints accurately AND you end up having copypasta validation all over the place.

    @bjolling said:

    the presentation layer (Controller)

    Controllers are not the presentation layer. They are more the UI event layer.

    @bjolling said:

    Then it calls BankAccount.Withdraw(3) who raises a business exception that the PIN is empty.

    So the Controller catches this PinIsEmptyException and displays a View to prompt the user for the PIN.

    Exceptions should not be used for flow control.

    @bjolling said:

    The big advantage of not having any business logic in my Views is that I can unittest my business layer independently from my views. In above scenario, I can unittest for a missing PIN and an insufficient balance and I don't need to have my screen running on an actual ATM or emulator

    Which is absolutely correct, except for the fact that you included validation logic in the views. So basically some validation logic is done in the model and some in the view but it's not easy to say which is responsible for which. Unit testing is even more difficult. "Let's pass the model an invalid amount to withdraw, like -100." "Oh, but was that validation logic done at the view or the model?"

    My take: views should be as lightweight as possible. I would recommend reading up on Passive View.



  • @bjolling said:

    Input validation logic is not necessarily the same as business logic.

    I believe it is. To some extent, you are validating your input against a set of business rules. The programmer doesn't decide what's correct and what's incorrect input, the business does -  the coder's decision is how to implement this validation stage.

    You mentioned MVC, so let me build further on that and become more concrete.

    @bjolling said:

    Suppose you are developing an ATM. There is a screen that let's you enter the number of 5 dollar bills you want. The fact that the user will have to input a numeric value is not business logic because according to business logic it would be acceptable to type "three" instead of "3".

    I still feel that defining correct input and deciding what to do upon incorrect input (sanitisation, canonicalisation, rejection etc) is a business decision.

    @bjolling said:

    This is purely validation logic that lives in the ViewModel on the presentation layer.

    Sorry, are we talking about the View or the Model part of MVC here?

    @bjolling said:

    the presentation layer (Controller)

    Now I'm confused. I thought the presentation layer was the View - the Controller should be separate.

    @bjolling said:

    So the Controller catches this PinIsEmptyException and displays a View to prompt the user for the PIN. The validation logic verifies if the PIN is within the range of accepted values. When calling back into the business layer, this PIN is actually used and checked for correctness.

    Being pedantic, but isn't the validation logic also used to check for correctness?

    @bjolling said:

    Now the business layer calls BankAccount.Withdraw(3) and either it returns succesfully or raises the BalanceInsufficientException. The Controller knows how to deal with both situations and either instructs the machine to dispense money or shows a View with an error mesage

    The big advantage of not having any business logic in my Views is that I can unittest my business layer independently from my views. In above scenario, I can unittest for a missing PIN and an insufficient balance and I don't need to have my screen running on an actual ATM or emulator

    That last bit has probably never been explained to bridget and Anketam.

    I don't disagree with the View containing validation logic, but ultimately the Controller has overall control (the final desicion) - by delegating some of those checks out to the View you are allowing this class to make an informed decision when passing messages to the Controller, but in doing so you run the risk of duplicating validation logic when dealing with several View classes. YMMV.


  • :belt_onion:

    @morbiuswilters said:

    @bjolling said:
    The fact that the user will have to input a numeric value is not business logic because according to business logic it would be acceptable to type "three" instead of "3".

    This statement is kind of silly. Strictly speaking I suppose you are right, but the use of numerals is an obvious constraint of any business system. I would say most data validation falls under the category of business logic, which is where it belongs. For example, if you require a valid first name, last name and email address then I would do that in the model layer. Otherwise your model isn't encapsulating your constraints accurately AND you end up having copypasta validation all over the place.

    @bjolling said:

    the presentation layer (Controller)

    Controllers are not the presentation layer. They are more the UI event layer.

    We are probably just discussing semantics here. Controllers are not part of the presentation but for ease of programming I've always included them in the same assembly (library) as the views and viewmodels. So in my projects they are part of the presentation layer, mainly because in the Microsofts way of doing things, it makes no sense to re-use an ASP.NET MVC controller inside a WPF application.

    I've mainly been doing web development so in my case the model layer (server side) indeed needs to check if the required parameters have been provided but the views needs to do the same thing too, even if it's just to avoid postbacks to tell a user that a certain field is required. I'd refer to these "help my users to easily complete their forms" as validation logic. Yes, it means you end up with the some checks twice, once in client-side Javascript and once in your model layer (business layer, domain service, ...)

    @morbiuswilters said:

    Exceptions should not be used for flow control.
    I do agree but was merely responding to a remark by Cassidy about "direction to dealing with Exceptions". Could have found better examples instead of adding my disclaimer I suppose.

    @morbiuswilters said:

    My take: views should be as lightweight as possible. I would recommend reading up on Passive View.
    I've been experimenting with Passive View and I found it working very well with desktop applications. I've only just recently been reading up on a way to do the same for web applications. Basically:

    • Views in HTML
    • ViewModels in Javascript
    • Model - server side web services being accessed through AJAX

     Microsoft has been recently releasing some very exciting libraries: "knockout.js" to setup two-way binding between the HTML DOM elements and these javascript viewmodels. And then "upshot.js" to bind these Viewmodels to the back-end through AJAX. 



  • @bjolling said:

    I've mainly been doing web development so in my case the model layer (server side) indeed needs to check if the required parameters have been provided but the views needs to do the same thing too, even if it's just to avoid postbacks to tell a user that a certain field is required. I'd refer to these "help my users to easily complete their forms" as validation logic. Yes, it means you end up with the some checks twice, once in client-side Javascript and once in your model layer (business layer, domain service, ...)

    That makes sense.

    @bjolling said:

    Microsoft has been recently releasing some very exciting libraries: "knockout.js" to setup two-way binding between the HTML DOM elements and these javascript viewmodels. And then "upshot.js" to bind these Viewmodels to the back-end through AJAX.

    That sounds pretty cool. What I've been gravitating towards is writing the whole MVC part in client-side Javascript. Then the backend doesn't really do any presentation, it just exposes API methods called by the frontend. Of course, you may end up duplicating some validation logic between frontend and backend, but you can do some of those just by posting back to the server and letting it do the validation (which sounds pretty much what the Microsoft libraries do).



  • @bjolling said:

    I've mainly been doing web development so in my case the model layer (server side) indeed needs to check if the required parameters have been provided but the views needs to do the same thing too, even if it's just to avoid postbacks to tell a user that a certain field is required. I'd refer to these "help my users to easily complete their forms" as validation logic. Yes, it means you end up with the some checks twice, once in client-side Javascript and once in your model layer (business layer, domain service, ...)

    That's kinda two controllers in two separate systems, isn't it? The server-side one delegating work to the client-side one (but not fully trusting it).

    (in UK, post offices can perform a basic validation on your passport application before sending them in. Just because the PO has validated it, the passport office won't blindly accept it, but the PO can more quickly identify flaws that will cause the PassO to reject the application. Delegated responsibility reduces the time at a cost of decentralised bizz rules, potentially reducing maintainability. But only minor.)

    @morbiuswilters said:

    Exceptions should not be used for flow control.

    @bjolling said:

    I do agree but was merely responding to a remark by Cassidy about "direction to dealing with Exceptions". Could have found better examples instead of adding my disclaimer I suppose.

    Mmmm... that confusion probably stemmed from my lack of clarity. To me, the Controller is the intelligent decision-making object, but is lazy with it, delegating the actual work out to Models/Views: thinking, not doing, so should have a handle on what to do when "exceptions to the happy path" are encountered, ie: deviations out of the normal workflow route - exceptions to the Use Case scenario. I didn't mean to infer code throwing an Exception. 

    Footnote: Passive View stuff sounds quite interesting. I've tried this before but abandoned it when I thought I was over-burdening the Controller, leaving the View to do very little. Didn't realise that was the point!


  • :belt_onion:

    @Cassidy said:

    @bjolling said:
    This is purely validation logic that lives in the ViewModel on the presentation layer.
    Sorry, are we talking about the View or the Model part of MVC here?
    I didn't realize you were talking pure MVC. I usually end up with "M V C VM", meaning that my views don't immediately affect the model (and vice versa)but pass through "adapters" called the ViewModel. The Model usually contains a fixed set of services that don't easily translate in your Views. ViewModel make this transformation. I also use it for generating the client-side validation rules, meaning the validations that help a user quickly fill in his HTML form without requiring a postback to call into the model to get the real checks for correctness.

    I think I answered the rest in my response to Morbs so feel free to call me out on what I posted there

     


Log in to reply