I was recently catching up on some articles from the Code Better RSS feed and came across this Foundations of Programming eBook, which is essentially a composition of a number of Karl Seguin's posts on the code better site all neatly presented in an eBook, best of all it's free. I had missed many of Karl's original posts so I decided to download it, take a look and give it a quick review if anyone is interested.
Chapter 1: ALT .NET - this chapter gives quite a nice overview of what ALT .NET is all about, why it exists and where it fits within the community. It also contains some explanations for all of those little acronyms and terms that you hear bouncing around all over place, items such as YAGNI (You Aren't Going to Need It!) and DRY (Don't Repeat Yourself), Coupling, Last Responsible Moment.
Chapter 2: Domain Driven Design - a brief introduction into what DDD is and how it differs from Data-Centric design. Karl uses very simple code samples to get his point across but these do the job well and the tips and tricks section is well worth a read to refresh your knowledge on typical patterns and practices you should be following when developing software applications.
Chapter 3 - Persistence - it seems that the concept of persistence and persistence ignorance is a bit of a buzz word at the moment, what with various discussions about Entity Framework vs NHibernate etc (just Google these terms and you'll come up with some discussion or another). In this chapter Karl neatly summarises the main issue in-hand i.e. the Object-Relational Impedance Mismatch and continues to discuss the use of Data Mappers and, with the use of some example code, highlights the drawbacks of using manual mapping (hand writing the code to perform the mapping of relational to object data), which had I not been convinced of already, this chapter would have pushed me to look for alternatives. I think the title of this chapter is a little misleading as it does mainly focus on manual data mapping and I was expecting the chapter to go into more details about other persistence mechanisms available, I'll keep reading and see where it takes me.
Chapter 4 - Dependency Injection - this section discusses the balance between decoupling and coupling of items within an application, introduces the concept of unit testing which requires at least some form of decoupling and details how the Dependency Injection pattern can be used. The chapter also focuses on the StructureMap dependency injection tool written by fellow CodeBetter blogger Jeremy Miller, there are plenty of other DI frameworks out there such as Castle Windsor, Unity, ObjectBuilder each has their own pro's and con's so I leave it to you to make a decision on which might be the most preferable for your situation.
Chapter 5 - Unit Testing - the previous chapter briefly introduced unit testing as a way of introducing the need for decoupling within a system, this section delves a little more into unit testing and why should we use it, I especially liked the section on "Why Wasn't I Unit Testing 3 Years Ago?" which rang very true to me. Karl then goes on to discuss unit testing and the tools you need to do it, these include NUnit, TestDriven .NET and RhinoMocks and he details simple some code examples to give the reader and idea of the kind of things you can do with them.
One point worthy of note is that Karl mentions that UI testing "is complicated and suffers from very tight coupling" which is true, but I would definitely recommend looking into integrating WatiN into your continuous integration build process, the tests are not be as fast as unit tests so you may want to use them in a separate build process but I believe that can be equally invaluable to ensure the UI meets the needs of the user.
Also, when it comes to testing of the database, I have recently found some success in using a LINQ to SQL data context which exposes the stored procedures within the database can be extremely useful for testing individual stored procedures and ensuring they perform as expected (may be I'll do a blog about that some day).
Chapter 6 - Object Relational Mappers - starting head on with details about the Stored Procedures vs Inline SQL debate, Karl explains some of the key points involved in this discussion and argues the reasons for inline SQL over stored procs which leads on to the use of an object relational mapping tool. I for one agree with Karl's arguments and believe that the use of an O/R Mapper should be a developers first port of call and then stream line to use stored procs when bottle necks appear. The chapter then moves on and describes how to configure and use NHibernate for your O/R Mappings, recently I have had a lot of experience of LINQ to SQL and I find this to be pretty useful even though it probably lacks a level of abstraction that tools such as NHibernate would provide, it certainly does the job if your just focusing of SQL Server databases in a smallish application.
Chapter 7 - Back to Basics: Memory - I personally believe every developer should read this section even if its just to recap your knowledge on these items, it's always good to keep an idea of what the memory usage of your application in your mind even when in a managed environment. Karl covers all of the areas you would expect to see such as Boxing, ByRef, Managed Memory Leaks, Fragmentation and Pinning and the use of IDisposable. The chapter is relatively brief considering the subject matter but it is easy to read and digest, compared to CLR via C# (I book I would thoroughly recommend you get if you haven't got it already) Karl's is a lot more lightweight but serves the purpose of getting developers thinking about the things that matter.
Chapter 8 - Back to Basics: Exceptions - the suggested exception handling is simply two rules 1) Only handle exceptions that you can actually do something about, and 2) You can't do anything about the vast majority of exceptions and Karl goes on to state that "Most new developers do the exact opposite of the first rule, and fight hopelessly against the second. I believe he is right, exception handling can actually be quite an overwhelming concept and developers can easily be too defensive when dealing with them. Karl continues to highlight what to do when handling exceptions that you can do something with also asserts that exception swallowing is bad. The chapter continues to detail how to throw exceptions and the subtle differences this can have on the stack trace, when to throw exceptions i.e. in exceptional circumstances or when expected behaviour cannot be executed. Finally, the chapter rounds up with a section on custom exceptions.
Chapter 9 - Back to Basics: Proxy This and Proxy That - the chapter looks inheritance and polymorphism in terms of the Proxy Domain Pattern and how this is used within NHibernate to handle lazy loading of objects. There is an interesting side note about NHibernate which is that it is considered to be a frictionless or transparent O/R Mapper because it doesn't require modification of any of your domain classes, although if you require lazy loading then you must mark all of your methods as virtual but you still don't have to add NHibernate specific constructs to your classes. The chapter then turns into a discussion about the lazy loading capabilities of NHibernate and how the proxy pattern is used to achieve this. The intention of the chapter was to make the reader think about what methods should and shouldn't be virtual, I am not sure whether this was achieved but it certainly got me thinking a little bit more about looking into NHibernate.
Chapter 10 - Wrapping It Up - this final chapter simply summarises the contents of the eBook and Karl gives what I consider to be a good list of core principles to good software engineering, I have summarised these as follows (see the eBook for more detail):
- The most flexible solution is the simplest (YAGNI, DRY, KISS and explicitness)
- Coupling is unavoidable, but must be minimised
- You are responsible for the code you write, test your code because this helps you identify bad coupling, find awkwardness in your API, document behaviour and expectations, and lets you make small and radical changes with far greater confidence and far less risk
- It's more fun developing projects using agile and iterative development
- Always look for alternatives and learn all of the time
I must say I really enjoyed reading this eBook, so much so that it inspired me to write this review of it. At only 79 pages it is manageable and IMO makes some absolutely valid points about how to "Code Better", reading this eBook will be a great learning aid for those wanting to progress their programming knowledge and a stark reminder for those with a greater knowledge that it is always worth reminding yourself of your coding principles, practices and understanding of the underlying framework that you work with everyday.
The eBook has opened my eyes to the way of the ALT .NETer and I am now far more interested in learning about NHibernate and how it could make my life as a programmer a better place to be. Some might say that the focus on NHibernate should not be considered as a "Foundation of Programming" but the principles that lie behind the development of NHibernate certainly should be. All in all I would definitely recommend reading this eBook when you have a spare 5 minutes.