Working Effectively with Legacy Code by Michael Feathers is a key resource for anyone who has to work with less-than-pleasant code. Feathers defines legacy code as code without tests, and his main goal is to get automated tests in place. The last section of the book contains a catalog of dependency-breaking techniques to make this possible.
Examples are in Java, C++, C and C# (plus one in Ruby). C and C++ developers will likely find this book invaluable, as a number of the techniques target challenges in those languages.
The book is very readable, due in large part to the friendly writing style of Mr. Feathers. Experienced developers will smile (or perhaps shudder in remembrance) at section names like “The Case of the Irritating Global Dependency.” Most code examples are short and to the point, although it does help if the reader is conversant in at least one C-style language.
The text suffers from the occasional typographical error, which I found distracting.
Developers who do not see value in automated tests may find little of interest in this book. If you don’t fall into that category, order your copy today!
With all the discussions of software craftsmanship and SOLID principles lately, I’d like to list the guidelines (not absolute rules!) I find most useful. These are listed in order of importance, highest to lowest.
Key Principles and Practices of Software Development
Frequent Anti-patterns of Software Development
Remember that the right answer is often “it depends.” Almost everything is a trade-off. Use your own judgment. Think!
Thanks to everyone who reviewed my initial draft, and to Robert ("Uncle Bob") Martin for inspiration.
Comments are welcome.
I have a great deal of respect for “Uncle” Bob Martin. He’s done a tremendous amount to bring professionalism and craftsmanship to software development. I’ve heard him speak, and he definitely knows more than I do. But in this one small area of programming, I think he’s off-target. Decide for yourselves.
Dependency Injection Inversion (Uncle Bob)
Some of the follow-ups:
Poor use of DI versus need for DI (Jimmy Bogard)
Dependency Injection Inversion Rejection (Davy Brion)
Constructor over-injection anti-pattern (Jeffrey Palermo)
I agree most closely with Jimmy Bogard on this (Davy Brion makes some good points too). In Jeffrey Palermo’s post, I side with Alwin in his comment - why not just pass an interface to the factory?
EDIT: Here’s a nice rebuttal to Jeffrey Palermo’s post that discusses better alternatives to Alwin’s solution:
Rebuttal: Constructor over-injection anti-pattern (Mark Seemann)
EDIT: Another response to Uncle Bob:
Rejecting Dependency Injection Inversion (Ayende)
EDIT: And another related post by Mark Seemann:
Dependency Injection Inversion in .NET
EDIT: Yet another interesting post by Mr. Seemann (I think I’ll pick up his book):
I finally got tired of the “Connecting…” message and associated delay when starting Internet Explorer 8, and did some searching. This worked for me; your mileage may vary. No warranties.
In IE 8:
Tools/Manage Add-Ons
Toolbars and Extensions
Select Java™ Plug-In 2 SSV Helper
Disable (OK if disables other helper)
Close
Tools/Internet Options
General
Under the “Tabs” section, click Settings
When a new tab is opened, open: A blank page
OK
These were two of the links that helped me find this info:
https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=366238
I wrote my first real AutoHotkey script yesterday. I’ve been using the program for a week or so to provide keyboard macros, but I wanted a way to list all of my hotstrings (abbreviation-expanders).
I set up my hotstrings to start with two dots (..) and to not require an ending character (like space or tab). So if I type “..e” it will be replaced with my email address. That’s set up as:
:c*:..e::myemail@my.domain
Here’s my first cut at a macro to list the hotstrings in the current script. I haven’t found a way to get at the metadata for this yet, so I’m loading the current script file as text and parsing it with regular expressions. Note that this does not depend upon my two-dot convention. It does have to be in the same file as the hotstrings, though. I don’t list the expansion text, as that can get pretty long (snippets of SQL, etc.).
; == HOTKEYS ==
#H::
; Windows + H: Display all Hotstrings
FileRead, ScriptContents, %A_ScriptFullPath%
if not ErrorLevel
{
AllHotstrings := ""
Loop, parse, ScriptContents, `n, `r
{
if (RegExMatch(A_LoopField, "^:.*?:(.+?)::", SubPat))
{
AllHotstrings := AllHotstrings . SubPat1 . "`n"
}
}
MsgBox 0, Hotstrings, %AllHotstrings%
}
return :: Next Page >>
Development Central is the blog of Bill Sorensen, a professional software developer. Much of this will relate to C#, .NET, and OOP in general.
Disclaimer
These postings are provided "AS IS" with no warranties and confer no rights.
| Next >