Coding is optional: A random walk down OO Road (LESS is more).

Coding is optional in LightSwitch, that doesn’t mean that no LightSwitch users ever code… During the short period that I have been coding, I had the priviledge of working with some of the best developers, using some of the most advanced tooling available, both of which has thought me many lessons, most the hard way.

Because I’m giving a session on some of these ‘practices’, I thought I’d summarize them in a short blog post…  Let me know if there’s any unclarities, I feel like I have enough material and examples to write a complete ebook on it, but due to time constraints, fitting them in a post instead.

I’m actually posting this before giving the session, so any of the team members that actually read my blog: get out or spend an extra day next week bugfixing! 🙂

Single responsability principle.

Any class you code, should have only one responsability.  It’s the first of the five SOLID design principles, five principles to learn and live by, that help you avoid “code smells”, ie. make your code more legible, extensible and durable.

The single responsability principle states that your code can have only one single responsability.  This implies that you can summarize what your class does in one short sentence (without using any of the words “and”, “or”, …), sometimes I wish visual studio would be more like twitter: a 140 character limit for all of you classes.  The reason for this is simple: if a class has only one responsability, it will have only one reason to change.  Suppose there is some class “ReportManager” with two methods: “CreateReport” and “PrintReport”.  It has two responsabilities: creating and printing reports.  It can have two reasons to change: something is wrong with creating a report, or something is wrong with printing reports.  Suppose that the “PrintReport” relies on the “CreateReport” in case the report hasn’t yet been created.  If in that case, there is a bug in the “CreateReport” method, and you alter the behaviour for it, it is likely that something will change by calling the “PrintReport” method aswell.  This is typical for classes that have multiple responsabilities: a change in one of it’s key features, introduces bugs (or at least changed behaviour) in sometimes totally different parts of the software.  If you feel that for each bug you close, two new bugs are introduced, you’re in a race you can only win by splitting your classes into a lot of smaller classes, one per responsability.

Nomen est omen.

I recently discovered a class that was created by one of our newer colleagues a couple of months ago called “Date”, which is used in one of our data exporting implementations.  When a class is named Date, one immediately assumes it’s responsability is to hold the notion of a certain day (one square on the calendar, perhaps with or perhaps without the time part)…

        public class Date {
                 public DateTime RegistrationTimeStamp { get; set; }
                 public IEnumerable<Revenue> Revenues { get; set; }
                 public XmlDocument Serialize() { /***/}
             }

I did cry a little, to say the least, when I saw the implementation.

Nomenclature is an important thing.  Since a class has only one responsability, name it after that responsability.  If the class is an implementation of a certain design pattern, make the classname indicate so.  Try to adher to the company and generally accepted naming conventions, and don’t be afraid to give a long and descriptive name, without exagerating… ( BLTSandwichBuilder is better than ClassThatCreatesASandwichWithBaconLettaceTomatoAndMayonaise).

Keep your classes open for extensibility, but closed for modifications.

The second one of the five SOLID design principles, states that it should be possible to change the core behaviour of your class without modifying the code.

Don’t google this principle though…  Although it is a very important one, most of the examples on the net still use inheritance to solve this.  Let’s try out a typical example:

        public class Duck {
                 public string MakeSound() { return "Quack"; }
             }

This class fails to adher to the second SOLID design principle.  When a certain customer has some rubber ducks, it’s impossible to make the rubber ducks squeek instead of quack.  The typical examples would consider this class to be better if written like:

        public class Duck {
                 public virtual string MakeSound() { return "Quack"; }
             }

The intent is obvious, one can now create a RubberDuck class that inherits the Duck class, and change the behaviour for the RubberDucks by overriding the MakeSound method.

 public class RubberDuck : Duck {
         public override string MakeSound()
         {
             return "Squeek";
         }
     }

Nice try, and it does allows to change the behaviour of a duck without having to modify the Duck code, but the solution is a bit 1990…

Favor composition over inheritance.

Inheritance is a dangerous thing.  It tightly couples the child class (RubberDuck) to the parent class (Duck).  In our example, what if someone adds a new method to the Duck class:

        public class Duck {
                 public virtual string MakeSound() { return "Quack"; }
                 public void Fly() {/** Make it fly here... */ }
             }

