Three Tier Architecture

There is a lot of information on the Internet about the three-tier architecture, three-tier structure and other names for the concept of breaking a program into tiers.  The current system design paradigm is to break your software into APIs and the three-tier architecture still applies.  I’m going to try and explain the three-tier architecture from the point of practicality and explain the benefits of following this structure.  But first, I have to explain what happens when a hand-full of inexperienced programmers run in and build a system from the ground up…

Bad System Design

Every seasoned developer knows what I’m talking about.  It’s the organically grown, not very well planned system.  Programming is easy.  Once a person learns the basic syntax, the world is their oyster!  Until the system get really big.  There’s a tipping point where tightly-coupled monolithic systems become progressively more difficult and time consuming to enhance.  Many systems that I have worked on were well beyond that point when I started working on them.  Let me show a diagram of what I’m talking about:

Technically, there is no firm division between front-end and back-end code.  The HTML/JavaScript is usually embedded in back-end code and there is typically business code scattered between the HTML.  Sometimes systems like this contain a lot of stored procedures which does nothing more than marry you to the database that was first used to build the application.  Burying business code in stored procedures also has the additional financial burden of ensuring you are performing your processing on the product with the most expensive licensing fees.  When your company grows, you’ll be forced to purchase more and more licenses for the database in order to keep up.  This proceeds exponentially and you’ll come to a point where any tiny change in a stored procedure, function or table causes your user traffic to overwhelm the hardware that your database runs on.

I often-times joke about how I would like to build a time machine for no other reason than to go back in time, sit down with the developers of the system I am working on and tell them what they should do.  To head it off before it becomes a very large mess.  I suspect that this craziness occurs because companies are started by non-programmers and they hook-up with some young and energetic programmer with little real-world experience who can make magic happen.  Any programmer can get the seed started.  Poor programming practices and bad system design doesn’t show up right away.  A startup company might only have a few hundred users at first.  Hardware is cheap, SQL server licenses seem reasonable, everything is working as expected.  I also suspect that those developers move on when the system becomes too difficult to manager.  They move on to another “new” project that they can start bad.  Either that, or they learn their lesson and the next company they work at is lucky to get a programmer with knowledge of how not to write a program.

Once the software gets to the point that I’ve described, then it takes programmers like me to fix it.  Sometimes it takes a lot of programmers with my kind of knowledge to fix it.  Fixing a system like this is expensive and takes time.  It’s a lot like repairing a jet while in flight.  The jet must stay flying while you shut down one engine and upgrade it to a new one.  Sound like fun?  Sometimes it is, usually it’s not.

Three-Tier Basics

In case you’re completely unfamiliar with the three-tier system, here is the simplified diagram:

It looks simple, but the design is a bit nuanced.  First of all, the HTML, JavaScript, front-end frameworks, etc. must be contained in the front-end box.  You need isolation from the back-end or middle-tier.  The whole purpose of the front-end is to handle the presentation or human interface part of your system.  The back-end or middle-tier is all the business logic.  It all needs to be contained in this section.  It must be loosely coupled and unit tested.  Preferably with an IOC container like AutoFac.  The database must be nothing more than a container for your data.  Reduce special features as much as possible.  Your caching system is also located in this layer.

The connection between the front-end and back-end is usually an API connection using REST.  You can pass data back and forth between these two layers using JSON or XML or just perform “get”, “post”, “delete” and “put” operations.  If you treat your front-end as a system that communicates with another system called your back-end, you’ll have a successful implementation.  You’ll still have hardware challenges (like network bandwidth and server instances), but those can be solved much quicker and cheaper than rewriting software.

The connection between the back-end and database has another purpose.  Your goal should be to make sure your back-end is database technology independent as much as possible.  You want the option of switching to a database with cheap licensing costs.  If you work hard up-front, you’ll get a pay-back down the road when your company expands to a respectable size and the database licensing cost starts to look ugly.

What About APIs?

The above diagram looks like a monolithic program at first glance.  If you follow the rules I already laid out, you’ll end up with one large monolithic program.  So there’s one more level of separation you must be aware of.  You need to logically divide your system into independent APIs.  You can split your system into a handful of large APIs or hundreds of smaller APIs.  It’s better to build a lot of smaller APIs, but that can depend on what type of system is being built and how many logical boxes you can divide it into.  Here’s an example of a very simple system divided into APIs:

