Enabling change by hard coding everything
I had a discussion today about how to make change easier. My take on that was a bit of a surprise to the other guy, "Just hard code everything".
Yes, I consider hard coding as much as possible as a key concept in enabling change.
I am going to leave this as is for now, and post a continuation for that tomorrow, just to see what kind of response this has.
Comments
This seems rather incongruous with your love of binsor.
I'm not sure if i'm on the same train. But I always start buy applying YAGNI and doing all the simplest way, putting functions in the same place i will need, using constants inside the class, etc...
Then when i start to see that there are common issues while implementing something similar or equal in another class...then i start to refactor and create reusable classes...
I don't need this extensibility if i didn't find the seconde time i will use all the infrastructure i only "supposed" i have the first time...
Gustavo.
Nathan,
Actually, no, it is exactly the same, you'll see soon
Well if you consider that hard coding, then I'm completely on board. In my current project, we retrieve our WCF bindings, the actual objects themselves, from a boo config file.
I guess you can hard code the 1st time you need a value/configuration but the 2nd time you need to use it in your code you probably want to change that.
A Code that is written twice is written once too many
Hope you meant hardcoding in the right manner =)
Instead of it you can meet same hardcode repeating 20 or 100 times thru all project, and that's not good.
And you want to use 'Search and replace' to change hardcodes due to it's immutability from place to place, am I right?
Anyway, having separate static (or not) class with all hardcodes is also as useful as config file.
I didn't expect this one from Ayende :)
Hard coding is simple. No need to worry about needing extra tools, dependencies and libraries to work with XML or databases or whatever. Plus you get to lean on your refactoring tools, and everything is in one place.
I'm guessing he means hard coding in the sense of writing code for everything as opposed to using XML (or some other text base) configuration. With dynamic languages, this is very powerful.
Nathan: I'm hoping for the same thing. I Don't mean to single out NHibernate but how many .hbm.xml files get changed after they're deployed to a production environment. Not many I hope!
I think I know what you are getting at here. I worked on a previous multi-tenant system, we had hundreds of settings so each company running the system could go into the admin area and configure everything from order process, reports, pricing, etc..
This was a webshop where a single instance was used by many country divisions of the same company. Each country had different laws and regulations and different process/wishes to how the system should work.
The settings and user admin customizable options just grew making the system very complex and hard to debug. We felt that a better solution would be to hardcode some of the settings, or the different behaviour, in separate implementations (of some interface).
I'm guessing Ayende is going to go with a double-barrelled
a) Worse is Better, and
b) YAGNI (taken to the logical extreme.)
By hardcoding a value, you are enabling change by allowing someone later (with more information) to determine how to best manage potential changes to the variable.
"By hardcoding a value, you are enabling change by allowing someone later (with more information) to determine how to best manage potential changes to the variable. "
You can always decide later to drop a constant with a hardcoded value if you need to have a different constant at that spot.
Using constants instead of hardcoded strings for example isn't always good: they're not compile time checked. So if the string value itself has meaning and can cause problems later on if it's not correct, I think using a constant / static readonly var is better because you don't run the risk of having a typo.
I'm definitely not a coding guru like many I whose blogs I read. I may also not understand all the technical terms that are banded around so forgive me if what I say overlaps (hopefully) in some way.
Surely there is nothing wrong with hard coding stuff as long as it is always hard-coded in 1 consistent location.
For example all the settings in your code should be hard-coded inside a suitable class called perhaps settings.
This is very quick and simple to do. then later when you need to make something alterable, you simply change the code in one place to read a settings file or whatever (defaulting to whatever value you had before)
Is this perhaps what Ayende was referring to?
BTW I have not been able to work out "Oren Eini" vs "Ayende Rahien" can somebody explain?
You're obviously not talking about connection strings and constants.
Do you mean hard coding the functionality that you need, but within an architecture that makes it easy to switch between these hard coded variations?
For example:
a) IOC and strategy pattern for complex calculations, e.g. discounts, instead of a monolithic rules engine with rules configuration stored in XML / database
b) Variations in calculation logic "hard coded" into a DSL instead of data used by rules engine
It kinda goes along with your ordered lego philosophy. Hard-code but hard-code it as service.
It is easier, indeed.
And the change friction is reduced by the support from the compiler.
I've learned this the hard way after putting way too much configurability into one of the projects.
O Giver Of Lessons and Keeper Of Secrets Until You Wish To Reveal Them,
I love you, but this is a little over the top. Just post to your blog if you are going to post to your blog. Nothing is as unattractive as arrogance.
Depends on your definition of "hardcoding"
if you mean you will use const strings rather than "xxx" everywhere, then that is a very good hardcoded const string :D
If you mean having a call through an interface rather than directly, then hardcoding is also easier to change. (perhaps except if you use resharper)
There are many examples of hardcoding function calls are more understandable, it just doesn't scale very well for testing or stability...
Rory,
http://www.ayende.com/Blog/archive/2006/05/28/7551.aspx
Nine Toes,
I am more interested in the discussion than anything else. I think it is fascinating to watch it.
"BTW I have not been able to work out 'Oren Eini' vs 'Ayende Rahien' can somebody explain?"
http://www.ayende.com/about-me.aspx
I think that one codebase I recently ran into took that to heart. There were no objects, and every method in a 1M LOC codebase took a NameValueCollection, with gasp every value retrieved with a hard-coded key.
Spread across 12 solutions, so a grep on one key I looked up found around 1500 matches.
Good times.
Haha, Jimmy. If only that were not so common! I have a similar problem, though only one project of 500,000 lines. The boss brags to me about it being the most complex piece of software the company writes, and my response is, "You think that's a good thing? If it's that complex, for this simple of a domain, then you have failed at making a good design." It's partly so complex because every byte-value that gets sent to the piece of machinery that we're sending it to is hard-coded. There's no easy way to change it, there are no comments, and we unnecessarily wrap everything into a call through COM using a single integer as the definer of over 700 virtual functions. Blah.
I agree with Michael Dorfman that hardcoding can have a YAGNI face.
Also, trying to make something hardcoded configurable or ortogonal, can smell as an early optimisation.
You change only and when you need it. This way you avoid unnecessary complexity and postpone the decision until the last responsible moment.
Jason, that is simple. Oren Eini used to be IDF guy who hired several of his "subjects" to do software development. Couple of them keep the blog, couple of them develop Rhino.* and Oren Eini itself goes only to public events drinking coctails and chilling.
Just my two utterly meaningless and not too serious cents ;)
That's one of the first things that goes out the window when I'm trimming the scope for a delivery. Let's make the configuration aspect part of the next release. For now we can hardcode some defaults in.
Of course, we're hardcoding those defaults in a central place that can be refactored easily into a per-user configuration.
Maybe Ayende is talking about this in terms of a maintenance nightmare that hardcoding brings.
Going through a nightmare of dealing/fixing hardcoded stuff during an incident could be a great catalyst to change.
It's hard to predict how you will need to change things later. If you design with changes in mind, it will complicate your code now and cost you time now. Since your code is more complicated, it will be harder to extend in ways that you didn't plan. And probably even in ways that you did plan.
In order to change one piece of code, I need to know what it is currently doing and how. That is much easier if everything is hard coded -- I look at the code to see the current behavior rather than switching between databases and config files and code. Not to mention Resharper doesn't integrate with NHibernate to quite that degree.
so amazing to watch this discussion...
specially, if you are one of the guys who Ayende suggested that in hour case, solution may be to
"Just hard code everything"...
Isn't some code mantra somewhere that dictates encapsulate what changes (and inject it where you can).
Hardcoding != inflexible. Hardcoding simply means the configuration (for example) is in code. How many websites have you built that required config changes after they were deployed to production?
Not sure if it's what Ayende is referring to but sucessfully identifying the information that may need to change across environments / customers / installations / ... and defining a contract for that, them implementing the contract and injecting the result where it's needed is insanely powerful. You get all the benefits of xml / database / ini type configuration but (as far as i can see) none of the downsides.
In terms of refactoring, sometimes it might be easier to work with a hard-coded module, if nothing more than to see more easily what might be abstracted.
I'm the guy he was talking to when this came up. In context of our conversation what he meant was, do not try to over-design a super flexible (and hard to maintain) infratructure early on. Start with hardcoding, then refactor as you see the pattern of repetitive changes emerge. But not until you see the system.
Comment preview