Without knowing (after all, your RubberDuck class might be in a totally different assembly, for another customer, which you don’t know about!), the developer that added the Fly method, also gave your rubber ducks flying power.  Last time I watched national geographic, rubber ducks don’t fly.

At this point, let’s correct our duck, by adding one of those behavioral design patterns (strategy pattern) and see if the Duck class improves.

First work is to define an interface callled QuackBehaviour.

        public interface IQuackBehaviour {
                 string MakeSound();
             }

Next step is to change our Duck class a bit.  In the constructor we’ll take in the IQuackBehaviour, and an IFlyBehaviour (code emitted due to being lazy) while we’re at it…

        public sealed class Duck {
                 private readonly IQuackBehaviour quackBehaviour;
                 private readonly IFlyBehaviour flyBehaviour;
                 public Duck(IQuackBehaviour quackBehaviour, IFlyBehaviour flyBehaviour)
                 {
                     this.quackBehaviour = quackBehaviour;
                     this.flyBehaviour = flyBehaviour;
                 }
                 public string MakeSound() { return this.quackBehaviour.MakeSound(); }
                 public void Fly() { this.flyBehaviour.Fly(); }
             }

Our class has come a long way from the inital draft and looks a bit more complicated, but it did completely eliminate the need of a RubberDuck class…

            var mallardDuck = new Duck(new QuackBehaviour(), new FlyBehaviour());
            var rubberDuck = new Duck(new SqueeckBehaviour(), new NoFlyingAllowedBehaviour());

Our Duck class now adhers to my three first rules of thumb, it has one responsability (to delegate to the concrete behaviour), it’s open for extensibility without having to modify the code (just pass a new IQuackBehaviour or a new IFlyBehaviour in the constructor), and it favors composition over inheritance.  On a side note: C# specifically, provides lambda expressions as a quick alternative to the single-method interfaces above to implement a strategy pattern.

Design for inheritance, or else prohibit it.

Favoring composition over inheritance does not imply one should never use inheritance.  There are still plenty of valid classes where inheritance can be of use, especially when creating “base” implementations for a particular interface (such as “NotifyPropertyChangedBase”, “EntityValidatorBase”, …).  With every class you make, you should think if this class might fit in an inheritance tree, and, enforce your intent.  If your class is ment to be a base class for a child implementation, make it abstract.  Even if it doesn’t have any abstract methods, you can still make it abstract, signalling to the user (the developer of the child implementation) that you thought about inheritance, approve for child implementations to be made, and you will not make breaking changes to the base class that might, unexpectedly, change the behaviour of the implementations.

If not, or if you didn’t bother to think it through, make your class sealed.  A beautiful choice of naming, this c# keyword, “sealed”.  It signals to the user that your class is at the bottom of the inheritance tree, and one cannot simply create a child implementation without breaking the seal (and hopefully: consider the concequences…).

Liskov substitution principle.

(Clarified after a comment by a colleague and good friend of mine, thanks!)

Third of the SOLID design principles is extremely easy to adher to, but hard to explain.

It basically comes down to the idea that when one thing “is” another thing in the real world, it doesn’t mean that it is necessarily a good idea that one class “inherits” from another class.

Liskov Subtitution Principle

The example I personally found best is the example of a “3d game board”.  One would easily think that a “3d game board” is a “game board”, and thus it would be a good idea to have the 3DGameBoard class inherit from the GameBoard class.  The unfortunate thing is that the GameBoard method “MoveUnitTo(int X, int Y)” can no longer be correctly called on the 3DGameBoard implementations, because those require the notion of the Z-value…  The 3DGameBoard is conceptually so different from the GameBoard class, that it can not be used as a substitution for the latter.

Adhering to the rule is easy…  Favor composition over inheritance, design for inheritance or else prohibit it, keep your inheritance tree shallow (and think about whether one class really “is a” subtype of the parent class), and design by contract…

O yea… Interfaces…

Use interfaces.

