2010-08-31

Making crap to hit deadline

Of course this works, and of course the other part (and then cleaning up the mess afterwards) doesn’t. If you have to clean things up afterwards, the only way is to sacrifice your own spare time.

I’ve never been allowed to do “code improvements” after feature perceivably works. “It works, go on with the next task! Can’t you see how far behind schedule are we?”. No one builds the perfect thing first time, and sadly I often find that my newborn code is not of high enough quality to be sufficiently maintainable. This is reality. I can write good code, but only when I spend some iterations improving it. I cannot make it good enough first time. Yes, it may be possible to do this, but only when working on familiar problem nth time. For instance good OO skills may do half the job, but what remains, the problem domain, and I don’t see a way to model it perfectly the first time.

I don’t want to work on the same damn problem for the nth time…

2010-05-24

C# Switch statement & enums

I wish i could write something like this:

void foo(MyEnum e)

{

  switch(e) complete

  {
    case MyOption1:

      bar(); break;

    case MyOption2:

      baz(); break;

  }

}

and expect compiler error is MyEnum also contains MyOption3. Of course, I can add

default: throw new Exception();

but this is not always appropriate when the code is not covered by automated tests. In my case, that’s how it is exactly. Some code similar to above is executed only on rare occasions, so there is little probability that the problem will be spotted by manual testing. And when it is in production, it would rather fail silently than throw unhandled exception.

Of course is is considered a bad practice to litter code with such switch statements everywhere, and bar() and baz() would better be virtual functions on polymorphic objects.

2010-05-17

Semi-Complex code

The codebase I am currently working on has some parts having as I call it, semi-complex logic. It has good names most of times, it adheres to reasonable coding standard, and it actually works. Well, most of time. However, it has copy-paste-alike constructs all around. There are lots of dead / redundant code. And each class has just too many responsibilities. This looks like a kind of code our developers seem to be happy with. Must be because they are most productive producing it. I too seem to be most productive when producing highly-entangled, low level of abstraction code. But in a few past years I settled to opinion that long-term qualities of code matter the most, event for small applications. And hence, nowadays I tend to write code I am not most productive writing, taking time to manage dependencies, eliminate duplication, extract methods. I’m still not that good at it, and of course no one appreciates it. But still I try…

What troubles me about this semi-complex code, is that it carries lots traits of bad code. Most notably, out-of-place dependencies. It suffices to have one wrong dependency, and soon inconveniences start to emerge. Like, having executable module link to seemingly unrelated one. And everyone seems to be OK with it, taking this as necessary evil. Another trouble point is that the code itself is easy to read, but it doesn’t mean you understand how it is working. Because responsibilities are not clearly separated, and some side-effects take place occasionally.

2010-04-27

Exception handling in ASP.NET MVC. Clear the output when returning error view

Today spent half a day figuring out why my error handling code sometimes returns “strange” view, as if error page was rendered inside partial view in which exception occured. Which by the way is exactly what was happening.

Exception handling looked like:

public abstract class MyController : Controller

{

//… other stuff

protected override void OnException(ExceptionContext filterContext)
{

    //log exception
    var exception = filterContext.Exception;              
    var model = new ErrorModel(exception);
    filterContext.Result = View("Error", "Site", model);
    filterContext.ExceptionHandled = true;

}

}

Until finally I found the fix:

public abstract class MyController : Controller

{

//… other stuff

protected override void OnException(ExceptionContext filterContext)
{

    //log exception
    var exception = filterContext.Exception;              
    var model = new ErrorModel(exception);
    filterContext.Result = View("Error", "Site", model);

    filterContext.HttpContext.Response.Clear();
    filterContext.HttpContext.Response.StatusCode = 500;
 
    filterContext.ExceptionHandled = true;

}

}

2010-04-25

Travian

Generally, I don’t like http because of its long response times. AJAX may have improved it a little, but another problem arises: JavaScript, which is also just too slow (not to mention i am really not approving the fact that it’s not compiled – it’s just a waste of memory). However, it has one outstanding feature – incredible availability. And as technology (in terms of http (or maybe whatever replacement protocol Google is building) request response time :) ) progresses, more and more applications will benefit from having web interface.

