We know that nowadays the systems are designed as web applications. Every imaginable system is either converted or planned to be converted to a web app.
Huh?
While web apps are certainly quite popular and useful, they are by no means the be-all-end-all. Here are some cases where web apps are a poor choice and a "desktop" app would be a much better fit:
- Intensive client side computation. Imagine a team of 50 astrophysicists all working together plotting an extremely intricate spacefaring mission. Now imagine that their equation system solving tool (e.g. WolframAlpha) is a web app. Do you really want a queue of jobs that each take minutes or hours to compute sitting around on the webserver? And consider that most of these jobs are going to be interim results, not the final answer, so many calculations need to be performed in a serial fashion. A web app would destroy productivity; calculate on the client and only push end results.
- Complicated or cascading validation rules. As a user, if I have to make 20 or 30 calls out to the webserver for validation checks when entering data, I'm going to get impatient with the app very quickly, even if each call only takes tens of milliseconds. Additionally, if the business objects are in C#, it's really aggravating to have to reproduce (and test) all the validation logic in JavaScript. A fat client prevents that code duplication and reduces user wait time.
- Very high levels of security. Say a classified government facility wants to pre-encrypt all data before any transmission or storage occurs. Tightly securing data through a web application is difficult. A web app has a greater attack surface than a desktop app. And then the webserver has to decrypt the data, perform its operations, then encrypt again before storage. Or the client could do everything and push the finished encrypted data to the DB.
- Minimizing maintenance and resource usage. A web app means you need a web server. But say the requirement is for a simple CRUD app that's only used in a single physical office, and the app rarely if ever changes. The users don't care if they're looking at a browser or a locally installed executable. Why complicate things by adding unnecessary components? Removing the web server from the equation makes the system simpler (meaning less chance of breakage), and reduces server and bandwidth usage.
In (very simplified) terms of three tiered architecture, the difference between a "web" and "desktop" app is where you put the middle tier: client side or server side. All of the examples above support three tiers, despite having only two physical machines (a client and a DB), because there's a difference between logical and physical tiers. If it helps, you can initially think of them as focusing on two different domains: design and deployment. Understanding these differences is an important part of system architecture and design.
Say I have a web app and find that users in Europe heavily consume a particular critical service, but the US users almost never use it. My web app servers are located in the US and can't be moved. If my middle logical tier is tied to my web app's servers, I can't break out the service and move it to a different physical location to improve EU performance. But if things are logically separated properly, I can change the physical middle tier without affecting the system's logical architecture at all.
To me, the middle tier is not actually the middle tier because regardless of how isolated the design is and how stateless the DLLs are, they execute in the context of a web server only and essentially a part of the web application.
You're conflating physical and logical tiers. If your middle tier is part of the context of the web server, then you don't really have a middle tier; you have a complex web app and a DB. If it simply resides there, then you have three logical but two physical tiers.
Is it correct to design the apps this way when there is no technical middle layer, even the applications that require heavy processing?
The only possible answer to this is "it depends", specifically on the requirements and use cases. You have a simple CRUD app? Then a middle tier probably isn't necessary (either physically or logically). Even my "heavy processing" example above functions fine on two physical tiers. But here's a real world example I worked on which would have been impossible without a middle tier: a very big client had many users in many different countries who needed many different reports. Different reports accessed different DBs and had different processing and run time requirements. So we used a middle tier which created and managed a job queue and generated the reports. Key points about why a middle tier was important:
- It provided an abstract interface to the UI tier, easily able to be consumed by web or desktop apps (we had both).
- It made it easy to make priority and scheduling decisions about which data to fetch from the DB and when. We had some very contentious tables, and blindly submitting many large requests for report data would kill performance.
- It did work which was impossible to accomplish on the other two logical tiers. The DBs couldn't generate the reports and the clients couldn't manage the queue.
- It saved doing work on the other two physical tiers. We had a lot of data which needed to be globally accessible, so pushing all of it to the client and generating the report there was not feasible. We also had very busy DBs; the DBAs would have murdered us if we'd cut out a chunk of the servers' resources for executing middleware on a VM or demanded a bunch of complicated, resource intensive jobs to run a custom queue.
Current is the only option for middle tier for a web app is a windows Service and nothing else?
Not at all. Your middle tier can be designed and deployed as almost whatever you want it to be, as long as it sits between and is distinct from the client and storage tiers. Web services, console apps, Linux servers... the list goes on.