Everywhere, always.  Design by contract, not by implementation.  They make your application less tightly coupled, easier to test, and allow you to express your intent more easely.  And while you’re at it, try to look for a standard interface (defined in the .NET framework) before trying to create your own.

        private void AttachDirtyListener(INotifyPropertyChanged propertyChangedSource)
             {
                 propertyChangedSource.PropertyChanged += new PropertyChangedEventHandler((o, args) => { isDirty = true; });
             }

Have a look at the code above.  In this piece of code, I don’t care what implementation gets passed in.  It can be a screen, a user control, a domain object, a DAO, I don’t care.  If it changes a property, I get dirty.

While we’re at it, let me throw another piece of smelling code at you for the next couple of my rules of thumb…

Assume something happens in your application, and that something has a severity…

        enum Severity{ Low, Medium, High, Critical }

Let’s try to determine the action to take according to the severity…

            IAction actionToTake;
            switch (severity) {
                 case Severity.Critical:
                     actionToTake = new CompositeAction(Action.InformThePolice).AndThen(Action.HaltTheApplication);
                     break;
                 case Severity.High:
                     actionToTake = new CompositeAction(Action.ShowMessageToTheUser).AndThen(Action.WriteLogStatement).AndThen(Action.ContinueTheApplication);
                     break;
                 default:
                     actionToTake = new CompositeAction(Action.WriteLogStatement).AndThen(Action.ContinueTheApplication);
                     break;
             }

Beware of the var keyword.

If you would change the first line to use the var keyword, (var actionToTake;), you will get compiler errors that the compiler cannot infer the type of actionToTake.  Let me be clear that there is nothing wrong with using the var keyword itself, however, one should be aware that during compilation, the compiler will replace the var keyword with the inferred type.  So in the end, you are strongly coupling your declaration to the actual implementations.  Granted, the easy and speed of writing code with the var keyword outweighs the downside of this, just be aware that you are doing it.

Avoid switch statements.

In fact, try to avoid writing switch cases altogether.  Usually, when you write a switch statement, you’re putting the responsability in the wrong place.  When you write a switch statement, (or a lengthy if-else statement, or even a short one), you’re trying to do things “on” or “with” the objects, which is ok in a procedural language, but not in an OO one.  In an OO world, you simply ask the objects to do something, and the result will change based on the current implementation.

In our Duck example, I could have putten a switch statement in each of the methods, trying to determine the correct sound to make based on the type of duck, where it’s better to just delegate this process to an IQuackBehaviour implementation, and making sure the right ducks receive the right behaviour.

But if you must, avoid the default case pitfall.

If aliens kidnap your family, and threaten to kill them and all other life on earth unless you write a switch statement (any other reason why you’d want to write one is beyond me), do not write a default case for your switch statement.  The reason again is quite logical, in our Severity example above, imagine someone adds a new type of Severity…

        enum Severity{ Low, Medium, High, Critical, LifeThreatening }

Since we wrote a default case in our switch statement, any life threatening situations will be handled by logging the statement and letting the application continue. Is that really the bahaviour we wanted?

Some development environments or coding tools will offer a check on this: “Uncovered enum constant in switch statement”.  Because you don’t write a default case, it will check if all of the enum constants are covered by the switch statement, and if not, throw a compilation error.  This implies that you will get a compiler error if a new constant is added to the enum.  If you’re not working with the correct tools that can check this for you, at least have the decency to write your default case along the lines of:

                default :
                         throw new UnrecognizedCaseException(severity);

This will halt your application at runtime, which isn’t as nice as noticing the bug that life threatening situations will be handled the same as low severity ones at compile time, but is still better then letting it slip unnoticed.

Realize there are alternatives to a switch case.

A nice trick a colleague showed me, is that you can write an entire application without any “if-else” or “switch” statements.

There’s one question on StackOverflow on how to handle a “300+ case switch statement”.  Let me show you my version of a “2 billion case switch statement”:

            Dictionary<Severity, IAction> actionsToTake = /**Initialize dictionary*/;
                 if (actionsToTake.ContainsKey(severity))
                     return actionsToTake[severity];
                 else
                     throw new UnrecognizedCaseException(severity);

The actual switch statement is really short, and initializing the dictionary can be done using convention or configuration, where that responsibility belongs.

Use enums for readability, not for behaviour.

