Sharing my thoughts on software development

Tuesday, March 4, 2014

OOP vs Functional Programming

I have been in several discussions with friends and colleagues about the limitation of OOP and virtues of functional programming. It seems as we push harder for code testability and lower bug rates, it's inevitable that everyone will eventually find the ideas of side impact-less, perfectly enclosed functional programming appealing.

Yet you rarely see business/web applications written in functional languages, and it's not because developers are all lazy.

See, the ultimate goal of almost all software is to solve a problem, it's never about making the most architecturally elegant solution and the most beautiful code in history. And when you focus on how to solve the problem, without worrying about the language, framework, or the programming paradigm you are gonna use, the solution you discover will make most of those technical decisions for you.

When you decide up front that you are gonna use a certain set of tools to a problem you don't have solution yet, you are essentially handicapping yourself, and in many cases will end up with wrapping functional logic with an OOP layer or vice versa.

In short, when you are solving a Sudoku, focus on the god damn Sudoku, worry about unit tests later.

Tuesday, September 17, 2013

Entity Framework Code First Migration Merge Conflicts

One of the major headaches with Entity Framework 5 Code First is merging migrations. Basically, if two developers works on their local branches independently, and both created a migration, merging can be quite a pain. 

The reason is that each migration keeps migration history in its .resx file, and when two migrations are created independently based on the same base migration, EF will only recognize one of the migrations (normally your local one) and go haywire.

In order to resolve this problem, you must manually re-generate your local migrations so they are based on latest migrations from other branches you are merging from, maintaining a single line of history, similar to git rebase.

Here is the step-by-step guide:

  1. Before Merge, take note of the migration you added (MyMigration), and its previous migration (BaseMigration)
  2. Merge branches in git
  3. Open Package Manager Console, and run: UPDATE-DATABASE -TargetMigration:BaseMigration. This will revert your database to the state before any of the conflicted migrations are applied
  4. Delete your local migration (MyMigration)
  5. Run: UPDATE-DATABASE. This will apply all newer migrations done in other branches.
  6. Run: ADD-MIGRATION MyMigration. This will add your local migration based on the other branches' migrations, like git -rebase.
  7. Run: UPDATE-DATABASE. Update database with you local migration.
This also works if you have multiple local migrations, but it will merge them all into a single one.

Monday, January 9, 2012

The simple and yet complex case of KISS

I was blown away when first introduced to KISS principle. At the time, I was frustrated with how overly complicated our enterprise software was designed. It was a rewrite of a legacy system and our architect single-handedly wrote a custom framework on top of ASP.NET MVC framework, with the goal to make it more succinct and extensible.

The only problem, was that everybody was so confused about how it worked, that we lined up to the door of the architect with questions on how to implement particular logic. I carried that bitter taste of over-engineering for a long time, and have rigorously asked myself every time I make any design decisions, if my design was not simple enough...until now.

Today, a very smart and capable colleague criticized a simple piece of my code for being over-engineered, it was a surprise.The problem was fairly simple, so I skipped over things like IoC container, unit testing and the like, implementing only a very simple MVC design, with model layer logic located in separate project, using a single-class Micro ORM (PetaPoco) as opposed to a full-blown ORM.

In my mind, things cannot get simpler than this. Well, technically it can, like skipping the overhead of unit-testability, keeping all logic within single project, using built-in SqlDataReader instead of Micro ORM. However those measures only reduces complexity marginally, while making future refactoring exponentially more difficult. In my book, those are bad trade offs.

What I failed to recognize was that, you see, I have been writing code this way for many projects by now and all those concepts and code structures are intuitive to me. Writing and reading code structured this way is as straight-forward to me as code structured in the simplest possible way (TM).

This was not the case for my colleague.

He has different background than I do, and has grown different habits. All the "intuitive" project structure, the MicroORM, and unit testable code was extra complexity to him. While he recognizes the value of all those things, those are extra complexity that has no potential return due to simplicity of the project.

In the end, after some discussion with him and mental struggle with myself, I got rid of most of the "fluffy" stuff. I also lost the bitter taste for the "over-engineering" architect, after all, the gigantic custom framework that I found so overly-complicated was probably "simple enough" for him.

Lesson learned: Simplicity, like anything, is subjective -- what is simple to one person may not be the same for another. And when working in a team, you have to consider the whole team when making design decisions.

Friday, July 29, 2011

Visual Studio Website Project vs Web Application Project

There probably has been billions of articles written about this topic, and I am no expert who understands the full extent on how the two types of project differ from each other. However, most of those articles are fairly old, and the year 2011 deserves a new article about this topic. :)

So if you are a developer working in a Microsoft shop, chances are you would use at least one of the following: ASP.NET MVC, NuGet, Unity Application Block, Unit Test, Gated Check-in, custom build event/script.

If you use any of those consistently in your projects, it's probably best to stick with Web Application Project, some of them (i.e. ASP.NET MVC) flat out cannot work with Website Project; some would, but requires non-typical setup which you have to investigate and assess.

Conclusion: in year 2011, if you are not sure, use Web Application Project.

Thursday, July 28, 2011

CoffeeScript global variable and @ keyword

I finally managed to pick up CoffeeScript, by writing a small game using CoffeeScript and Canvas. Writing code with CoffeeScript is a very fluent experience, even though I have never used Ruby and have C# background, the syntax feels so natural and code enjoyable to write. All the good things aside, I also got caught by a little gotcha of the language.

In the world of CoffeeScript, global variables must be explicitly declared, using either @ or window keyword, and most tutorials recommend @ due to its succinctness:

@luckyNumber = 4

this attaches luckyNumber into window object and thus accessible globally. The tricky thing is if you do the same declaration in a class:

class MyClass
  constructor: (@luckyNumber = 5) ->

all of sudden, @luckyNumber becomes a property of MyClass, and is not attached to the window object anymore! Now consider following situation:

@luckyNumber = 4
class MyClass 
  constructor: (@luckyNumber = 5) ->

  showLuckyNumber: () ->
    alert(@luckyNumber)

(new MyClass).showLuckyNumber()


Is it going to give you 4 or 5? ... Yes you probably guessed right, it's 5. To access the global variable, you need:

showLuckyNumber: () ->
    alert(window.luckyNumber)

While tricky, this is not exactly a CoffeeScript problem, but weirdness inherited from Javascript. Remember the golden rule: "It's just JavaScript".