This is not a typical way to divide your APIs.  Typically, an API can share a database with another API and the front-end can be separate from the API itself.  For now, let’s talk about the advantages of this design as I’ve shown.

  1. Each section of your system is independent.  If a user decides to consume a lot of resources by executing a long-running task, it won’t affect any other section of your system.  You can contain the resource problem.  In the monolithic design, any long-running process will kill the entire system and all users will experience the slow-down.
  2. If one section of your system requires heavy resources, then you can allocate more resources for that one section and leave all other sections the same.  In other words, you can expand one API to be hosted by multiple servers, while other APIs are each on one server.
  3. Deployment is easy.  You only deploy the APIs that are updated.  If your front-end is well isolated, then you can deploy a back-end piece without the need for deployment of your front-end.
  4. Your technology can be mixed.  You can use different database technologies for each section.  You can use different programming languages for each back-end or different frameworks for each front-end.  This also means that you have a means to convert some or all of your system to a Unix hosted system.  A new API can be built using Python or PHP and that API can be hosted on a Linux virtual box.  Notice how the front-end should require no redesign as well as your database.  Just the back-end software for one subsection of your system.

Converting a Legacy System

If you have a legacy system built around the monolithic design pattern, you’re going to want to take steps as soon as possible to get into a three-tier architecture.  You’ll also want to build any new parts using an API design pattern.  Usually it takes multiple iterations to remove the stored procedures and replace the code with decoupled front-end and back-end code.  You’ll probably start with something like this:

In this diagram the database is shared between the new API and the legacy system, which is still just a monolithic program.  Notice how stored procedures are avoided by the API on the right side.  All the business logic must be contained in the back-end so it can be unit tested.  Eventually, you’ll end up with something like this:

Some of your APIs can have their own data while others rely on the main database.  The monolithic section of your system should start to shrink.  The number of stored procedures should shrink.  This system is already easier to maintain than the complete monolithic system.  You’re still saddled with the monolithic section and the gigantic database with stored procedures.  However, you now have sections of your system that is independent and easy to maintain and deploy.  Another possibility is to do this:

In this instance the front-end is consistent.  One framework with common JavaScript can be contained as a single piece of your system.  This is OK because your front-end should not contain any business logic.

The Front-End

I need to explain a little more about the front-end that many programmers are not aware of.  Your system design goal for the front-end is to assume that your company will grow so large that you’re going to have front-end specialists.  These people should be artists who work with HTML, CSS and other front-end languages.  The front-end designer is concerned with usability and aesthetics.  The back-end designer is concerned about accuracy and speed.  These are two different skill sets.  The front-end person should be more of a graphic designer while the back-end person should be a programmer with knowledge of scalability and system performance.  Small companies will hire a programmer to perform both tasks, but a large company must begin to divide their personnel into distinct skill-sets to maximize the quality of their product.

Another overlooked aspect of the front-end is that it is going to become stale.  Somewhere down the road your front-end is going to be ugly compared to the competition.  If your front-end code is nothing more than HTML, CSS, JavaScript and maybe some frameworks, you can change the look and feel of the user interface with minimum disruption.  If you have HTML and JavaScript mixed into your business logic, you’ve got an uphill battle to try and upgrade the look and feel of your system.

The Back-End

When you connect to a database the common and simple method is to use something like ODBC or ADO.  Then SQL statements are sent as strings with parameters to the database directly.  There are many issues with this approach and the current solution is to use an ORM like Entity Framework, NHibernate or even Dapper.  Here’s a list of the advantages of an ORM:

  1. The queries are in LINQ and most errors can be found at compile time.
  2. The context can be easily changed to point to another database technology.
  3. If you including mappings that match your database, you can detect many database problems at compile time, like child to parent relationship issues (attempt to insert a child record with no parent).
  4. An ORM can break dependency with the database and provide an easy method of unit testing.

As I mentioned earlier, you must avoid stored procedures, functions and any other database technology specific features.  Don’t back yourself into a corner because MS SQL server had a feature that made it easy to use as an enhancement.  If your system is built around a set of stored procedures, you’ll be in trouble if you want to switch from MS SQL to MySQL, or from MS SQL to Oracle.