I don’t like the use of enums because they do tend to lead to the programming style I described above: doing things “on” the objects (often in large illegible switch cases) instead of asking the object to do something for you.  However, I do like enums because they increase the readability of your code.

Consider the process of showing a certain window…

            ShowWindow(myWindow, true, false, 4, 3, 1, 0);

Try to tell me, just by looking at that one line above, what exactly will happen.

            ShowWindow(myWindow, WindowState.Normal, WindowStartupLocation.CenterScreen, WindowStyle.SingleBorderWindow,
                 WindowModality.ModalToEntireApplication, Buttons.OkCancel, Sounds.Beep);

Now compare that to the line above and try again.

Magic numbers

Similarly… (thanks n3wjack for pointing that out.) We work in a binary world, so any code that contains the number 0 or 1 is ok, and any colleague that reads your code won’t have any problem understanding it.  However, when you are working with numbers, give your numbers a name.  This doesn’t mean anything to anyone:

            public decimal Calculate(decimal value) {
                     return value / 768 * 100;
                 }

Change this to:

            const int SPEED_OF_SOUND = 768;
                 public int Calculate(int currentSpeed) {
                     return currentSpeed / SPEED_OF_SOUND * 100;
                 }

And your code just became “self-explanatory” (without the need for code comments aswell…).

Use fluent interfaces only to replace optional parameters.

If you never heared about fluent interfaces, chances are you’ll do a google right now, think they are amazing and use them at the very next possibility, and every other opportunity hereafter.  I know I did, fluent interfaces are so cool I just had to use them.  The basic idea is that some methods, especially when building large objects, may need an exceptionally large number of arguments, not all of them required each time.  In the code above, with the “large” switch statement, I used a fluent interface to create a CompositeAction (“AndThen(…)”).

Due to lack of inspiration, let’s consider one of the most traditional examples: the constructor of some kind of pizza.  Each pizza needs a number of minutes to cook, a prize to sell it for, and an unknown number of ingrediënts.  One can also choose a special crust type, but not for small pizzas (business rule). A first attempt could be done by creating constructor overloads:

            var pizzaHawai = new Pizza(7, 15.50, "PlainTomatoSauce", "Pineapple", "Ham", "Cheese", Size.Small);
            var pizzaBbq = new Pizza(9, 21.00, "BbqSauce", "Chicken", "Beef", "Onion", "Peppers", 
                    "Cheese", Size.Large, CrustType.Cheesy)

The number of different constructors needed however, depending on the situation, might become enourmeous and also complex because of the extra check that a crust type can only be specified for medium or large pizzas.  A better implementation here, would be to create a fluent interface, and replace the code a such:

            var pizzaHawai = new PizzaBuilder().SetCookingTime(7).SetSize(Size.Small)
                     .AddTopping("PlainTomatoSauce").AddTopping("Pineapple").AddTopping("Ham").AddTopping("Cheese")
                     .ForPrize(15.50).Build();
            var pizzaBbq = new PizzaBuilder().SetCookingTime(9).SetSize(Size.Large).SetCrustType(CrustType.Cheesy)
                     .AddTopping("BbqSauce").AddTopping("Checken").AddTopping("Beef").AddTopping("Onion").AddTopping("Peppers").AddTopping("Cheese")
                     .ForPrize(21.00).Build();

More readable, true, but we still have the problem that we can select a crust type for small pizzas, and we introduced a new potential problem that it is possible to “forget” some mandatory parameters (method calls), for example the “ForPrize(21)” one, and serve free pizzas as a result.  I found some interesting implementations on the web that require a “validate()” method to be (implicitly or explicitly) called, which throws an exception at runtime for both the invalid state situation of forgetting to set the state, as the situation of setting the crust type on a small pizza.  A better attempt, would be to check this at compile time, by adding the required arguments to the constructor of the PizzaBuilder or the Build method, and having the optional arguments in a fluent interface style.

            var pizzaHawai = new PizzaBuilder(7, 15.50)
                     .AddTopping("PlainTomatoSauce").AddTopping("Pineapple").AddTopping("Ham").AddTopping("Cheese")
                     .BuildSmallPizza();
            var pizzaBbq = new PizzaBuilder(9, 21.00)
                     .AddTopping("BbqSauce").AddTopping("Checken").AddTopping("Beef").AddTopping("Onion").AddTopping("Peppers").AddTopping("Cheese")
                     .BuildLargePizza(CrustType.Cheesy);

