Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Casey Charlton - Insane World

Hang the code, and hang the rules. They're more like guidelines anyway

May 2008 - Posts

  • Some Great Free Winforms Controls - Krypton

    As I have just been asked to prototype the front end application for the reference architecture that I have recently designed, I was in need of some help.

    Here is the thing, I really, really suck at Winforms coding. Give me a web application and I can make a UI that sings and dances, looks pretty, and is a joy to use. Given a Winforms app I struggle to get anything that isn't grey and clunky. My Winforms always look like they were designed in the far reaches of the past.

    As the UI is really all that many decision makers see of a prototype, this is where your hard work on an elegant and flexible architecture can fall apart - how many times have you heard people quibbling over the exact layout of the grid during a demo, and being totally disinterested in the miracles of code wizardry you have going on behind the scenes to recover the data.

    Fundamentally, if you demo an application - make damn sure the UI looks amazing, because no matter what you think, that is what the people you were showing the application to will remember. I have learned the hard way that all your great coding can be wasted by a poor looking demo, first impressions count.

    Well, after a bit of searching, I came across the Krypton Toolkit. This amazing set of controls are visually great, and more importantly for me, they have amazingly good documentation. I'll repeat it, I suck at Winforms coding, so anything that makes my life easier (i.e. good documentation) is a godsend.

    Not only do they include help file style documentation, they contain a working example with full source code for every control, and even a mini application that can launch each of the examples without you having to build them yourself. This is how end user documentation should be done. 

    And the best part is, they are free for use, even for commercial projects. There are two extra controls that do require licences, and you can purchase the source code for the toolkit itself if you like, but use of the Toolkit controls themselves is totally free.

    And as a double benefit, I only downloaded and installed these a few days ago, and already there is a new release with some bug fixes. They were far from bug free or perfect, but they basically work and the bugs are irritating rather than show stopping - I'm sure this new release will make major fixes, and the responsiveness of the author to update them so fast is very reassuring.

    Now my UI looks something like this (apologies for the blurring out for confidentiality reasons), and is slick and enyoyable to use - thanks Krypton!

     

  • ReSharper 4.0 Has Apparently Gone to Beta!

    Yes, you heard me! Apparently ReSharper 4.0 is now in Beta status.

    This has got to be one of the longest upgrades in development history - I was beginning to think that ReSharper 4 was never going to be released!

    I love ReSharper, and the EAP program has given me a "free" licence for it for months now, but it was getting a little tiresome waiting - but now the end is in sight!  We all appreciate that support for C#3.0 was non-trivial, but much longer and they would have needed to think about supporting C# 4.0 :)

     

  • What Science Fiction Can Teach Developers

    I am a bit of a SciFi geek. There ... I have admitted it.

    No, not one of those weird SciFi fans that turns up at Trekkie or Trekker conventions (does knowing there are two terms make me an even worse geek???). On the whole, when it comes to modern SciFi I prefer to see it and hear it on the big screen.

    But many years ago, way back in my distant youth, I loved to read what would probably be described now as "classic" science fiction. Stories by Philip K Dick, Robert A Heinlein, Ray Bradbury and many other filled my childhood dreams, but above all of them stood Issac Asimov.

    Asimov was possibly the only person to have ever lived that could be described as more prolific than Oren. The entry for Asimov on Wikipedia starts with:

    Asimov was one of the most prolific writers of all time, having written or edited more than 500 books and an estimated 9,000 letters and postcards. His works have been published in nine of the ten major categories of the Dewey Decimal System (all except the 100s, Philosophy)

    This is certainly no empty boast, Asimov wrote not only fiction, but non-fiction, as a biochemist he was highly respected, and his works still form an important reading list of many university degree and PhD courses.

    Asimov was a truely great man

    What he will probably be remembered for mostly is his Three Laws of Robotics, essentially Asimov invented the modern robot. The Three Laws turn out to be amazingly pertinent to everyday life, as one of his stories Evidence explores beautifully, the difference between a robot following the laws is indistinguishable from a human who "may be a very good man".

    Numerous films have been inspired by his Robot stories, including the Bicentennial Man (a quirky Robin Williams performance) and I, Robot (an action packed Will Smith blockbuster)

    Asimov was smart, not just your everyday smart, but REALLY smart. His books are filled with a wealth of stunning observations about the human condition, about technology and science, and about the nature of the universe.

    Mostly what we can learn from Science Fiction, is simply to think beyond what we know. To explore outside the possibilities we can perceive, and to think of new possibilities that we can make happen. Good science fiction is about pushing the boundaries, about exploring options, and about not limiting ourselves to what is here and now. It is no accident that many of the concepts, devices and scientific gobbledygook in works by Asimov, Dick and others has eventually been turned into real science. Arthur C Clarke is credited with many inventions including satellites, Asimov with robotics, and a browse through a back catalogue of any of these writers will reveal things we take to be common everyday items, but described 20, 30 or even 50 years before we "invented" them.

    What actually prompted this post

    Asimov wrote countless fiction books, the most famous series of which was Foundation. And it is Foundation that prompted this post. Within Foundation's Edge (the second in the 7 book "trilogy") there is an observation at one point upon a treaty between two goverments:

    "Before you now you see a copy of the treaty between the Empire and Anacreon – a treaty, incidentally, which is signed on the Emperor's behalf by the same Lord Dorwin who was here last week – and with it a symbolic analysis."

    The treaty ran through five pages of fine print and the analysis was scrawled out in just under half a page.

    "As you see, gentlemen, something like ninety percent of the treaty boiled right out of the analysis as being meaningless, and what we end up with can be described in the following interesting manner:

    "Obligations of Anacreon to the Empire: None!"
    "Powers of the Empire over Anacreon: None!"

    This has always struck me as a good starting point for the analysis of documentation - with sufficient analysis, a document can be distilled down to it's component parts. And in most cases, it seems most of the development documentation that I come across (see I knew I would get back to development at some point) essentially fits the pattern of this treaty well, when distilled down to its most basic fundamentals, it says nothing. I don't mean a little bit of nothing, I mean a whole lot of nothing.

    I'll repeat it becasue it deserves repetition: Most documentation is totally and utterly worthless.

    Now, that isn't to say all documentation in development has no value, but I am sure the ratio of good to bad is stunningly low.

    Wasn't that a long route to a simple statement. Perhaps distillation of this post will show that it contains nothing of any note other than this one statement. Or perhaps it won't.

  • Is Alt.net Duplicitous?

    Roy makes a number of accusations about the Alt.net community, particularly centred around their espoused ideals clashing with their comments and blogs. I respect Roy greatly, his blog was one of my first real sources for great TDD information, and he has consitently put out great blog posts and software. Largely his complaints come down to TypeMock (who he now works for) not getting an overly warm welcome by many people in the Alt.net world.

    I don't for one second question Roy's sincerity, he really has shifted his view on how testing and mocking should work, for what he sees as all the right reasons, and now he seeks to convert others to the same cause.

    I'm not what you might call a "paid up member" of the Alt.net movement, my blog address appears on altnetpedia.com, I frequent the Alt.net mailing list, but I have never attended one of the conferences, nor do I put the Alt.net logo on my site. I read a few dozen blogs, probably a third would be classed as Alt.net people, most would not be. I guess I have a foot in Alt.net but dance with the devil.

    I am however one of the people that has commented a number of times on TypeMock and its suitability as a mocking framework (for my needs), and Roy's obvious frustration comes down largely to his perception that people are bashing TypeMock unfairly, or out of dogma, and not seeing his vision for a better way to write software that TypeMock can help with.

    That is perhaps the case with some people. TypeMock has some fervent supporters, and there are some people that think TypeMock encourages bad practices and should be avoided - software for some reason is one of those things people become almost religious about. I suspect that most people, myself included, are somewhere in the middle.

    TypeMock is to me largely irrelevant. It has some plus sides (debugger support, mocking legacy and framework classes easily), and it has some down sides (it makes it "ok" to couple your code, or to use concretions over abstractions)

    But mostly I just cannot see the point of TypeMock as it exists. It is, if you exclude the plus and minus points I just listed for a moment, basically the same as Moq or Rhino Mocks. It does more or less the same things, in more or less the same way, except both of those options are free, and TypeMock is one of the most costly development tools you could own.

    I'm certainly not against commercial software, I own personal licences for all the software I use on a daily basis, but those products I choose to purchase are the best in their class, or solve a particular problem I face. I also weigh up the cost to value benefit.

    The best comparison would be against unit testing frameworks, which are all to the best of my knowledge open source. There are commercial tools which make them easier to use, but there is no need for a commercial unit testing framework, as they are at least 95% feature complete.

    The same could be said of mocking frameworks, Rhino and Moq are at least 95% feature complete, and pretty much (in all day to day ways) the same as TypeMock. There is for me, no one "killer feature" that TypeMock has that justifies it's price or putting a dependency upon it within a code base.

    So is Alt.Net guilty of the duplicitous charge that Roy has made?

    Expecting all people who frequent the Alt.net world to be constantly flicking between technology and tool choices is not going to hold water. A typical software project may last weeks, months and possibly years. You cannot switch and change that frequently, you have to make choices and go with them. That doesn't stop Alt.Net people wanting to become aware of more options, but it also means that new options have to get compared to existing options, and even when a better option comes along, it is frequently not going to be used because of historical reasons. People still have their favourites, they still have their personal biases, and they still consider themselves as capable individuals who can evaluate these things.

    I honestly don't think TypeMock in it's current form is that revolutionary that we should be sitting up and rushing to use it. The few new things it brings to the mocking party are different, not much better or that much worse. So picking the right tool for the job, means most of the time I prefer to write a wrapper or abstraction (a few wasted minutes) as opposed to changing an entire mocking strategy, all for the sake of a shinier toy. Others make take another approach. When I encounter a real world scenario where I need the power that TypeMock has, I'll re-evaluate.

    Sometimes, the newer tool isn't the right tool for the job.

  • Good Development Practices - Basic Reading List

    It struck me that a good reading list is always welcome to find, and while I suspect most of these books are not entirely new to you, I thought it a good idea to list what I think is the basis of any good development library. Start with these books and you cannot go far wrong, what they teach will be valuable for many years to come.

    The links go off to Amazon for information purposes, but I get no referrer fee or credits, so feel free to purchase where you find the best deal!

    Code Complete 2Code Complete 2

    There is no better book for teaching the fundamentals of good software development. This is a book that explains exactly what goes wrong in software projects, and makes excellent observations and recommendations to avoid falling into the same pitfalls over and over again.

    Domain Driven DesignDomain Driven Design

    Eric Evans has made a wonderful contribution to code design with this book, neatly encapsulating a number of OOD and OOP principles into a coherrent world he defined as Domain Driven Design. Regardless of whether you buy into DDD as a fashion accessory, this book provides masses of valuable information on how to structure and design your applications.

    Enterprise Integration PatternsEnterprise Integration Patterns

    This is a no compromise, heavy reading book on just how to put patterns into your enterprise code. It proves to be an invaluable resource when read alongside Domain Driven Design, giving well explained patterns for dealing with many of the concepts DDD puts forwards. Martin Fowler writes the forward (I put him as the author ... silly me!)

    Patterns of Enteprise Application ArchitecturePatterns of Enterprise Application Architecture

    A Martin Fowler classic, that has become almost the bible of patterns in the enterprise world. While some of the patterns here may run contrary to later evolutions and thinking, this book provides a good solid foundation of patterns at a higher (and in my opinion, more useful) level than the original GoF book did.

    Refactoring To PatternsRefactoring to Patterns

    Where most books focus on defining patterns in isolation from real code, or real usage, this book very clearly sets out to put patterns in their context in existing code bases, and provides many good approaches to refactoring code into a set of recognisable patterns. If nothing else, this book shows how to improve your own code, by showing how simple it is to make a few small changes, and increase code quality significantly.

    Effectively Working With Legacy CodeWorking Effectively With Legacy Code

    Sometimes you cannot avoid legacy code, sometimes you end up with legacy code on a new project. Michael Feathers' book is an excellent resource when trying to bring some sense of order back on to an unruly code base. At a slightly grittier level than Refactoring to Patterns, this book gives practical ways of dealing with low quality code, and either isolating it, or bringing it into some kind of order.

  • What Determines High Quality Code?

    Code quality is an abstract concept again, and can be defined may ways depending on how you perceive quality. A good discussion of the many aspects of code quality can be found on Wikipedia at http://en.wikipedia.org/wiki/Software_quality

    Some general high level objectives for software quality could be considered to be:

    • Conformance to requirements
    • Scalability
    • Correctness
    • Completeness
    • Absence of Bugs
    • Fault tolerance
    • Extensibility
    • Maintainability
    • Documentation

    At a code quality level, some general good guidelines would be:

    • Readability
      - Code should be simple to read, even without comments
      - Class, method, and variable names should be expressive and unambiguous
      - Functional intent should be easily understood
    • Ease of Maintenance, Testing and Debugging
      The degree of effort required to maintain, test and debug an application is a strong indication of the quality of the code and architecture. As the great majority of the cost of an application is actually composed of these three activities, these should be primary considerations
    • Low Complexity
      Complex code is rarely complex because the business functionality it implements is complex. Most software complexity comes through poorly designed and implemented code, over analysis of the problem, or adding additional functionality for requirements that do not yet exist.
    • Low Resource Consumption
      Poorly written code will not take account of resource usage, for example it will not cache information it could cache, or it will create new objects when it did not need to. These issues lead to hard to maintain applications when deployed and used.

    To achieve these objectives, some basic principles of development and design can be applied. These have been referenced elsewhere, but are repeated here for clarity:

    • Single Responsibility Principle
      There should never be more than one reason for a class to change
    • Liskov Substitution Principle
      Methods that use references to base classes should be able to use derived classes without knowing they are doing so
    • Open Closed Principle
      Software entities (classes, modules, methods) should be open for extension but closed for modification
    • Interface Segregation Principle
      Clients should not be forced to depend upon interfaces they do not use
    • Dependency Inversion Principle
      High level modules should not depend upon low level modules, they should both depend upon abstractions
      Abstractions should not depend upon details, details should depend upon abstractions
    • Principle of Least Surprise (sometimes known as Principle of Least Astonishment)
      The result of performing some operation should be obvious, consistent, and predictable, based upon the name of the operation and other clues
    • Separation of Concerns
      The application should be broken into components that overlap in functionality as little as possible

    An assessment of code against these core principles should give a developer a good basis for assessment of the quality of a code base.

  • Statistics and How They Lie

    Industry experience suggests that the design of metrics will encourage certain kinds of behaviour from the people being measured. The common phrase applied is "you get what you measure" (or "be careful what you wish for").

    A Brief Explanation of Cyclomatic Complexity and Code Coverage

    Cyclomatic complexity is a measure of the number of possible paths through a piece of code. This is a relatively easy measurement to make, and code analysis tools can give you this figure directly. As cyclomatic complexity is directly analogous to the number of paths through the code, it is also a direct count of the number of unit tests required as a minimum to test all the code paths.

    • A cyclomatic complexity of 1-10 is a simple piece of code that is easily maintainable.
    • A cyclomatic complexity of 11-20 is a moderately complex piece of code, that is relatively easy to maintain.
    • A cyclomatic complexity of 21-50 would indicate either a highly complex or high risk piece of code. The functionality of the code observed indicates it is in no way complex, and therefore it must fall into the high risk category.
    • A cyclomatic complexity of 51 and above indicates un-testable code, and a very high risk to the project.

    Code coverage measures the number of paths through your code that had at least one execution when unit tests were run. It does not however give any real quality measure against the value of those tests, or the actual quality of those tests.

    It is actually easier to get better coverage results from writing poor code. The poorer the quality of your code and of your tests, the easier it is to achieve high coverage figures.

    See also: Measuring Progress

  • Lines of Code as a Measure of Progress

    Some reports will highlight lines of code as a figure to attach some relevance to, and these become measures used to establish progress.

    These are possibly the most misleading figures to use, in fact almost always within a well designed application and code base, the reverse is true.

    Good code tends to be more concise than poor code, and therefore it is less lines of code.

    Good code also tends to have high levels of code reuse; one of the primary refactoring exercises is removing code duplication. This obviously again leads to a lower number of lines of code. However, the concept of reuse can also be used to increase lines of code and reduce quality in the hands of inexperienced developers.

    An example:

    The following pieces of code are all functionally identical:

    Version One (4 lines):

            public void MyMethod()
            {
                if (myObject == null) doSomething();
            }
    

    Version Two (8 lines):

            public void MyMethod()
            {
                if (Assert(myObject)) doSomething();
            }
    
            public bool Assert(object theObject)
            {
                return theObject == null;
            }
    

    Version Three (8 lines of code):

            public void MyMethod()
            {
                if (Assert(myObject))
                {
                    doSomething();
                }
            }
    
            public bool Assert(object theObject)
            {
                bool theResult = (theObject==null);
                return theResult;
            }
    

    Version Four (20 lines of code):

            public void MyMethod()
            {
                if (Assert(myObject))
                {
                    doSomething();
                } 
            }
    
            public bool Assert(object theObject)
            {
                bool theResult;
                if (theObject==null)
                {
                    theResult = true;
                }
                else
                {
                    theResult = false;
                }
                return theResult;=
            }
    

    As it turns out, the version of that code with the highest quality is Version One, coming in at 4 lines of code total, and actually only 1 line of code that does anything. Version Four has 5 times the number of lines of code as a base guideline, but has 8 times the lines of code if only actual statements are counted. Version Four is coincidentally the poorest quality version of the functionality.

    So if lines of code are a measure of progress, a developer can, consciously or subconsciously, increase their visible progress, by writing lower quality and less maintainable code.

    How About Measuring Decreasing Lines of Code as Success?

    Depending on how you are measuring lines of code, even looking for trends in reduction of lines of code can be considered the wrong approach. For example, now if I concatenate multiple statements into a single terse, unreadable and un-maintainable statement, I can reduce my line count.

    An example:

    Version One (8 lines):

       public int MyMethod(string myString, int result)
       {
           private int const SmallIncrease = 1;
           private int const LargeIncrease = 2;
    
           if (string.IsNullOrEmpty(myString))
               result = result + SmallIncrease;
           else
               result = result + LargeIncrease;
          return result;
       }
    

    Version Two (4 lines):

       public int MyMethod(string myString, int result)
       {
          return string.IsNullOrEmpty(myString) ? result+1 result+2;
       }
    

    In this example, Version One of the code is simpler to read, but is twice as many lines of code. This is also a very simple example; a more complex example would be even more drastic in the difference between the numbers of lines of code in the two methods.

    Within this simple example the first is much easier to read, understand, and therefore maintain. The second obfuscates the values of 1 and 2 in the calculation, and makes it harder to follow the execution path of the code.

    Arguably Version Two could be considered acceptable with some modifications (like the addition of the constants defined in Version One), however both of these piece of code will actually compile to identical binary code.

    In this case Version One is higher quality code as it is easier to understand its intention, and the ability to quickly read and understand intent is a major factor in determining the quality of code.

  • Measuring Progress

    "Working software is the primary measure of progress"

    Fundamentally, there is no more valid measure for progress, than the working software itself. This only leaves open to discussion, the definition of "working software".

    Defining "Working Software"

    The criterion for defining working software is obviously open to debate. A common definition is:

    Software can be called "working software" when it meets a defined set of business requirements and can be demonstrated to do so through testing.

    This is one reason why Agile processes put so much value on unit testing, these tests show very early on in the process that software is meeting business requirements, without the need to create a fully functional user testable application. These unit tests also allow demonstration at a fairly low level of granularity that code is meeting requirements, where a user facing application is dependent on too many factors to easily establish correctness.

    So How Do We Measure Progress?

    Based on this definition, our best way to measure progress and velocity on projects is to evaluate defined business requirements, against the code that is provided to meet those requirements.

    Code that is written, but is not yet functional and passing tests cannot be considered progress until it has been completed to a level as defined above.

    This then prioritises getting components of functionality completed early, rather than attempting to do all things simultaneously.

    The traditional "waterfall" approach to software development is to spread large amounts of functional requirements out amongst large teams, for example assigning each piece of functionality to a team member with an expected delivery date measured in weeks or months. This leads to very long cycles for delivery of something correlating to "working software"

    An Agile approach to the same problem is to focus the teams on only a small subset of that functionality, and to attempt to deliver it in a working and testable state in very short iterations. The degree of success with which they do this then becomes their "velocity". The velocity can then be used as a predictor of future success rates and therefore of future timescales. This also allows a "fail fast" mentality, where it is better to hit problems early on and resolve them, rather than delay all the problems for as long as possible down the development path.

    Therefore, the best way of measuring success is to do one thing at a time, do it well, ensure it works, ensure it meets criteria, ensure it can be tested, and then to replicate the things that went right on the next piece of functionality, and eliminate the things that did not go so well.

     

  • The Only Certainty is Change

    I got an email at the end of last week from a developer asking about Agile development. It highlights a few problems with development in general, and with Agile as a "badge of honour" that are worth exploring. It deserved a fairly detailed reply, so excerts of the email follow: 

    I just came into an Agile project with some difficulties, they have stopped doing Agile development and gone back to a Waterfall approach. Coming into the project late, I saw numerous problems with the approach that are not helping.

    It strikes me that developers rarely come onto a project and think how wonderful it is and how well it is running. This could be because they just have different ideas to everyone else, we all know developers are pretty opinionated, and believe they have the "right" answer to all the questions.

    There is however a more likely reason, when you are close to a project, it is sometimes hard to see what is glaringly obvious to anyone with fresh eyes.

    Agile can be daunting, you are fully exposed, you need to have Courage, you need to resist the urge to falling back to lines like "well we don't have written requirements", "it will be fixed in testing", "it isn't my code", and all the other Waterfall phrases.

    Developers would be working on stories but things were not available to them as they had not been created yet - those items were in other stories

    This sounds like a bad planning excercise. If you are using user stories, then it is the job of the developers to be involved in the planning of these, and to be able to assess up front what dependencies these stories have upon each other, and to properly break these down to more manageable, and more appropriate, stories.

    I have seen similar problems, and it was generally caused by project managers deciding upon the priorities for things, and not listening to developer feedback (or not even including them). A good project manager is vital to a project to act as an "enabler", someone who can make things happen, can remove stumbling blocks, and can generally "grease the wheels". A bad project manager is the worst thing that can happen to a project.

    Requirements changes by the business could cause certain functionality to have to be reworked significantly, causing a lot of problems, if the stakeholders changed their mind every time they saw something, more changes would be introduced. The more they saw, the more they wanted to change.

    Well, Agile dictates (in so far as Agile dictates anything) that the only certainty in a project is that the requirements will change. We embrace change. Agile methodologies are all designed to allow change to happen as easily as possible, and to encourage change to be a core part of the driving process.

    There is a point at which this can easily go wrong though, and again it comes down to either the wrong people in the planning excercise, or someone not listening.

    Understanding change happens is only the first step.

    You have to also explain to the business that change is inevitable, but it is certainly not free. The decision rests with them, but it is the job of the development team to properly evaluate requests and user stories to see what impact they will have on the project now, and into the future. Business users presented with an option to change, but no consequences of doing so, will of course choose change. When asked whether they want to make the change they think is needed, or do the other three user stories that were scheduled for this week instead, the choice becomes rather different. Agile encourages everyone in the process to become a stakeholder, but everyone also has to bear the cost of change.

    Then you have to be able to think ahead and to design your system in such a way as to allow for change. This is a technical challenge, largely only obtained via experience, both of the development language and tools you are using, but also of the business team you are dealing with - how often do they change their minds, how often do they express things badly, how often do they get the wrong person to make the decision. In the sales game, you always want to be talking to the decision maker, becasue only they can give you the answer you need - make sure as a development team you are talking to the decision maker too.

    A well designed architecture is fundamental to a successful project, and a key quality of a well designed architecture is the ability to make changes with relatively little impact upon other system components. Adding or modifying behaviour should not be a traumatic process - it may not be trivial either, but it should never be traumatic. I covered some of the aspects of this previously, and although that post was geared towards why Inversion of Control can benefit your code, it also deals with Robert C Martin's observations on a Rotting Design. Make no mistake, it is perfectly possible to start a greenfield project and have a rotting design from day one. It is also a large risk to any project that the once elegant code base rapidly slips into being a rotting design when time pressures are on, and people start taking shortcuts.

    It is hard to know when it will be finished when things are always open to change

    Agile methodologies do not say we have no delivery date, in fact almost to the contrary. Generally under an Agile project you should be able to deliver a working version of the software at any point in the development.

    Admittedly the functionality present within that software will be largely restricted the earlier on in the process you decide to deliver, but 75% of functionality with a high quality code base is a lot better than 100% functionality which it is heavily bugged and fragile.

    I often draw a triangle for clients, with Time, Quality, Functionality as the three points (Resources is often included here, but I ignore it for this purpose, Brooks Law usually applies by the point this matters). I tell them they can pick any two of those aspects and fix them, but that means the last one will have to vary. They cannot fix all three.

    If Time is a critical deliverable, then you can choose to sacrifice Quality or Functionality (or both). The perfectionist in me says sacrifice Functionality, Quality is too precious to be the one to slip.

    If Quality is a critical deliverable, then choose to slip Time or Functionality. The choice here only comes down to whether you want it fast or complete, or what combination of the two you want.

    If Functionality is the key deliverable, then you can slip Time or Quality, and again I would say that Time has to slip, as Quality is too precious.

    My personal opinion is therefore that Quality comes first, Functionality and Time are the things you can alter - but not only does this vary by project, but also by business circumstances. Sometimes it really is better to get to market with a low quality product, in the lowest possible time, with limited functionality (Twitter immediately comes to mind), just to steal a march on the opposition.

    But what is really important, is that you express these aspects of development explicitly. If you are sacrificing quality because the business has asked for something unachievable, then let them know you are doing this, and make it an express design decision. If later on the business tells you the software is bugged to hell, you can point out when they took that decision to satisfy another need. If you need to take two more months because the business just changed the business model, then fine, but again make it an expressed and documented design decision.

    Too many of these things get left as "assumptions" ... if you don't say otherwise, the business will assume a really high quality product, with massive functionality, in a very short timescale ... it isn't possible, so let them make the choice.

     

  • Project Failures - Blame the Process, or the People?

    Prompted partially by some comments yesterday on my post on How to Make Late Software, Even Later, and partially by a discussion on the altdotnet Yahoo list, I wrote this long email. As it became an epic in its own right, I thought it deserved a blog.

    We Are Doing Agile!

    I can claim to be doing Agile, and following with some degree of conformance, a known and understood Agile methodology. If my project fails, we must blame the Agile process, and our practices in some way for this

    I can claim to be doing Agile, but make up my own variation of a known methodology, in which case a failure of the project is largely encumbant upon me for deciding to sacrifice the practices we chose to ignore, and the new ones we added.

    I can claim to be doing Agile while just coding hell for leather and following no methodology, just cherry picking a couple of practices here and there, and picking the principles I like - in which case any failure is mine to bear.

    All of these approaches should be highlighted in a risk analysis to management to make the decisions *before* you decide to pursue any of these paths. It is the decision of management to weigh risk vs reward and to make that decision. If I didn't write that report, or I wrote it badly, then again the fault is mine to bear. If I wrote it clearly expressing the dangers of a hack and see approach, and management chose that path, then it is their cross to bear.

    You Cannot Blame A Process For Producing Bad Results

    If all participants in a waterfall methodology like RUP followed the practice rigourously, then I have little doubt the project would have a high chance of success (as defined by the process, a close match to the intial requirements)
     
    If all participants in an Agile process like XP followed the practice rigourously, then I have little doubt the project would have a high chance of success (as defined by by the process, a close match to the evolving requirements)

    Bad people on any project can stuff any methodology, and bad application of good practices will always result in failure. Agile just gives you much earlier feedback that you are not getting it right - how you choose to interpret that feedback, or how management choose to, is the fault of those communicating or interpreting the information - not of the process.

    How To Fail Under Agile

    The worst, and I mean absolute worst project failure I ever worked on was done using Agile, using Extreme Programming, and the practices were fairly closely followed. It should have been a success. And for a few small but critical mistakes it would have been.
     
    The first big mistake was not evolving the architecture first. The application had been developed under XP for over 9 months when I was brought in the provide the "Enterprise component" of the application. It became rapidly apparent that the application had been written as a desktop applciation, and was too tightly coupled to allow any extension points for an evolution of the functionality into a different UI and service layer.

    The second big mistake was a large amount of code that had been written to allow the client applciation to operate on domain objects, using an ORM, persisted across a web service layer, relying on massive amounts of code generation. This was a technical mistake that should have been picked up by prototyping and getting the architecture right first.

    The third big mistake was a very poor application of the XP process. The bug backlog for each week was continual, and continally increasing. It was seen as acceptable that stuff didn;t work, and in each stand up it was just refered to as a bug and would go on the backlog. Nobody ever stopped to take a grip of this, and realise that this was a warning sign. As complexity was increaing, the number of interactions in the software was going up rapidly, and people spent more time bug fixing. Out of around 5000 unit tests (afair) that existed when I got there, around 2000+ were failing - this was explained as changes to the code and hence they couldn't get them working. This invalidated pretty much the entire test suite.

    These were not problems with the process (XP), but clear problems with no up front design or prototyping (point one), no technical understanding of the challenges involved (point two), and people badly applying the process (point three).

    Was Agile or Extreme Programming to Blame?

    Yeah, we know loads of it is in flux, and it is a bit 'out there' but this is Agile man, we live by the seat of our pants, we ride fast and hard, this is EXTREME!!!!!

    In the respect that it allowed developers to go to senior management and say this, hell yes Agile and XP were to blame. It gave the excuse to developers that they could excuse stuff being chaotic, as being all part of the way this stuff works.

    The reality was the project failed due to a manager that for all his ability, had never done Agile or XP before, and had taken to quoting Martin Fowler PoEAA so often when we tried to raise problems, that his copy was starting to fall apart. And the business owner took the Agile/XP no requirements thing to the Nth degree and would change his mind on features on a daily basis, so the team could never get a handle on the problem. And lastly the team, that had gone into a terminal march towards inevitable failure, but had never spoken up loudly enough.

    Oddly enough, that was the single team I have worked on that had by far the highest technical ability of any team as a whole I have ever worked with. They had some absolutely superb developers - but sometimes even that isn't enough.

  • How to Make Late Software, Even Later

    I'll start by quoting Brooks Law, as no doubt you expect me to:

    Brooks's law is a principle in software development which says that "adding manpower to a late software project makes it later". It was coined by Fred Brooks in his 1975 book The Mythical Man-Month

    The truth of this is blatantly obvious to anyone who has ever been involved in a project that was slipping its schedule. It is so blatantly obvious that The Mythical Man-Month is almost legendary in development circles largely due to that one brilliant observation.

    Segmentation 

    The often suggested way to avoid Brook's Law biting your backside when you are faced with a project that is rapidly disappearing into the future is around segmentation, breaking your project into manageable chunks that can be developed in isolation. Teams can then take these chunks and develop while a core team is repsonsible for integration of their work. As Wikipedia correctly points out, when the segmentation is done poorly this can actually increase the time to deliver the project even more than just filling a single room with more developers - preventing developers on separate teams interacting easily, when they are actually working on common code is a near catastrophic mistake.

    And now to my real point, correct segmentation can only work when there is a clear and clean architecture underlying the system upon which new developers and teams can easily add new functionality in complete and total isolation from each other, whilst still maintaining the integrity of the system.

    One Common Vision

    The architecture or framework is important in any project, it provides the one common point of reference that all developers have, a project can succeed or fail based solely on getting this part of the project right. Without this in place, all development work on the project is in real danger of producing an inconsistent and incohherent system, that at best will meet the majority of the business requirements but be totally unmaintainable over a period of time - a greenfield legacy system.

    In a large project with multiple developers, and potentially multiple teams, the architecture is critical to the project success. Without this common vision teams will start going off at tangents, will duplicate work, and will spend more time trying to get their code to work nicely with their colleague's code than they ever will providing real business functionality.

    And then Brook's Law not only hits you up the backside, it reverses back over you a few times just to be sure you are really suffering. Project managers, in a way that only project managers could do, ask for more developers to help integrate the code, and your descent into hell has begun.

    Conclusion

    So, if you do nothing else right on a project, get the fundamental architecture and framework right, early. Get a walking skeleton of all critical functionality running early against this architecture to prove it is right, and then ask the business to validate it. You will be amazed how much easier this will make things in the long run.

     

     

  • Always One Step Ahead - Unit Test for Missing Attributes

    Oren always amazes me - I think he is psychic!  Whenever I have a problem, I almost always find Oren blogged about it a few days before - and today's bugbear is a perfect example.

    I started the day off with a really weird timeout exception in WCF. The code was just fine apparently, and I spent a very long time debugging code I was pretty sure was working. The error (in typical framework style) was not able to be caught, debugged, or otherwise detected - it just "happened" somewhere in the WCF call.

    To cut a long story short ... it turned out an attribute was missing on a DTO class, and instead of WCF giving me a meaningful error, it just gave me a worthless message. One addition of [DataContract] later and all was working fine again.

    So, it just happens that Oren (in association with Glenn) had done something similar, and so taking a leaf out of their book, here is a really basic unit test to check that the DTO classes have the right attributes. Some discussion on Oren's blog discussed whether unit tests were the right place for this kind of checking (as it is pretty much static code analysis), and in some ways I can see their point - however, frankly, a unit test is just as valid a way of testing the same thing, fits nicely into CI, and is in a common format to all the other checks.

    [Test]
    public void Ensure_DTO_classes_have_WCF_attributes()
    {
      foreach (var type in typeof(ClassInDTOAssembly).Assembly.GetTypes())
      {
        if (type.IsInterface || type.IsAbstract)
            continue;
        if (type.Namespace.StartsWith("Interfaces.DTO"))
        {
           var attributes = type.GetCustomAttributes(
    typeof (DataContractAttribute), true); if (attributes.Length == 0) Assert.Fail("Unable to identify [DataContract] attribute on type "
    + type.Name + " in DTO namespace"); else foreach (var memberInfo in type.GetMembers()) { if (memberInfo != null) { var memberAttributes =
    memberInfo.GetCustomAttributes(typeof (DataMemberAttribute), true); if (memberAttributes.Length == 0) Assert.Fail("Unable to identify [DataMember] attribute on member "
    + memberInfo.Name + " on type "
    + type.Name + " in DTO namespace"); } } } } }
  • Good Code Is ...

    Simple

    Without a doubt, simple code is better code - more really is less. To misquote Einstein, "Make everything as simple as possible, but not simpler". Rarely have I encountered complicated code that needed to be complicated, even complicated logic does not not require complicated code.

    If you aim for nothing else in your code, make it as simple as you can possibly achieve - someone will thank you for it one day, and it may even be yourself. 

    Expressive of Intent

    It should be simple for a casual reader to browse your code, and figure out what you were trying to do. This comes down partially to using meaningful names for variables and methods, and partially down to structuring your code in a slightly better way. Don't sacrifice code clarity for secondary concerns like optimisation or the "wow factor". Simplicity has a lot to bring to this objective, but so does elegance.

    Elegant

    Code that is well written should be elegant, it should flow, it should read more like poetry than a technical manual. A well written code base is a joy to read, it leads you through the functionality, and always leaves you with a smile on your face. It takes no more than a brief glance at a source file to tell you if it has this quality. You only have to glance at open source projects like Castle or Rhino Mocks to see just how beautiful well written code can be.

    Easy to Identify, Hard to Write

    And the crux of the problem - good code is hard to write. Really hard to write.

    An average developer can pick up a good code base and immediately identify it as being "really good code", but it takes a lot of experience to be the one to create it in the first place. The real skill in writing good code is knowing what you can take away, till nothing remains but the purest form of the solution.

    Good developers are creatives, not technical people - technical things can be trained, but creativity is something that you have within and need to nurture. Practice, practice, and practice more - always strive to write simpler, more expressive and more elegant code.

     

  • TDD is All About Design, Tests Are a Useful By-Product

    I made a comment yesterday on the altdotnet Yahoo group to the effect of:

    Test Driven Development is All About Design, Tests Are a Useful By-Product

    I worded it slightly differently then, but I think this sums it up better. And coincidentally, Oren just blogged a very similar sentiment.

    Whatever you may think, TDD is certainly not about the tests.

    • TDD is a mindset
    • TDD is an approach to designing and writing better software
    • TDD it is a method of driving out good design through *using* your own classes and methods
    • TDD is about starting with your pain points, and working towards a point where the code feels right, because the pain has subsided

    So if ever someone says we are going to use TDD to write our unit tests, take a moment to think.

    Red, Green, Refactor - the most important of the three by a long measure is Refactor. Passing tests are a good starting point, but not much more.

     

More Posts Next page »

Our Sponsors

Red-Gate!