Simplicity...

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

Feedback

# re: Simplicity...

left by Mark Brackett at 11/19/2007 6:42 AM Gravatar

Seriously, man, WTF? You say the Marketing guy knows how to implement an ISecuritySystem interface, can use reflection to call an internal constructor, and is willing to override security checks - yet all of your security checks are client side? You're screwed - regardless of DI or not.

Using reflection, I can easily inject my own ISecuritySystem instance whether you exposed it via a constructor or not. I'd also bet there's a 101 other ways to get through your code while bypassing the security calls.

Not saying that DI is appropiate for a *public* API - but that's why there's InternalsVisibleTo. And it's not appropiate because it doesn't add value to the intended use of the API, nor is it intended to be supported "forever" - as an API should be; not because of a misguided security implication. If your clients are your enemy, managed code is probably not the best option for you anyway.

# re: Simplicity...

left by efdee at 11/19/2007 7:48 AM Gravatar

"That would work... as long as your support people never touch your build server or any other dev version of a DLL..."

If that's the case, what keeps them from just plain taking out the code that does security checks?

Apart from that, I'd like to hear some opinions from the TDD/DI people here. I've been somewhat worried about the same thing -- I don't like the fact that my users can just switch random parts of my application out. So far what I've done in situation where this matters is not supporting configuration files and configuring the container in plain old code.

# re: Simplicity...

left by Jacob at 11/19/2007 11:09 AM Gravatar

Nice post. I've been sitting on a follow-up post of my own for a month or so for similar reasons. I think we need to examine that hesitation more closely. I know that mine stems from the vehemence directed my way when I expressed doubt about the utility of Dependency Injection. Since my pending follow-up is actually going to be more explicitly skeptical I expect to catch more public flak for it and I cringe somewhat in anticipation.

The thing is, there's a reason silver bullets have a bad name in software development. Until we learn some discipline and stop giving every fad the weight of unquestioned dominion, I'm afraid we'll continue having a tough time being taken seriously as a profession. Yes, Dependency Injection has a place in the software development toolbox. As does unit testing. As does any of dozens of other innovations both recent and receding. But what they have is just that... a place. As long as we continue to allow ourselves to forget simplicity (or my favored encapsulation of it in YAGNI), we'll contintue to over-design and pay the costs of doing so on the back side.

# re: Simplicity...

left by Mitchell Silverman at 11/19/2007 1:29 PM Gravatar

I hate to say Duh - especially when you give an outstanding example of why you wouldn't want to use a pattern. But the whole point of being a programming professional - of being any professional is judgment. Software engineering - like all forms of engineering - simply cannot be brought down to "the One True Way".  This is a good thing because it means we always have more to learn - we can further the art. But it means that we must be aware of the strengths and weaknesses of the approaches/tools we use. I hate to say Duh - not ecause I disagree but because it needs to be said.

# re: Simplicity...

left by Soon *** at 11/19/2007 4:56 PM Gravatar

On rule 2, you said that you made no more code public than necessary for "security reasons".

Although I agree that one should not made more code public other than necessary, doing it for the security reasons is uncommon. After all, if anyone is determined, he can easily use reflector to read your private methods and call them via reflection ( I assume that you are programming in .Net).

I want to keep my code as private because I want to present a clean interface to my code users. That's the reason

# re: Simplicity...

left by Alex at 11/19/2007 11:42 PM Gravatar

As far as I know you can even set a private field with reflection. You don't need a constructor to inject a mock security system object.

# re: Simplicity...

left by Alek Davis at 11/20/2007 12:41 AM Gravatar

Amen, brother! I do so agree with you.

# re: Simplicity...

left by jkimble at 11/21/2007 7:25 AM Gravatar

Sorry it took me so long to respond guys... New blog... and I don't have everything on yet... <grin />

I am glad to see people are actually reading and that I see some agreement on this topic.  

Those who mentioned reflection I would agree, but we are also not talking rocket science folks that I'm worried about... I'm talking about guys who know how to launch VS or SharpDevelop and can use the provided intellisense...

BTW, there was something else I missed mentioning in the article which I will mention here... In my actual implmentation I would  not be using an ISecurity anything... it would be the full class so unless one could inherit from that class overriding it would be a little more difficult.

Again, this is a somewhat contrived example... Use your brains for when to use the pattern and when you shouldn't use it...

Title  
Name
Email (never displayed)
Url
Comments   
Please add 1 and 2 and type the answer here: