About the future.
Look out of a window. All those cars that you see there, they all have software. Think about it. This should terrify you. Sooner or later a day will come when software bug will cause hundreds of people to die. Politicians will step in and ask why we didn't prevent it. We should have an answer ready. Otherwise, they will impose rules on us - use only this language, or that construct. They already disallow dynamic memory allocation for airplane software.
About TDD.
Software is fragile. If you take a piece of software, it is possible to find a bit that if you flip its value, a software will crash. Most engineers do not have the same problem: if you take a brick out of the building, it will not fall down. There is, however, another industry that has similar problem - a mistake in a single digit for an accountant may cause a company to go bankrupt. The solution that accountants have been using for 500 years is double-entry bookkeeping. TDD is our double-entry bookkeeping. Accountants have managers too, and they have deadlines. But they never say, "OK, today I will register only debits, and after the deadline I will go and fix all the credits (since it is possible to recreate those based on registered debits)".
About functional programming.
There is no assignment in functional programming. Is it good? Well, no assignment, no concurrent update problem. Manufacturers can't increase the speed of a single CPU any more, so they started to put more cores. Imagine a machine with 128 cores. Or 1024 cores. Will the OS make sure that no concurrent updates are possible? Maybe yes, maybe not. But functional programs can.
About DLL and project decomposition.
We invented DLLs to be able to compose application from components that can be deployed independently. Do you follow this rule when you decompose your application into a set of DLLs? [Note: that is why interfaces should be part of an application DLL, but implementations can live in different DLLs].
About stable and unstable components and UI automation.
Components that have many incoming dependencies are stable and independent. Components that have many outgoing dependencies are unstable and dependent. The more stable the component is, the more abstractions it has to have. The more unstable the component is, the more concrete classes it usually has. UI has many outgoing dependencies. Hence, it is unstable. Do you write tests via UI? Well, then you base something that has to be stable on something that is unstable.
About architecture.
Good architecture defers important decisions (e.g. which database to use). Web is only a delivery mechanism and thus architecture should not be build around the fact that application is a web application. Database is a detail, and architecture should not be build around the fact that application uses database to store content.http://www.linkedin.com/in/oldbam