Bill Yang's Weblog

Sharing my thoughts on software development

Thursday, June 5, 2014

Angular Directive Isolated Scope binding cheatsheet

1. "@"   (  Text binding / one-way binding )
2. "="   ( Direct model binding / two-way binding )
3. "&"   ( Behaviour binding / Method binding  )
4. "=?"  ( Optional model binding, outer scope does not have to have the corresponding scope variable )
5. "@", then add observe/watch in the directive  ( Text / one-way binding, but will update inner scope whenever the value changes, as opposed to passing it into directive like a parameter once )
http://www.undefinednull.com/2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/

Monday, May 26, 2014

How to hide "You May Know" section in Google+

Unlike many others, I do like G+, I use hangouts a lot, both for work and with friends. Of course, it is not used for the same purpose as Facebook, and I have no need to connect and share stuff with friends here.

But this annoying "You May Know" section would keep suggesting personal contacts to me, heck, I'm not going to go through my extended contact list (which google has, from my phone contacts) and add everyone to my G+ circles. That is madness, and there is no setting to make it go away.

Anyways, I finally had enough today, and found a lot of people were recommending Adblock Plus, which seems to be the easiest way to get rid of this unwanted feature. It's quite simple, once Adblock Plus is installed, go to its options tab -> Add your own filters, and add following filter:

plus.google.com##div[guidedhelpid="friendsuggestions"]

Then you are good! The damned "You may know" box is gone from google plus... for now.

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.