Summary

I’m hoping that this blog post is read by a lot of entry-level programmers.  You might have seen the three-tier architecture mentioned in your school book or on a website and didn’t realize what it was all about.  Many articles get into the technical details of how to implement a three-tier architecture using C# or some other language, glossing over the big picture of “why” it’s done this way.  Be aware that there are also other multi-tier architectures that can be employed.  Which technique you use doesn’t really matter as long as you know why it’s done that way.  When you build a real system, you have to be aware of what the implications of your design are going to be five or ten years from now.  If you’re just going to write some code and put it into production, you’ll run into a brick wall before long.  Keep these techniques in mind when you’re building your first system.  It will pay dividends down the road when you can enhance your software just be modifying a small API and tweak some front-end code.

 

Dear Computer Science Majors…

Introduction

It has been a while since I wrote a blog posts directed at newly minted Computer Science Majors.  In fact, the last time I wrote one of these articles was in 2014.  So I’m going to give all of you shiny-new Computer Scientists a leg-up in the working world by telling you some inside information about what companies need from you.  If you read through my previous blog post (click here) and read through this post, you’ll be ahead of the pack when you submit your resume for that first career starting job.

Purpose of this Post

First of all, I’m going to tell you my motivation for creating these posts.  In other words: “What’s in it for Frank.”  I’ve been programming since 1978 and I’ve been employed as a software engineer/developer since 1994.  One of my tasks as a seasoned developer is to review submitted programming tests, create programming tests, read resumes, submit recommendations, interview potential developers, etc.  By examining the code submitted by a programming test, I can tell a lot about the person applying for a job.  I can tell how sophisticated they are.  I can tell if they are just faking it (i.e. they just Googled results, made it work and don’t really understand what they are doing).  I can tell if the person is interested in the job or not.  One of the trends that I see is that there is a large gap between what is taught in colleges and what is needed by a company.  That gap has been increasing for years.  I would like to close the gap, but it’s a monstrous job.  So YOU, the person reading this blog that really wants a good job, must do a little bit of your own leg-work.  Do I have your attention?  Then read on…

What YOU Need to Do

First, go to my previous blog post on this subject and take notes on the following sections:

  • Practice
  • Web Presence

For those who are still in school and will not graduate for a few more semesters, start doing this now:

  • Programming competitions
  • Resume Workshops
  • Did I mention: Web Presence?

You’ll need to decide which track you’re going to follow and try to gain deep knowledge in that area.  Don’t go out and learn a hundred different frameworks, twenty databases and two dozen in-vogue languages.  Stick to something that is in demand and narrow your expertise to a level that you can gain useful knowledge.  Ultimately you’ll need to understand a subject well enough to make something work.  You’re not going to be an expert, that takes years of practice and a few failures.  If you can learn a subject well enough to speak about it, then you’re light-years ahead of the average newly minted BS-degree.

Now it’s time for the specifics.  You need to decide if you’re going to be a Unix person or a .Net person.  I’ve done both and you can cross-over.  It’s not easy to cross-over, but I’m proof that it can happen.  If you survive and somehow end up programming as long as I have, then you’ll have experience with both.  Your experience will not be even between the two sides.  It be weighted toward one end or the other.  In my case, my experience is weighted toward .Net because that is the technology that I have been working on more recently.

If you’re in the Unix track, I’m probably not the subject expert on which technologies you need to follow.  Python, Ruby, which frameworks, unit testing, you’ll need to read up and figure out what is in demand.  I would scan job sites such as Glass Door, Indeed, LinkedIn, Stack Exchange or any other job sites just to see what is in demand.  Look for entry level software developer positions.  Ignore the pay or what they are required to do and just take a quick tally of how many companies are asking for Python, PHP, Ruby, etc.  Then focus on some of those.