Travian is quite simple web-based real-time war strategy game. Yet, it earned quite a fame in some previous years. Why do I play it?

  1. I’m just a child. I need games :)
  2. It’s possible to play it at work without annoying those above me too much.
  3. It’s simple. It has simple interface, and simple mechanics. Which allowed it to be quite balanced, in terms of races. Like SC.
  4. It’s social network. No matter how much I despised idea of finding friends online, it seems viable one. It’s due to Travian that I have some certain friends now.
  5. It models war craft & social engineering quite well, IMO.

However, it’s dying. Because of lack of innovation, and some stupid changes, like nerfing Gauls, leading to race imbalances. Also, like other online games, I’ve seen, it carries two drawbacks: $ advantage and bots. While they are finally trying to solve 2nd problem – 1) It might be too late, 2) They may be implementing the wrong approach. The only solution I see to fighting against bots is making them obsolete. Just let everyone do what they are trying to do, or if you don’t have enough resources to be on track - enable plugin system like in Hattrick. But it seems as always, short-term $ is getting in the way :(.

So, in the end greed seems be be ruining in all. To Hell.

2010-04-23

Software, Soft

I’m against attempts to bring discipline to SE akin to other engineering disciplines. Like the SEMAT movement. Software is just so much softer than materials of other engineering disciplines, that it allows for so much more freedom and agility (as indicated by success of agile). Attempts to prevent failures also prevent successes, and leads to stagnation. I don’t mind if someone creates those restrictions for themselves, but just hate when they try imposing such huge restrictions on me. Yes, it’s true in software it’s so easy to shoot yourself in the foot, and such disciplines can help to prevent that from happening. You may say this is an “Adult” approach, as opposed to “childish”. But there is just so much potential in Software, even child cannot embrace it, not speaking about adult. Bad practices will simply go away because they are not working, and there is no need to present me with The One And Only set of right practices, beyond which I should not be looking further. Software principles/guidelines/methodologies/etc should be soft.

2010-04-22

Specification, User story, Test

Specification. Specification can never be complete. There is certain amount of information needed to build a system. If specification contains that much information, it can be the system itself. In this case, system = specification.
But of course this is not very common scenario. Usually, some "business person" describes requirements for the software, in English, and programmer translates it into formal program. Of course we all know that English is ambiguous, and so there are N persons with N views of what a software should do according to that specification. And more importantly, this specification will not be complete, because there is so much a system can do, those thing which one would call “implementation details” actually creep into “specification details”.
The only way I see of using specification as a single source of truth, is for "business person" to write the program himself.
Some solutions that do not work:
1. Take the right programmer, the one who captures the intent of the specification so well, that the ambiguities of what software should do will never arise.
-- people are just so different. When they are left for their own interpretation, each will produce different results.
2. Write specification in some "specification language", understandable by business person.
-- First of all, has anyone seen formal specification language understandable by business person? Second, if that language is not automatically translatable into final program, and human has to make his own decisions for this translation, he will make those decisions. They are not irrelevant, or else they wouldn't be necessary. And there is no guarantee they will do what you wish, because you jus didn't say what you wish - because you don't know what you wish.


User story. So, reasonably sized software system is an input from many people. Each of them is shaping that software in some way. How then to ensure we are building the right system? User stories seems to be the right way. The idea is to capture input from domain expert by small (i.e., manageable) chunks. Each user story tells a story about user interacting with the system. User stories are not necessarily captured all at once, but just some most valuable system aspects, once in a while, when the need arises to move forward.

Test. Sometimes user stories may not be precise enough. This is where automated tests can help. They are the executable system specification – a thing that formal specification fails to achieve. They can do this because they are incomplete specification, only pinpointing some, very small amount of cases. They are the things nailing down your user story carpets to the ground. As with user stories, they are examples of how a system is used.

So. Specification will not work as a single source of truth for a system. Writing specification and requiring that someone else would do “all the dirty work” will fail. Formal specification = program itself. Specification can be used as a starting point. Specification can be used to model some aspects of a system (it may be easier to write them in some formal language which is not executable (like, some nice pictures), but I believe as SE progresses, such cases will be diminishing ). But most of the time, user stories or similar mechanisms, acting as examples of required system behavior – will yield much better results, because people learn by example, and programming is understanding. Finally, if precision of user stories is not enough, automated tests can cover the most interesting cases, nailing down your system so that it won’t be blown away.