Simple != Poor Quality, period!
Casey commented on my post about ALT.Net and the Enterprise, and we have a good discussion going on there. But something he said triggered so many red flags that I had to go breath into a paper bag for a few moments:
many 'enterprise' teams have to take whatever body count they can get to satisfy the management. And in that case you have to keep things really simple (and by definition produce poor quality code).
He later went on to expand what he think is simple:
In case I expressed myself badly ... by simple in that context, I mean simple as in "mostly drag and drop", no IoC, no inheritance, no composition, lots of "standard things" like EAAB, and most code in the aspx.cs files ... because that is as far as most developers understand code.
"simple code" in the context I suspect you mean it is probably as I would define it... which is the hardest code in the world to write. The simpler the code is, the harder it is to write.
High quality code is simple, elegant and to the point. Keeping things simple means making it easy to go the right path. Thinking that keeping things simple is by definition producing poor quality code is a mistake.
I am afraid that I can't really find any simplicity in "mostly drag & drop, most of the code in the aspx.cs". In fact, it is far more complex than the alternative, because you have to juggle so many balls at the same time.
Here is a piece of simple code:
[Occurrences(OccureEvery.Day, At = EsitmatedRunTime.MidMorning, RunAtHolidays = false)] public class SendSmsTwoDaysBeforeEventStart : ScheduledTask { public override void Execute() { ICollection<Event> eventsInTwoDays = Repository<Event>.FindAll( Where.Event.ScheduledDate.Between(InTwoCalendarDays, InTwoDays) && Where.Event.Participants.With(FetchMode.Join) ); foreach(Event e in eventsInTwoDays) { SendNotificationSmsToAllParticipantsIn(e); } } }
It is easy to write, easy to read, and it is stupid code. You can write & test this in a short amount of time, and it lends itself greatly to a check list approach. "Here are the batch processes we need to build right now, here is how you build a batch process, let me know if you have any issues and when you are done". Very simple code, quite elegant, if I say so myself, but nothing that you need to really think about when you build it.
Keeping things simple means higher code quality, period. Making them complex any tiny bit over the necessary, and your code quality will plummet.
Comments
I couldn't agree more. too many times people over architect a solution or feel by delivering something highly complex they're showing off how abstract or how "elevated" there skill level is. which is not true.
simple isn't easy. simple is difficult. simple is powerful.
You can't have simple with complex. the beauty is in the application. Beneath everything simple and beautiful (an ipod for example - heck a flower for example) is something very complex.
deep right? ;)
Ok ... things I have interview people on and they (on the whole) wouldn't understand:
Attributes - seriously, ask most developers what an attribute is and they may vaguely know, ask them to name 2 they use every time the code and they would be very hard pressed to say [Serializable] and [WebMethod] or any other very common attributes - let alone custom ones!
Inheritance - Tricky, they probably copied and pasted an example you coded, so don't count on them figuring out why they overrided anything.
Generics - yes 3 on from generics in C#, I meet very few developer that understand them even at the simple level in your example.
Fluent interfaces - way beyond their comprehension.
Enums - yep, seriously, many many developers don't know what an enum is ...
Most developers (in my experience) would have:
Put public properties on the class to deal with what your attributes covered.
Created a new class and copied/pasted the contents of ScheduledTask where they thought they needed that code.
Used a Dictionary<Event> at best, and more likely used HashTable
I have seen all these done in production code for some of the world's most prestigious organisations!
Yes - I'm serious - you work with the elite of the development world, even though you may not consider all of them to be Einsteins, they certainly aren't Mort either.
Okay, seriously, if you're a professional developer and you can't grok enumerations, you really need to find another career path. Also, if you have some experience with .NET, and you don't understand inheritance, attributes, and generics, you don't have the right to call yourself a .NET developer. I don't want to have to compete with you for a job.
(Naturally, when I say "you" I'm not referring to YOU, Casey, I'm talking about the person/people you interviewed.)
It's true, though, that the simplicity provided by a fluent interface is supported by a complex infrastructure, likely the Builder pattern or something like that. However, I'd much prefer that the complexity exist and be hidden than be in my face every day.
I think I know what you're disagreeing on. See, I agree with you completely, but I also see Casey's case (pun unintended).
That piece of code you put there, it's remarkably simple. But the infrastructure that supports it (I can spot a Fluent Interface, some sort of ORM, and custom attributes, and I guess there's more) isn't simple at all. In fact if I'd have to wager a guess, I'd say it's very, very complex. It's complex to code; and even if you have it ready and open sources and everything, it's complex to set up; and even it if isn't, it's definitely complex to grasp.
As someone said, simple isn't easy. But for less skilled coders, it's far simpler (and easier) to just write the code in the .aspx.cs files or the equivalent easy task. The code that's produced isn't simple at all, but the design, or architecture, or I don't know what to call it, is simple: "we double click the web control and write the code that handles that event". That's IT. You don't get much simpler than that. It's easy to do and everybody gets it. Crummy code? of course. Maintainability issues? probably. Do I care? nope.
In contrast, your architecture/design is complex. You can't explain it in the same number of words. You'd have to go "well, we use an IoC container (link) configured with Binsor (link), and a Repository approach (link) facilitated by NHibernate (link). The code goes in the controller, which is called by the view when appropriate (link to MVC/MVP), only the view only knows an interface, and it uses the IoC container to get the actual controller. Then, if we need model (link) entities, we use Repository<T> to handle them, which exposes a handy fluent interface...". This can go on forever. The bright side is that when you're done, you'll end it with "and then all the rest becomes extremely simple."
To a simple-minded developer, that's anything BUT simple. It's simple to use, but it's insanely hard to comprehend - let alone implement. If they have an Ayende-equivalent on their team, they can have the luxury of letting him handle the infrastructure; but most teams don't develop on .Oren(TM), they develop on .NET.
And without .Oren or its equivalent, simple coders will write simple code, which would inevitably mean bad code quality. That (I think) is Casey's point, and he's kinda right.
You need bright people that can grok and appreciate the complex infrastructure that allows them to write stupidly simple code. Simple coders won't get this, and will be happy with the out-of-the-box way.
Now put yourself in the position of a contrator, where my CV looks exactly like very other CV of all of those people I have interviewed, and probably looks the same as yours.
An agent has no way of telling one from the other, nor do most employers. They get 100 CVs for every position, and have no way of knowing which are good and which are bad. AS most emplyers don't do any kind of technical testing of any value either (I have been tested maybe 3 times in 10 years and 20 odd contracts, and dozens of interviews, and only one of those was of a level I couldn't have bluffed through) ... they pick 5 or 6 to get in for interview, and the one that seems most confident and tells the right story gets the job :)
A fuller reply here http://blog.goinsane.co.uk/archive/2007/10/12/simple--poor-quality-period.aspx
I would like to encourage all of the "simple" developers to keep writing their "simple" code!
Dont use inheritance! Dont use interfaces/IoC! Write all of your logic in the codebehind! And for goodness sake please use datasets instead of ORM.
After all, I have some more college loans to pay off, and if I people keep labeling me as a "advanced" or "esoteric" because I use these relatively simple concepts, it makes me more money.
thank you for your support.
-p
Use this rule of thumb and you should be good to go!
If its not built into visual studio, or it doesnt look like a drag and drop UI from microsoft office, its buggy, too complex and not worth learning.
attributes/ inheritance - if they can't figure that out after I explain it the second time, they aren't going to remain long. Although at worst, they can just copy/paste the example and edit the content of Execute()
Repository<TEntity> - > Use that to make queries. They don't need to understand generics in order to use this. They just need to feel the strange whole in the < >.
NHQG is beyond my comprehension, but you are wrong here. I build the FluentEmailSender that I mentioned before, a few days letter someone added FluentPhoneConversationBuilder, without any prompting from me, just because they liked the idea. Beyond that, there is a difference between creating and using.
Enums - deal with that with the magic of inteli sense.
ICollection<Event> is the return type of FindAll(), no choice there.
Casey,
Here are a few cases where the code was so bad I had to tell someone about it:
http://ayende.com/Blog/archive/2007/05/12/For-Experts-Only.aspx
http://www.ayende.com/Blog/archive/2007/02/08/Stories-from-the-Code-Reviews-Threading.aspx
http://www.ayende.com/Blog/archive/2006/10/01/7241.aspx
http://www.ayende.com/Blog/archive/2007/06/02/Effective-Software-Development-or-Policing-Of-Monkeys.aspx
Those are just the stuff that I could find in a quick google search. I work in the real world, an I have to deal with the messes that other people do.
Casey,
If I picked my plubmer in the same manner, I shouldn't be surprised if I get a leak.
I'll just take this as an example ... a CV has 5 major blue chip corporations as last jobs, all check out, all 6 month contracts. All would have been paying £500 per day ...
The person has no idea what attributes are, and can't explain polymorphism to you in an interview, and when you ask them the differences between an abstract base class and an interface they say things like "well a class is used to write code in and an interface is something that you used to use in COM but we don't use any more"
Now you wouldn't give them a job, nor would I ... but as they have been in well paid contracts for the last 2 years doing just what you asked them to explain (apparently), I'll lay a bet there are a hundred other managers that will employ them ... they aren't all leaving the industry to get jobs in McDonalds ... people are actually paying them to write code.
Here's your next problem ... when they get good jobs, and their managers don;t know they aren;t good... who do you think they will employ when they get their promotion to team leader? The person who knows they are writing terrible code, or someone dumber still?? :)
Ahhh the plumber comparison .. yeah ... builders/plumbers .... the previous "cowboy industries"
If a builder is employed and he starts building you a wall .. even an average person can tell that the wall isn't straight. A plumber might work on your pipes, but if they satrt leaking the day after you know it isn't right.
Now if your builder was left to work on building you a new house, and everytime you asked how it was going you were told "its fine, just doing some bits on the back end now" but he didn;t let you look at the house you would be worried. When a developer does it, you have no idea that he hasn;t coded anything worth having, after all ... all software has bugs ... doesn't it?
I have to say I agree 100% with Ayende.
This is true of any field where teams are involved like sports as well.
The team leader is the one who makes the other members do things.
If the leader does not really believe in the cause, the game is lost in advance, don't even bother to play.
All team members don't have to understand at first how Ayende's code works behind the scene, they just use it, but maybe a few of them are trying to understand how it works and Ayende will notice, take those apart and teach them.
Within a couple of month, he has a few members that can build these complex systems that are easier to use for the other (not so smart ones)
Casey,
Sad, but so true.
And on an unrelated note, I feel that this "blind" process is very akin to the way that the US elects its presidents, as well.
I very much see what Casey was saying.
Simple code is -not- easy to write. It may be easy for everyone to read, but it's definitely not easy to implement. Beginning developers never do things the simplest way, they do them the most obvious way. It takes a lot of experience to identify and pick the simple solution out of all the possible options.
Simple code is what we all strive for. If you screw up an implementation, it ends up complicated. Beginning or average developers screw up a lot, it's part of the learning process. Unless you have the luxury of very tight review/rework cycles, your code is going to continue to tend to the complicated.
Does that mean I think you should punt and tell everyone to just stick everything in the code behind? Hell no. You should teach, train, push, pull and work as hard as you can to elevate the level of your team so everyone can write simple code. Otherwise you'll always be in a mess, fighting fires. Or worse, throwing away code and starting over for every new project.
But the idea of "if you can't write code like this you're off the team" is not practical in most enterprise organizations. Remember, the corporate culture is not about writing software, it's about making widgets, or transporting things, or whatever the business is. Software development culture is often at odds with the culture of the core business. When you have the weight of a 40,000 employee company with hiring and evaluation processes that are designed to recruit and retain the best salespeople or managers and not developers, you have to take what you have and work hard to train and teach.
Again, just to reiterate, this doesn't mean giving up. It just means it's a hard, never-ending road from where you are to where you'd love to be. Over time (2-3 years), you can notice a big improvement if you can keep your seniors around. You can eventually drop off a few of the people with incompatible ideas about development, elevate the people who want to try, and retain/add enough good developers to make quality software. It's just not easy.
Is it your contention that he should be employing skilled people, or employing people he thinks he can teach?
When I am in the position of needing to recruit, I am paying very large sums of money to people, not so that I can teach them, but so that they can do work that needs to be done.
I still think that Oren is in the priviliged position of working with some exceptional people, and having the ability to spend time investing in those people he thinks are worthwhile. When I find myself on a team like that, I too am very happy and enjoy gong to work :)
However, rarely on real projects is that time to teach and educate a luxury that can be afforded.
I have read through all of the comments on the last couple of posts and really am not sure how to respond succinctly other than to say: Casey, you are a total downer. If we were all to blindly follow your recommendations we might as well all just pack up and go home. Or use COBOL. :)
Defeatist attitude's like Casey's are exactly why we find ourselves in a society where so many people feel an undue sense of entitlement, as if they should be able to coast through life without improving themselves, and is why our society continues to dumb everything down to the Mort level.
We should have better expectations of ourselves, and heck, even if we can't have better expectations of absolutely everyone, we can certainly choose to ignore Chicken Littles like Casey, get ourselves onto good teams, choose good technology, and deliver high quality, long-lived solutions. Along the way, hopefully we can lift up those around us, and be lifted by them, as we and they all have many things to learn.
Or, you could be like Casey and just give up, pack up and go home.
As an aside, the industry desparately needs to kill off the term "Mort". Just look at the kinds of posts and comments we've been seeing these days. Every time "Mort" comes up, Mort gets used as an excuse to let crappy "professionals" continue to be crappy, continue to feel unduly entitled, and continue to drag the rest of us down. Die Mort, die!
Avish,
If you are talking about getting started, this is something that can be easily be have using project templates and documentation.
You are comparing oranges to apples here, because you latched in the OR/M, IoC and MVC on one side, and responding to a single event on the other side.
It is comments like that when I have to check if I have interviewed Jeremy before and rejected him :)
I don;t think personal attacks are either very constructive or add anything to the conversation. We all agree that good code is very important, we all have to write it on a daily basis, and we all have to deliver real working solutions.
Just becasue I am putting forward the deabte from the point of view of an employer means I am a "downer"? Or does it mean that there are counter viewpoints to the rosy world that you see in a place like this, where almost by definition everyone reading will pride themselves on writing high quality, maintainable code.
If you believe that the vast majority of the developers in the world are here, you are sadly mistaken, most of them want to go to work, throw someting together and go home - it is a job, not something they aspire to excel at.
That isn't being a downer, it is showing another side to the world.
Casey,
I don't get where you are going, frankly.
Do you want me to admit that there are people out there that are basically frauds, that they get paid good money and couldn't find a value type with a map & both hands? And that at clients who should certainly know better?
Yes, they are there.
If they were on my team, they would need to either straighten up or leave, I have very little problem with lack of knowledge, I have huge problem with unwillingness to learn.
But, given all of that, do you suggest that I should structure the way I work in order to fit that line of thinking?
Casey,
I am not sure about you, but I certainly can't evaluate the work of a plumber or an electrician, even if I am on site and inspecting things.
Let us take the electrician, since I have a good example there. You had a house built, found a electrician, he go the thing wired, and you are happy.
Then you buy a dryer to go with the washing machine, and you get a total blackout. Turns out that the circuits for the basement can't handle both machines at the same time.
Now take a hammer and break the walls & rewire the whole thing from scratch, sounds similar?
I want to employ skilled people, but they are already employed. I have some true horror stories from interviews, if you care to search the blog for them.
At this point, I no longer believe that I will find skilled people through CVs hunt, only through direct contacts, so I settled on getting people that I can teach.
In the long run, there is little difference, and I don't mind investing in an employee, in fact, I think I should. As for lack of time to invest in employees, I don't have the time to fix their mistakes, frankly, so I have better pay it up front, in cash, it will be cheaper this way.
This started at ALT.Net and the Enterprise ... where you wondered why these things are believed not to scale up to (for example) 100 developers. I suggested the reason was that the great majority of those developers were 'body count', hence you had to let the overall team take the common approach (which I referred to as simple).
In that case, no these 'revolutionary' things won't scale, becasue you are hiring from a pool of developers that grew up with drag, drop, VB6, WebForms and Intellisence.So your options are: train 90 developers to use better techniques (while paying them) or use the things they are comfortable with and get some kind of result.
Managers will almost always pickthe second. As a technical person, I aksed you how you could convine them to take a better approach, wiythout using any technical terminology.
I disagree, because I think that a sense of professional pride is mandatory for a healthy life.
I am privileged to work in a field that I love, but a lot of people don't get this chance, and work in something that they have very little personal interest in.
_But_, they still take pride in doing the job right, on time, and efficiently.
I am privileged to work in a field that I love, but a lot of people don't get this chance, and work in something that they have very little personal interest in.
_But_, they still take pride in doing the job right, on time, and efficiently.
<<
In that case not only are you lucky enough to work with some very experienced and dedicated induviduals, but you are lucky enough to encounter these people in every line of work in your everyday life.
I tend to find the great majority of people don't like their jobs. I can probably count on one hand the number pof developers that I have worked with (which must be in the hundreds) who even read a blog outside of work, or have ever attended a conference.
Those who work at what they love are lucky, but they are also pretty rare.
And from another comment - I think Paula Bean sums it up pretty well ... http://worsethanfailure.com/Articles/The_Brillant_Paula_Bean.aspx ... she isn;t as uncommon as she may appear.
Rob,
We got around to discussing the applicability of this concerns with beginners, but they would never get the chance to build it from scratch. They would only get the chance to get it working from the given architecture.
I am not suggesting throwing them an IoC article and an MVC webcast and coming back in six months to see what they did. I am talking about having an architecture in place that split what they need to do into small pieces, carefully defined so they don't have much place to add complexity.
You catch the additional complexity in code reviews, and you sit with that dev and go through refactoring it until it is simple. Over time, they get a sense of it and write simple code by default.
There is a distinct difference between liking my work and having professional pride in what I do.
This is not about meeting people who like what they do, they may not care "it is just a job" or dislike it "sucky job", but nevertheless, you ought to take pride in what you are doing.
Before I was a developer I was working in a position that I loathed. That didn't prevent me from doing it moderately well, and attempt to be successful. The Minimum Required approach is one that end up hurting the employee in the end, and will cause any employer to want to get rid of that person.
I think that we need to add some context to the discussion.
Let's say we need to get out a quick app to 5 users who will use it once a week for non-critical work. As a manager, I would probably be OK with any kind of code that got the job done.
On the other hand, if I'm managing a project that deals with target acquisition for missiles, I'd be much more concerned with the code quality, specifically issues of testability.
The kind of developers that I'd look for in each case would be different. The criteria for what constitutes acceptable code would be different. The amount of money I'd be willing to pay for developers with those skills would be different.
All points made so far can be correct, given the appropriate context.
That makes sense, it's just really, really hard. :-)
And the important part of the argument is that on the flip side, the vendors are selling their silver-bullet products -hard-, at all levels. Especially at Microsoft, their sales machine is brilliant and relentless. (I wonder how many CEO or CTO's passed through the executive briefing center today....).
So our voices, way down from the depths of the organization that in order to be more productive we need to be more selective about who we hire is pretty much the opposite of what they are being sold.
They are being sold on the idea that all these fancy platforms and tools cut back on your need to have as many talented people on the ground. So the organization pressure is to hire more people, faster and cheaper. That culture is very difficult to carve out a niche to build a smaller, better, more efficient development team that writes high quality code. When you developer salaries are capped, change is a long hard road, and your open job reqs. start counting against if you if they are open to long and get closed, it takes a lot of ground and middle management skill to shield a high quality development team.
Rob,
Absolutely!
But good practices should hopefully produce good results (otherwise why practice them?), so you can prove efficiency with results.
That does tend to make things easier
Why does everyone argue STUPID crap all the time. One of the things I have learned about 3 years ago is when the CIO asked me:
"What do I gain for doing it this way?"
My answer consisting of "more maintanable/readable code" didn't go well.
Bottom line is...if I can get to market with an idea/release/upgrade 40% faster because u took code shortcuts. That is MAGNITUDES times better than being late and having essentially "pretty" code.
Developers don't cut each other slack. Most don't have a clue that none of this stuff really matters. Ur not saving the manatees no matter HOW great ur code/design/architecture is. Once in a while there will be a piece of code that is admired (i.e. square root opimization in Quake).
http://www.codemaestro.com/reviews/review00000105.html
Bart,
The answer you gave is wrong. To be more exact, it is phrased in the wrong terms.
"Because I can get things faster this way, and keep going fast in a month and in a year"
Sure, you can do that, but then you have 4000% higher costs in the next feature / bug fix.
@Casey - I think the issue of getting a 100 average devs to do IOC/MVC style work is partially addressed by the Microsoft P&P Guidance Automation toolkits and their related software factories. Using this kind of framework, you can decent architectures with a wizard type of environment.
@Bart : I would put money that if you are still developing software in 10 years you will not think the same way.
This language is so ugly... why use such a complicated language if other languages get the same with less code?
Too many sacrifice speed over their life-time
She,
What language?
What other options?
<<
Well, every consultancy already had their own versions of this ... it is back to the drag and drop idea ... get enough monkeys together, give them a mouse and they will probably hack something to gether that looks right. The real developes can fix it later :)
The idea of a "standard framework" that lesser skilled developers can easily use has been tried at every single organisation I have ever worked at - it is the silver bullet that management always wants... "our good developers will set this up, then we save money by hiring cheaper people to just link it all together" ... it has never worked yet :)
I suspect the P&P factories have never been used in a real project that didn;t have MS as one of the consultacies involved in delivering the solution, nor will it ever be used in anger.
Sadly I feel that Casey is right and Ayende bravely, wonderfully, inspiringly, totally wrong. I love programming and can program quite well in C, Haskell, Lisp, Java, C#, ML, Smalltalk, Python. I work in C# these days. I work as a contractor in the North East of England and have done for over 10 years working in every sector. I’d love to set up a little software shop and do it right but as it is I have to go work in large and small companies with enterpisey developers. I have worked with scores, possibly hundreds of such developers. Perhaps 1 in 10 actually gave a rats ass and would have understood what being able to pass a function around our use generics/templates, who really, really /got/ inheritance and interfaces or so forth. [anecdotes removed] Frankly, the reality of IT is that it is chock full of utterly clueless code monkeys who never read a book couldn’t give a fig about their job but then almost nobody give a toss about doing a good job in any job, its strictly about getting paid and getting the beers in. I love programming and get paid very well for it, but my god my colleagues are a downer.
Casey,
If you have followed my suggestions, you could have seen that I am proposing much of the same thing, although I am careful to phrase it differently, and drag & drop is not involved :-)
David,
I have found those people too, in much greater quantities than the good guys, but that doesn't mean that I need to stoop to their level, it means that I need to find a way to make them work in mine.
I do, and I have.
I'm currently maintaining a Delphi system that was built as Bart said. "Why care about maintainability? Let's just make this work!". Bottom line: now, all the logic is spread across different buttons, menu entries, etc. So, when you're going to change the validation of a given field, you have to check: all of the textbox's events, the "save" button for the given record, the "save" button for a global record, the "print" button (the data needs to be validated before it's printed), the "upload data" button, etc.
Bart: I think your problem is that you don't really know what the term "beautiful code" means (yet). It does not mean beautiful as in "a beautiful rokoko painting, with lots of useless but pretty details". At least as I understand the term, it means something like in "a beautiful mathematical proof", which has two main qualities: 1. It's short and 2. its obviously correct. (In that sense, Carmac's 1/sqrt-implmentation is exceedingly ugly, and the only reason to build something like that is that you timed, with a profiler, that 1/sqrt is a bottleneck in your absolutely performance-critical appllication.)
But, to be honest, it took me some time to figure that out myself, too ;-)
Also, what the hell is Esitmated?
Shannon: A typo....?
In mathematics, there is a phenomenon where, as an area is better understood, the best proofs of a given theorem get shorter and easier to understand. The same is true for code. As you understand the requirements and algorithms better, the code gets simpler.
Comment preview