If you’re in the .Net track, I can tell you exactly what you need to get a great paying job.  First, you’re going to need to learn C#.  That is THE language of .Net.  Don’t let anybody tell you otherwise.  Your college taught you Java?  No problem, you’re language knowledge is already 99% there.  Go to Microsoft’s website and download the free version of Visual Studio (the community version) and install it.  Next, you’ll need a database and that is going to be MS SQL Server.  Don’t bother with MS Access.  There is a free version of SQL as well.  In fact the developer version is fully functional, but you probably don’t need to download and install that.  When you install Visual Studio the Express version of SQL is normally installed with it.  You can gain real database knowledge from that version.

Follow this list:

  • Install Visual Studio Community.
  • Check for a pre-installed version of MS SQL Server Express.
  • Go out and sign up for a GitHub account.  Go ahead, I’ll wait (click here).
  • Download and install SourceTree (click here).

Now you have the minimum tools to build your knowledge.  Here’s a list of what you need to learn, using those tools:

  • How to program in C# using a simple console application.
  • How to create simple unit tests.
  • Create an MVC website, starting with the template site.
  • How to create tables in MS SQL Server.
  • How to insert, delete, update and select data in MS SQL Server.
  • How to create POCOs, fluent mappings and a database context in C#.
  • How to troubleshoot a website or API (learn some basic IIS knowledge).
  • How to create a repository on GitHub.
  • How to check-in your code to GitHub using SourceTree.

That would pretty much do it.  The list above will take about a month of easy work or maybe a hard-driven weekend.  If you can perform these tasks and talk intelligently about them, you’ll have the ability to walk into a job.  In order to seal-the-deal, you’ll have to make sure this information is correctly presented on your resume.  So how should you do that?

First, make sure you polish your projects and remove any commented code, remove any unused or dead-code.  If there are tricky areas, put in some comments.  Make sure you update your “Read-Me” file on GitHub for each of your projects.  Put your GitHub URL near the top of your resume.  If I see a programmer with a URL to a GitHub account, that programmer has already earned some points in my informal scale of who gets the job.  I usually stop reading the resume and go right to the GitHub account and browse their software.  If you work on a project for some time, you can check-in your changes as you progress.  This is nice for me to look at, because I can see how much effort you are putting into your software.  If I check the history and I see the first check-in was just a blank solution followed by several check-ins that show the code being refactored and re-worked into a final project, I’m going to be impressed.  That tells me that you’re conscious enough to know to get your code checked-in and protected from loss immediately.  Don’t wait for the final release.  Building software is a lot like producing sausage.  The process is messy, but the final product is good (assuming you like sausage).

If you really want to impress me and by extension, any seasoned programmer, create a technical blog.  Your blog can be somewhat informal, but you need to make sure you express your knowledge of the subject.  A blog can be used as a tool to secure a job.  It doesn’t have to get a million hits a day to be successful.  In fact, if your blog only receives hits from companies that are reading your resume, it’s a success.  You see, the problem with the resume is that it doesn’t allow me to into your head.  It’s just a sheet of paper (or more if you have a job history) with the bare minimum information on it.  It’s usually just to get you past the HR department.  In the “olden” days, when resumes were mailed with a cover letter, the rule was one page.  Managers would not have time to read novels, so they wanted the potential employee to narrow down their knowledge to one page.  Sort of a summary of who you are in the working world.  This piece of paper is compared against a dozen or hundreds of other single-page resumes to determine which hand-full of people would be called in to be interviewed.  Interviews take a lot of physical time, so the resume reading needs to be quick.  That has changed over the years and the rules don’t apply to the software industry as a whole.  Even though technical resumes can go on for two or more pages, the one-page resume still applies for new graduates.  If you are sending in a resume that I might pick up and read, I don’t want to see that you worked at a Walmart check-out counter for three years, followed by a gig at the car wash.  If you had an intern job at a tech company where you got some hands-on programming experience, I want to see that.  If you got an intern with Google filing their paperwork, I don’t care.

Back to the blog.  What would I blog about if I wanted to impress a seasoned programmer?  Just blog about your experience with the projects you are working on.  It can be as simple as “My First MVC Project”, with a diary format like this:

Day 1, I created a template MVC project and started digging around.  Next I modified some text in the “View” to see what would happen.  Then I started experimenting with the ViewBag object.  That’s an interesting little object.  It allowed me to pass data between the controller and the view.

And so on…

