Ok, I have been sitting on this post for probably 6 months. Once you see what it is you'll understand why I sat on it this long (Consider where I just came from).
I have been asked "Why don't you like this pattern or that pattern? I mean [Some famous blogger] says s/he always uses them. I think they are smart or at least they seem to be. You must be a 'Mort' or a pretender..." At least that's the way it has always been stated to me.
With lot's of disrespect for th 15+ years of dev experience that I have. The truth is that it usually mischaracterizes what my stance is. My problem is not in the pattern... it's with the word "ALWAYS."
I've had a few months to really ponder my own stance and the battle lines that I have drawn in the past (those posts are here at TheRunTime... you can feel free to read... although I am a little embarassed by some of them... negativitiy is rampant I must warn you).
[BTW, I have not always lived by these tenets (Sorry Dana and Steve... I know you both inherited lovely pieces of my code that were an ode to my own brilliance... sorry)]
At this point I have identified 2 rules (there are probably more)
Rule #1 - Write no more code than is necessary
What this means is that I look at the problem and try to solve it as simply as possible. This has the net effect that once I leave the project someone can come after me and take over... Some of the ASPSOFT guys inherited code of mine that I think they were able to take over very quickly after I was gone (Although again... Sorry, Steve). It also means that when I need to update the code to add some new functionality or refactor it I'm way ahead of the game, because I don't have to "unfactor" some other pattern to make my life easier...
Rule #2 - Make no more code public than is necessary
This rule is Anti-TDD in light of current TDD Best Practices (at least as much as I as a non-practitioner can understand... which from what I have been told is very little <grin />). So I don't use for instance Dependency Injection on all projects.
The reason for this is security. Let me throw out a not-so contrived example to explain (and I don't mean to be attacking TDD... I just want to show a failing of it as I understand the practice).
Rule #2 - Scenario
I've made it known that I used to work for a large corporation. One of the things that was happening in the corporation as I was leaving (2 years ago) was that there had been ordained a standard library for all things security-related (so login, and permission checks were to be handled via this library). Let's say I was working on a desktop app that I was going to be building and I had a support DLL where I was placing additional library function code. I realized that some of these lines of code were going to need to run security checks against the current user's permissions, but I wanted to test various scenarios so I decided to Dependency Inject the security system so I could mock it. The code would look something like this:
1: public class blah
2: { 3: private ISecuritySystem SecuritySystem;
4: public blah(ISecuritySystem security)
5: { 6: SecuritySystem = security;
7: }
8: // Other methods below
9: }
Now by adding that constructor there I can mock the SecuritySystem and test in different security profiles. Wonderful! Why would I not want to do that?
Well...
At the corporation I mentioned... there are programmers within the company... But their titles are like Sales Technician or Marketing Technical Consultant. Their job is to write little reports and stuff for the various departments who want to avoid having IT do the work. These people are very inexperienced, but very good at hacking the system. If I gave them a DLL or even simply did the above in an EXE that would be very, very dangerous. Because using the same mocking tools they could potentially override security and call functions that they do not have permission to call. They could also write their own implementation of ISecuritySystem and again bypass securtity entirely. Even if this is private... reflection technically makes it possible.
You stick with simplicity that's not even possible... The embedded SecuritySystem is the one that gets used.
TDD arguments
Ok, now I know someone will say... wait, what about simply making that constructor appear within a #if construct and not build that for the release version. That would work... as long as your support people never touch your build server or any other dev version of a DLL... again you are making risks that someone's machine won't work and a Dev DLL is temporarily pushed so that the user's machine is patched... You need to remember that the security code is there...
Besides in my mind you've made more work for yourself than I think it is worth (you may think differently though).
----
I would be remiss to say that I don't oppose any pattern. Study/learn them. But most importanly learn when to use them and scrutinize heavily things that you feel you must "ALWAYS" use.
Print | posted on Friday, November 16, 2007 1:16 PM