In short: use fluent interfaces only to deal with a large number of optional parameters, don’t brute force the style where it doesn’t offer any benefits.

Keep your interfaces small.

The fourth of the SOLID design principles states that if an interface becomes quite large, you should consider splitting it up into seperate, smaller interfaces.  I fail to see how your interfaces can ever become quite large, if you keep the single responsability principle in mind.

The Hollywood principle.

The last of the SOLID design principles, the dependency inversion principle, got nicknamed the Hollywood principle: “Don’t call us, we’ll call you”.  The rule of thumb here is easy: never call a constructor (unless it’s the sole responsability of your class: creational design patterns) .  If you need to do something with an object, either ask for it as an argument or in the constructor of your class.  It’s either your responsability to do something with the object, or to create the object, not both.  Consider:

        public class MessageSendingExceptionHandler : IExceptionHandler{
                 public void Handle(Exception x)
                 {
                     IMessageSender sender = new EmailSender();
                     sender.SendMessage(x.Message);
                 }
             }

The MessageSendingExceptionHandler has two responsabilities (creating an EmailSender and sending the message), it can never handle an exception in any other way than to send it away with the use of an EmailSender, violating both the “open-closed” and the “Liskov substition” principle.

A nicer implementation would be

        public sealed class MessageSendingExceptionHandler : IExceptionHandler
             {
                 private readonly IMessageSender sender;
                 public MessageSendingExceptionHandler(IMessageSender sender)
                 {
                     this.sender = sender;
                 }
                 public void Handle(Exception x)
                 {
                     this.sender.SendMessage(x.Message);
                 }
             }

Now you’re talking.  It’s the responsability of whoever creates the MessageSendingExceptionHandler (a builder for example) to give an IMessageSender implementation, which in turn can just delegate that responsablity to the object that created the builder, and so on.

MEF (in an abusive but effective way), Ninject, Spring.NET, … There’s a large variety of dependency injection frameworks, pick one, learn it, use it, love it, never think about it again.

Trust others as you would trust yourself: not.

Another anti-pattern I once got into was checking for null references everywhere.  The MessageSendingExceptionHandler above I would once have written like:

        public sealed class MessageSendingExceptionHandler : IExceptionHandler
             {
                 private readonly IMessageSender sender;
                 MessageSendingExceptionHandler(IMessageSender sender)
                 {
                    if(sender != null)
                        this.sender = sender;
                 }
                 public void Handle(Exception x)
                 {
                     if(this.sender != null)
                         this.sender.SendMessage(x.Message);
                 }
             }

Completely free of application crashes due to nullpointer exceptions, true, but the behaviour of this class is quite unreliable now: no message might be send, and no one will know about it.  When you get that reported as a bug by the way, it takes quite some debugging before you accidentely find out what’s going on. A null reference, is a programming mistake.   Humans make mistakes, nothing to be ashamed about, but it’s better to find out your mistake by having the application crash (hopefully during testing phase), than to try and hide your mistake and introduce unreliable behaviour instead.

Therefor, my personal rule on checking for null references (or other validations): do not trust others, and do not trust yourself.

Not trusting others comes in the form of checking arguments on the first line of the implementation of public methods.

Not trusting yourself comes not from not your inner state everywhere and trying to quietly move along, but make sure that when you are in an invalid state, you’ll know it when it happened, and where it happened.  You application will fail either way, but at least it fails fast and precise.

        public sealed class MessageSendingExceptionHandler : IExceptionHandler
             {
                 private readonly IMessageSender sender;
                 MessageSendingExceptionHandler(IMessageSender sender)
                 {
                     if (sender == null) throw new ArgumentNullException("sender");//Do not trust others
                     this.sender = sender;
                 }
                 public void Handle(Exception x)
                 {
                     if (x == null) throw new ArgumentNullException("x"); //Do not trust others
                     this.sender.SendMessage(x.Message); //Do not trust yourself
                 }
             }

Everytime you write the word static, god kills a kitten.

        public static void Main(string[] args) { }