Show that you did some research on the subject.  Expand your knowledge by adding a feature to your application.  Minor features like, search, column sort, page indexing are important.  It demonstrates that you can take an existing program and extend it to do more.  When you enter the working world, 99% of what you will create will be a feature added to code you never wrote.  If your blog demonstrates that you can extend existing code, even code you wrote yourself, I’ll be impressed.

Taking the Test

Somewhere down the line, you’re going to generate some interest.  There will be a company out there that will want to start the process and the next step is the test.  Most companies require a programming test.  At my point in my career the programming test is just an annoyance.  Let’s call it a formality.  As a new and inexperienced programmer, the test is a must.  It will be used to determine if you’re worth someone’s time to interview.  Now I’ve taken many programming tests and I’ve been involved in designing and testing many different types of programming tests.  The first thing you need to realize is that different companies have different ideas about what to test.  If it was up to me, I would want to test your problem solving skills.  Unfortunately, it’s difficult to test for that skill without forcing you to take some sort of test that may ask for your knowledge in a subject that you don’t have.  I’ve seen tests that allow the potential hire to use any language they want.  I’ve also seen tests that give very gray specifics and are rated according to how creative the solution is.  So here are some pointers for passing the test:

  • If it’s a timed test, try to educate yourself on the subjects you know will on the tests before it starts.
  • If it’s not a timed test, spend extra time on it.  Make it look like you spent some time to get it right.
  • Keep your code clean.
    • No “TODO” comments.
    • No commented code or dead-code.
    • Don’t leave code that is not used (another description for dead-code).
    • Follow the naming convention standards, no cryptic variable names (click here or here for examples).
  • If there is extra credit, do it.  The dirty secret is that this is a trick to see if you’re going to be the person who does just the minimum, or you go the extra mile.
  • Don’t get too fancy.
    • Don’t show off your knowledge by manually coding a B-tree structure instead of using the “.Sort()” linq method.
    • Don’t perform something that is obscure just to look clever.
    • Keep your program as small as possible.
    • Don’t add any “extra” features that are not called for in the specification (unless the instructions specifically tell you to be creative).

When you’re a student in college, you are required to analyze algorithms and decide which is more efficient in terms of memory use and CPU speed.  In the working world, you are required to build a product that must be delivered in a timely manner.  Does it matter if you use the fastest algorithm?  It might not really matter.  It will not make a difference if you can’t deliver a working product on time just because you spent a large amount of your development time on a section of code that is only built for the purpose of making the product a fraction faster.  Many companies will need a product delivered that works.  Code can be enhanced later.  Keep that in mind when you’re taking your programming test.  Your program should be easy to follow so another programmer can quickly enhance it or repair bugs.

The Interview

For your interview, keep it simple.  You should study up on general terms, in case you’re asked.  Make sure you understand these terms:

  • Dependency injection
  • Polymorphism
  • Encapsulation
  • Single purpose
  • Model/View/Controller
  • REST
  • Base Class
  • Private/public methods/classes
  • Getters/Setters
  • Interface
  • Method overloading

Here’s a great place to do your study (click here).  These are very basic concepts and you should have learned them in one of your object oriented programming classes.  Just make sure you haven’t forgotten about them.  Make sure you understand the concepts that you learned from any projects that you checked into GitHub.  If you learned some unit testing, study the terms.  Don’t try to act like an expert for your first interview.  Just admit the knowledge that you have.  If I interview you and you have nothing more than a simple understanding of unit testing, I’m OK with that.  All it means is that there is a base-line of knowledge that you can build on with my help.

Wear a suit, unless explicitly specified that you don’t need one.  At a minimum, you need to dress one step better than the company dress policy.  I’m one of the few who can walk into an interview with red shoes, jeans and a technology T-shirt and get a job.  Even though I can get away with such a crazy stunt, I usually show up in a really nice suit.  To be honest, I only show up in rags when I’m Luke-warm about a job and I expect to be wooed.  If I really like the company, I look sharp.  The interviewers can tell me to take off my tie if they think I’m too stuffy.  If you’re interviewing for your first job, wear a business suit.

