Michael Jervis shares another gem from his former employer (the place with the custom in-house "development" "tool"). At first glance, if may seem like a runner-up in the Nested-If competition. But it's far worse than that ...
Set WSObj = Server.CreateObject("WScript.Network") If sUserName <> "" Then If CheckLicences(sUserName) Then If Not(CheckLogonOther(sUserName, WSObj.ComputerName)) Then If AccountExist(sUserName) Then If CheckDisabled(sUserName) Then If CheckPassword(sUserName, sPassword) Then If Not(CheckPasswordExpDate(sUserName, sPassword)) Then If Not(CheckPasswordExpSoon(sUserName)) Then If Not(CheckFirstLogin(sUserName)) Then Call SetupSessionVars() Call AddToUserTable(sUserName, cstr(sClientIP), "page.asp") Response.Redirect("../pages/page.asp") Else Call SetupSessionVars() Call AddToUserTable(sUserName, cstr(sClientIP), "ChangePassword.asp") Response.Redirect("ChangePassword.asp?ChangeMode=FirstLog") End if Else Call SetupSessionVars() Call AddToUserTable(sUserName, cstr(sClientIP), "otherpage.asp") Response.Redirect("../pages/page.asp?DaysLeft=" + cstr(NumberOfDaysLeft(sUserName))) End if Else Call SetupSessionVars() Call AddToUserTable(sUserName, cstr(sClientIP), "ChangePassword.asp") Response.Redirect("ChangePassword.asp?ChangeMode=Expiry") End if Else Session("Attempts") = Session("Attempts") + 1 If Session("Attempts") >= 3 Then Session("Attempts") = 0 Call DisableAccount(sUserName) Response.Redirect("login.asp?Err=2") Else Response.Redirect("login.asp?Err=1") End if End if Else Response.Redirect("login.asp?Err=3") End if Else Response.Redirect("login.asp?Err=1") End if Else Response.Redirect("login.asp?Err=5") End if Else Response.Redirect("login.asp?Err=6") End if Else Response.Redirect("login.asp?Err=1") End If
Each function call (AccountExist, CheckLicences, etc) creates a related COM object (clsAccountExist, clsCheckLicences, etc) and calls the corresponding method on that object (AccountExist, CheckLicences, etc). The method on that object in turn creates a COM object (clsAccountExistDA, clsCheckLicencesDA, etc) that abstracts the database access (clsAccountExistCRUD, clsCheckLicencesCRUD, etc) which finally calls a stored procedure in the database. Phew!
Now you may be thinking gee, with all those layers, it must be good. And yes, although it really pains me to say, a Windows-DNA architecture ... can ... be ... ... ... good ... sometimes. But if your object-oriented solution is a class for each function you need, I'm not sure any enterprise architecture pattern will help ...