In each application, there is the static method above, usually auto-generated, which is the “entry point” of your application.  Besides this one occurence, you should never write the word static.  In fact, I would be happy if my entire team worked on keyboards that emit a 2000V shock to the developer each time he or she types the letters s, t, a, t, i and c consecutively.  Static methods will make you violate the substitution and the Hollywood principle, making sure your application is as tightly coupled as *insert reference to Margaret Thatchers butt cheeks here*, and static fields are even worse: they allow you to save state from one test run to another, so that one of your unit tests might only work if you run another one first…

Extensive use of static constructs is one of my dissapointments in the LightSwitch framework, which makes it very hard to create very complex extensions, like replacing the “user and roles” with something more manageable in a large LightSwitch application.  It’s really easy to refactor that out though (use a wrapper around the static call, and inject that wrapper or a custom implementation instead), so I hope in the next version there will be a couple of minor changes like that, opening a new world of opportunities…

The singleton anti-pattern.

Yes, you, bully of my beloved “Hello makker” teammember, this one is for you.  The Singleton pattern is an anti-pattern that should be avoided.  Even if you did read an awesome implementation using enums (which wasn’t even true until java 1.6 where they restricted the creation of new enum constants using reflection…), in Joshua Bloch’s otherwise amazing book Effective Java.

It violates the single responsability pattern (it has the responsability to do something and the responsability to restrict the number of instances to just one), it tightly couples the caller to the singleton implementation (Litskov substitution principle) and thus also violates the Hollywood principle.

Every dependency inversion framework has some kind of option to create “just one instance” and return the same reference over and over again, and that’s where that responsability belongs, not in the caller, nor in the actual implementation.

Don’t get me wrong, there’s nothing wrong with the idea of having “just one instance of a class in your entire application”, it’s just a bad design to try and enforce that in the same class that gets instanciated, so unless you design for smelly code, it’s an anti-pattern, not a design pattern.

DRY – Do not repeat yourself.

Imagine a user of your software is looking at a customer in your software and finds out he has no way of keeping track of the customer’s birthday, and wants you to add that.  If this change request means to you: manually update the View, ViewModel, Model, process service request object and implementations, capability service request object and implementations, shared validators, repository or DAO and database, then you probably DIE ( = duplication is evil) a bit with every little modification in your application. There is nothing wrong with this kind of architecture, the accent is on the “manual” here.  You are not relying on the correct tools to help you with it, and thus killing your productivity.
LightSwitch for example, is one of the best examples on correctly implementing DRY.  Adding the birthday to a customer is a two step process: add the field to the customer model (in the applicationdefinition.lsml, using the graphical editors provided), and add them to the screens where you want to show them.  The effect of that is changes to the model, viewmodel, view, WCF services, validators, EF, database changes, …

There is nothing wrong with having code generation or other tools help you, in fact, not using tooling, even for code generation, is a handicap.

YAGNI

YAGNI is an acronym of “You ain’t gonna need it”.  Basically, it means that one should only design for or spend effort in forseeing, the “known” future.  There is only one “known” future: the more time you spend preparing for possible changes, the higher the chance your customers will require the one change you did not forsee, and the harder it will be to actually implement that change (it’s Murphy’s law, applied to coding).  Keep it simple, silly (KISS).  This does not mean that straight-forward procedural programming is preferred because it is simple to accomplish fast results (if you thought that, go back to the top and read again), it only means that each line of code you write should have a reason to exist in the here and now (or the tomorrow… But not on “some day”).

/**Don’t comment my code, it was hard to write, it should be hard to understand*/

