Some Guiding Principles for Software Development
Patrick Cauldwell is one of the architects on our Next Generation Banking System. A while back I asked him to write up our guiding principles for not only educating new developers but also for indoctrinating existing team members into our world view. He published it on his blog as This I Believe...The Developer Edition.
It's a great list. Here's a partial listing of the first two levels of his outline. Be sure to visit his post for the complete outline. It's bent towards .NET, because the stuff he's doing is .NET, but the general ideas are usable elsewhere.
- Our "guiding principles"
- Test Driven Development
- Continuous Integration
- Unit Tests
- Two kinds of tests
- Automation is equally possible for both sets of tests
- All UI development should follow the MVP pattern for ease of testing
- Test Coverage
- 90%+ is the goal
- NCover runs as part of the build, and reports are generated
- Buy, Not Build
- Take full advantage of the platform, even if it only solves the 80% case
- Don't write a single line of code you don't have to
- Take full advantage of .NET 3.0, SQL 2005, Windows 2003 Server, plan for- and test on Longhorn.
- Don't invent new solutions to solved problems.
- Limit compile time dependencies on code you don't own
- Everything not owned by us should be behind an interface and a factory method
- Define your data contracts in C# (think "active record")
- All persistent storage should be abstracted using logical interfaces
- Fewer assemblies is better
- There should be a VERY good reason for creating a new assembly
- The assembly is the smallest deployable unit, so it's only worth creating a new assembly if it means NOT shipping something else
- Namespace != assembly name. Roll up many namespaces into one physical assembly if they all must be deployed together.
- Only the public interface should be public
- Only make classes and interfaces public if absolutely necessary
- Test code should take advantage of InternalsVisibleTo attributes
- VS 2005 defaults to creating internal, not public classes for a reason
- If it's public, you have to support it for ever
- Windows authentication (good)
- Just say no to connection strings
- Windows authentication should be used to talk to SQL, ADAM, the file system, etc.
- You can take advantage of impersonation without impersonating end users
- Tracing
- Think long and hard about trace levels
- Use formatted resource strings everywhere for localization
- For critical, error, or warning, your audience is not a developer
- Error Handling
- Method names are verbs
- If anything breaks the contract, throw an exception
- The definition of "done" (or, how do I know when a task is ready for QA?)
- Any significant design decisions have been discussed and approved by the team
- For each MyClass, there is a corresponding MyClassFixture in the corresponding test assembly
- MyClassFixture exercises all of the functionality of MyClass (and nothing else)
- Code coverage of MyClass is >=90%, excluding only lines you are confident are unreasonable to test
- No compiler warnings are generated by the new code
- Before committing anything to source control, update to get all recent changes, and make sure all unit and integration tests pass
- FxCop should generate no new warnings for your new code
- Compiling with warnings as errors will flush out any place you forgot documentation comments, which must be included for any new code
What guiding principles do you follow at your development shop?
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
this is arguable I mean. There are good reason not to use Window authentication for sql database
That is a great list! Each bullet is a principle worth serious consideration for any kind of programmer.
One thought about Fred's comment:
There are good reason not to use Window authentication...
In some circumstances, I think Fred is right. In an ASP.NET scenario, ASP.NET has no way of forwarding user credentials because of limitations to NTLM (Windows) Authentication. This can be problematic if your services span several machines, such as having a Microsoft Exchange Server on a separate machine than the website. Some services might simply be unavailable using only Windows Authentication.
I think, though, that in nearly every circumstance, Windows authentication is the way to go. This is especially true if the application must live on someone's desktop instead of the server. Even if encrypted, giving clients physical access to a file containing a connection string is asking for trouble.
Never stop writing, Scott. You're well appreciated!
Many programmers talk up the MVP model, but every time I start trying to read up on it, I always think, "Am I the only one who doesn't get this?" I think "ease of testing" should be balanced against "ease of development" and "ease of future support by other developers."
Scott -- how about a podcast on MVP? I'd love to use it, but it just hasn't clicked yet -- and I think I'm not alone in this.
Besides wouldnt it be better to have your code seperated out more in different assemblies especially if multiple teams on it. At least during the development phase. Could you talk about that sometime in a podcast to?
Also
Lets assume that it would be cheaper to not buy code? For example a 2000 dollar printing suite for reports when you know one of your capable jr programmers could program the basic functionality I know. Don't you find a blanket statement like this to be not cost effective.
With the lack of good documentation from even major vendors, could this practice leave a development team very much delayed.
This new approach of all programming(coding) is bad. Does this lead to a lack of refactoring of existing code?
Im also curious to how much of the day writing unit tests take up for a developer on your team?
If I have time I'll try and post an example that doesn't suck. :)
In other cases, to generate PDF's a component may work great for many years, for example, but then you need one property to set to generate the PDF with signed and protected, then all of the sudden, you need to shell out $1,800 each for 20 servers and again for 10 more developers, but when you finally do so and apply the updated version to all of your servers, existing functionality breaks and you must spend days correcting the differences in versions.
For us, it has served our company well in minimize 3rd party dependancies and we must provide a strong justification for actually using them. Our developers are talented enough that it isn't a drain on finance to create it ourselves, which is what we've done, and almost every problem we had with previous 3rd party vendors has dissappeared, in exchange for having a slightly longer target release date, but the quality of our deliverables is also acceptable.
Personally, my belief is that whether you stake the existance of your business on whether or not 3rd parties can keep pace with your requirements proportionately depends on how critical your product is to your company's survival. The part of about placing 3rd party dependencies behind a factory or proxy interface is sound. One which we haven't even considered but I will put some thought into that as it might help to keep a familiar interface but allow a switch to new toolkits in the future if necessary.
Thanks,
Shawn
re unit testing and 90% coverage: do you kids recommend unit tests for private methods? I've seen some great discussions of this recently -- and wondered what the hanselstance was on this one?
lb
>> ASP.NET has no way of forwarding user credentials because of limitations to NTLM (Windows) Authentication.
This is partly correct. ASP.NET has no way of forwarding credentials if you are using NTLM, but ASP.NET can pass credentials when you use Kerberos and delegation, allowing you to still use integrated authentication in multi-hop scenarios.
Could you link to those discussions, here or on your blog? I'd be very interested.
To give my own unsolicited answer: I'm in the "test public interface period" camp. The rationale is that the existence of private methods is an implementation detail you don't want to couple your tests to, because it leads to severe test osteoporosis. Broken encapsulation will lead to a broken hip every time.
http://polymorphicpodcast.com/shows/mv-patterns/
It is really good because it is a simple, short demo that for the most part focuses solely on the MVP issue, and doesn't complicate things with data access or other pieces you would find in a real project. Just following the walkthrough and typing in the code myself helped me figure it out pretty easily. In a larger "real world type" project you can lose the pattern in everything else that is going on. For someone like me lacking experience with MVP, better to start with the simplest possible example like this one.
I have to say I'm not yet convinced that MVP is the way to do +all+ UI's, but I do see its value.
I still don't fully grok the pattern because I haven't yet had enough hands on experience with it, but I understand the concepts and see the benefits the pattern provides.
In the end, you should see bunches of projects/dlls which go together, while between the bunches there is almost no dependence whatsoever. The boundaries between bunches will almost always be an interface project/dll.
This will have the pleasant side-effect of enabling concurrent development of bunches with developers hardly ever stepping on each other’s toes. Actually, the number of projects in a given developer’s solution will probably decrease, since they no longer have to deal with all parts of the system.
You're absolutely right.
Unless the developers sit on different floors of the same building, or different building, cities, time zones, etc.
I've scaled up and down the "many assemblies" approach and have found it doesn't create much overhead even at the single team level compared to code-and-merge techniques.
- The code should compile
- Have a simple design with fewest classes
- Be well factored - have no duplication
- Structured in accordance with coding standards
- Well documented
- Communicate the developer’s intentions
- Checked into the version control repository
- Integrated and build successfully.
- Unit tests must pass
- Code coverage >85%
Some of points are fuzzy and can’t be measured, but the force the developers thing about it.
Comments are closed.
They all generally sound pretty good, personally I've never found a good reason to use fx cop(but thats probably just me).
Could you confirm that the below doesn't refer to those horribly wizards or draggy drop tools in visual studio?
"Don't write a single line of code you don't have to"
Andy