Don’t BS your way through the interview.  If you don’t know something, just admit it.  I ask all kinds of questions to potential new hires just to see “if” by chance they know a subject.  I don’t necessarily expect the person to know the subject and it will not have a lot of bearing on the acceptance or rejection of the person interviewing.  Sometimes I do it just to find out what their personality is like.  If you admit that you know SQL and how to write a query, I’m going to hand you a dry-erase marker and make you write a query to join two tables together.  If you pass that, I’m going to give you a hint that I want all records from the parent table to show up even if it doesn’t have child records.  If you don’t know how to do a left-outer join, I’m not going to hold it against you.  If you are able to write a correct or almost correct left join, I’ll be impressed.  If you start performing a union query or try to fake it with a wild guess, I’ll know you don’t know.  I don’t want you to get a lucky guess.  I’m just trying to find out how much I’m going to have to teach you after you’re hired.  Don’t assume that another candidate is going to get the job over you just because they know how to do a left outer join.  That other candidate might not impress me in other ways that are more important.  Just do the best you can and be honest about it.

Don’t worry about being nervous.  I’m still nervous when I go in for an interview and I really have not reason to be.  It’s natural.  Don’t be insulted if the interviewer dismisses you because they don’t think you’ll be a fit for their company.  You might be a fit and their interview process is lousy.  Of course, you might not be a fit.  The interviewer knows the company culture and they know the type of personality they are looking for.  There are no hard-fast rules for what an interviewer is looking for.  Every person who performs an interview is different.  Every company is different.

What Does a Career in Software Engineering Look Like

This is where I adjust your working world expectations.  This will give you a leg-up on what you should focus on as you work your first job and gain experience.  Here’s the general list:

  • Keep up on the technologies.
  • Always strive to improve your skills.
  • Don’t be afraid of a technology you’ve never encountered.

Eventually you’re going to get that first job.  You’ll get comfortable with the work environment and you’ll be so good at understanding the software you’ve been working on that you won’t realize the world of computer programming has gone off on a different track.  You won’t be able to keep up on everything, but you should be able to recognize a paradigm shift when it happens.  Read.  Read a lot.  I’m talking about blogs, tech articles, whatever interests you.  If your company is having issues with the design process, do some research.  I learned unit testing because my company at the time had a software quality issue from the lack of regression testing.  The company was small and we didn’t have QA people to perform manual regression testing, so bugs kept appearing in subsystems that were not under construction.  Unit testing solved that problem.  It was difficult to learn how to do unit testing correctly.  It was difficult to apply unit testing after the software was already built.  It was difficult to break the dependencies that were created from years of adding enhancements to the company software.  Ultimately, the software was never 100% unit tested (if I remember correctly, it was around 10% when I left the company), but the unit tests that were applied had a positive effect.  When unit tests are used while the software is being developed, they are very effective.  Now that the IOC container is main-stream, dependencies are easy to break and unit tests are second nature.  Don’t get complacent about your knowledge.  I have recently interviewed individuals who have little to no unit testing experience and they have worked in the software field for years.  Now they have to play catch-up, because unit testing is a requirement, not an option.  Any company not unit testing their software is headed for bankruptcy.

APIs are another paradigm.  This falls under system architecture paradigms like SOA and Microservices.  The monolithic application is dying a long and slow death.  Good riddance.  Large applications are difficult to maintain.  They are slow to deploy.  Dependencies are usually everywhere.  Breaking a system into smaller chunks (called APIs) can ease the deployment and maintenance of your software.  This shift from monolithic design to APIs started to occur years ago.  I’m still stunned at the number of programmers that have zero knowledge of the subject.  If you’ve read my blog, you’ll know that I’m a big fan of APIs.  I have a lot of experience designing, debugging and deploying APIs.

I hope I was able to help you out.  I want to see more applicants that are qualified to work in the industry.  There’s a shortage of software developers who can do the job and that problem is getting worse every year.  The job market for seasoned developers is really good, but the working world is tough because there is a serious shortage of knowledgeable programmers.  Every company I’ve worked for has a difficult time filling a software developer position and I don’t see that changing any time in the near future.  That doesn’t mean that there is a shortage of Computer Science degrees graduating each year.  What it means is that there are still too many people graduating with a degree that just to measure up.  Don’t be that person.

Now get started on that blog!