There’s two posters hanging in our office, the first states the title above.  Everyone, except some funny colleagues, hates to write code comments.  I do too, for three reasons.  Have a look at our class above, this time with code comments…

        public sealed class MessageSendingExceptionHandler : IExceptionHandler
             {
                 private readonly IMessageSender sender;
                 MessageSendingExceptionHandler(IMessageSender sender)
                 {
                     //If the argument called sender is null
                     if (sender == null)
                     //we should throw an argument null exception to inform the caller.
                         throw new ArgumentNullException("sender");
                     //else...
                     //We're going to store the argument in our private field so we can call it later.
                     this.sender = sender;
                 }
                 public void Handle(Exception x)
                 {
                     //If the exeption is null
                     if (x == null)
                     //We should throw an argument null exception to inform the caller
                         //throw new ArgumentException("Agument exception is null!", "x");
                         //^^ EDIT JVH: there's a specific exception called ArgumentNullException, using that instead
                         throw new ArgumentNullException("x");
                         //TODO AC 1/11/11 : this if case is never covered by unit tests 
                         //TODO DC 2/11/11 : write the tests please
                         //EDIT JVH 5/11/11: wrote the test, it's covered now.
                     this.sender.SendMessage(x.Message); //Send the message of the exception with the message sender.
                 }
             }
  1. Commenting out code sucks.  You (hopefully) work with an advanced source control system, which is specialized in keeping track of versioning and history.  Don’t comment out your code, delete it.
  2. TODO’s.  Now really, is your code base the best place to keep track of your TODO’s?  What happened to the backlog / outlook tasks / a sticky note on your screen monitor?  All of these are better places to keep track of the work you still need to do, your code base is ment for code, not TODO’s…
  3. Explaining your code.  If your code needs comments to be explained, there’s something wrong with your code, go back to the start of this post and try again.  Fix your code, don’t make it even more eligible by adding even more (green) lines.

First make it work, then make it right, then make it fast.

The latter of the two posters, sums ‘my development process’ up quite nicely.

First make it work.  Write an automated test (you do know unit tests right?) with the desired behaviour, the desired outcome of the code you’re going to write.  Then, code untill your tests pass.

Then make it right.  Make sure your code is solid (S.O.L.I.D) (although this becomes more then a state of mind instead of a “phase 2: make it right”), ánd legible.  Never be afraid to show your code to the cantine lady.  If she understands any of it without having any coding knowledge, it’s good enough.

Then make it fast.  The biggest pitfall of all.  Unless a) there were non-functional requirements regarding speed and the load tests show you didn’t meet them, or b) a customer complains about the speed of the application,  your code is fast enough.  Trust me, there’s a good chance you’re not in the Battlefield 4 game engine team, but writing b2b CRUD applications where no one notices the 2 ms speed improvement that took you four hours to make.  If you really are in a situation where you really need some really big speed improvements, really, than know that a) hardware is cheaper then peopleware (software engineers cost a lot by the hour!) – sometimes an application is best optimized by putting it on some better hardware, and b) profiling tools will be your best friend.  Don’t look at your code and attempt to guess where the speedup loop is…

In summary…

A friend of mine, a consultant, walked into a company once.  (All good stories start like this, don’t they?) He was greeted by the team leader, who introduced him to the team.  One of the team members, Bob, according to the team leader, was the best developer the company had ever had, in fact, he was so good that none of the other team members were capable of understanding a line he wrote.
Bob is not the best developer in that company.  In fact, he is the worst.
LESS is more: legible, extensible, solid and simple.

On a more personal note: yes I know again I have been too quite on my blog lately, I have had a lot of major changes in my life lately, I just wanted to state that LightSwitch and my blog followers are still very close to my heart, and I long to make more time for you again!

Advertisements

8 thoughts on “Coding is optional: A random walk down OO Road (LESS is more).

  1. Wow. That’s great, but you might have to arrest me. I’ve must have broken most of your patterns.

    So, is there any hope of rehibilitation? How do I rebuild my life not to mention my classes?

    Please Dr. Jan, what is the next step to get out of this anti-pattern pattern?

    Your faithfull student,
    Dave

  2. Ha.. at least for you guys… ‘coding is optional’. In my job responsibility.. ‘development itself is optional’ :). Patterns & Practices…?? U gotta be kidding me. Opening my VS after 3 weeks.

    Seems like I need a week to understand what the post is about. I wish i’m ur next door neighbor.. Jan. 🙂

    Take ur time and hit us hard……. harder.

  3. Pingback: Metadata driven development (part 2): A thought on software development as it could be… « Jan Van der Haegen's blog

  4. Pingback: Windows Azure and Cloud Computing Posts for 4/6/2012+ - Windows Azure Blog

  5. Pingback: Understanding the decorator pattern. « Jan Van der Haegen's blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s