Saturday, January 17, 2015

I'm Long Term Lazy

Apparently my managers are very happy this year with my performance and what I accomplished.

At the start of the year, I pretty much got full development ownership of several projects... and well there were lot's of issues. Over the year, I proposed and implemented several improvements (among many other tasks) including: automated build and deployment, automated (integration) testing, and application and procedures documentation.

Now the overall benefits are greater stability (less PROD issues), smaller iterations, faster turnaround, and clearer understanding of code... but to be honest, all I really considered was: What's in it for me? how will it make my job easier? How much will it cost me (in effort)?

I think many people under pressure or time constraints just think how can I fix the immediate issue?

While the most immediate and simple solution may work really well, often it's just a quick fix and if you don't do anything else, it will may come back in the distant future as a bigger problem.

My approach is... OK immediate issue fixed, now how do I make sure I never have to deal with this problem ever again or at least greatly reduce the likelihood that I will.

And usually the answer involves all those great benefits that my managers seem to like :)

See... short-term lazy people cut corners and then it usually comes back to bite them with bigger problems.

Long-term lazy people know duct-tape solutions lead to bigger problems and there for invest more time and thought on how to make sure the solution is mostly future-proof.

I'd rather spend 2 days figuring out how to automate our builds, rather than spending 1 day a week (or month) just on packaging and deploying programs.

Or I'd rather spend a week thinking about good design, implementation, and testing out prototypes, instead of 2 days a week putting out Production fires caused by lousy design.

And it's not just time, because usually the longer option is also much more boring.

Sunday, January 11, 2015

Shortcuts and Best Practices

Sometimes you think you don't need to follow Best Practices and that your situation is unique and different.... And that you're the best to judge right since you know the specifics of your current situation right?

... Not quite because most situations change so more often than not, taking that shortcut is going to hurt more than the extra few minutes it would've taken to implement according to best practices.

Trust me... I know... (Below are some personal examples.)

Getters and Setters 

When I first used Getters and Setters in Java, I always wondered why we needed write out the functions specifically, instead of like in C# where you could just use something like:

public string Name {get; set;}

At first, I actually didn't even know why we did this. Why not just use a public variable? Well you quickly realize making everything public is a very bad idea. When an object's field is changed by another object, usually it would like to know about it or have some say in what it can be changed to.

(It also saves you a lot of trouble if the underlying data type changes from like an int to a string, becomes a composite of multiple other values.)

But anyway... why would I ever need to implement it like as below?

Java
private String name;
public void setName(String value)
{
     name = value;
}

public String getName()
{
     return name;
}

Or slightly better

C# (Slightly easier)

private string name;
public string Name
{
    get
    {
         return name;
    }
    set
    {
         name = value;
    }
}


Why does Java make you write you to write it out? It does two things:

  • It shows you how Properties actually work; C# is just automatically creating it when it's compiled (this understanding also helps you realize what a struct backing field is and why you get the related error)
  • It will save you a minor inconvenience in the future where you need to add some validation logic or raise an event... like for INotifyPropertyChanged

Variable Naming

Early in my career and as a hobbyist, I would usually create some local variables for some calculation or formatting logic. But I used vague names for them as, at the time, they seemed trivial or temporary.

The keyword is seemed but as the surrounding code grew longer, very often it became less trivial: having a variable used like 5 times in some loop that spans over 50 lines of code makes it... not trivial.

Anyway, it saved me a few second at the time, but then months later there is an issue... you go back to the code and you cannot recall at all what this variable (or the function) is supposed to be used for.

If you're lucky you may be able to walk through it and figure it out... after like an hour.

Nowadays names are cheap and with code hinting, not very hard to type out. Use descriptive names and also comment when needed, because while they may not look so nice... they're really cheap.

Using x,y instead of row, col may make you feel smart until you spend 10 minutes trying to figure out if your incrementing a row or column (and sometimes like for an Excel output... that kind of matters... a lot).

Unit Testing

I work on existing systems, designed not by me. Test-ability was never considered and not a core part of the applications' designs (which also I think contributed to how messy and tightly coupled everything was).

Anyway, because we don't have tests for every possible usage, it is now extremely difficult to make core logic changes. One of the things I am doing this year is figuring out test cases from our usage data and creating automated tests that give us 100% certainty that any change does not alter existing behavior.

Another shortcut that now causes a lot more pain and issues... than it should.

Conclusion

The general thing about shortcuts is that you really need to think about and be able to predict whether or not the shortcut is worth it. For a small application, you can see far ahead and be pretty sure, and the cost of changing it is very low.

For a large and/or critical application or component, I've learned the hard way, from my own coding and from cleaning up other people's messes, that it is just better to not take the shortcut in the first place.

ALWAYS follow best practices, unless you are literally 150% sure the shortcut is worth it.







Software Development Heuristics

While my core strength is C#,  I've worked in so many languages and on various levels  (of the stack) that I've picked up many tools,  paradigms,  best practices, and  other bits of knowledge and experience.

I'm not sure if I would be considered a full-stack developer,  generalist or something else, but whatever you call, I've found that these bits of knowledge are what really makes a difference, especially when tackling new problems or issues. Particularly when things come together such as:

  • Experience and confidence in searching for existing solutions
  • Ability to evaluate choices and utilize the appropriate frameworks, because of similar situations in other languages or projects such that you can foresee future issues or outcomes
  • And most of all when small bits a pieces of information literally come together and leads you to an elegant new solution either by guiding your thought process or in an actual AHA! moment (I do a lot of the former; have had some of the latter, usually after thinking about a problem all day and just when I'm about to fall asleep)
You could call it experience but I think it's a bit different:
  • Being really good at one specific thing would not yield this result
  • It's more like being decently or really good at one or a few things BUT also have a some knowledge of a bit of everything else, which guides you in analyzing new problems, AND the ability to look further when needed to evaluate potential solutions or ideas

I suppose it would be more of an entrepreneurial mindset as that's where innovations come from: very often it's taking multiple existing ideas and putting them together and then adding something else.

For me particularly, it started by learning different languages and programming approaches from functional programming, to MVC/MVVM, JSON syntax, Java anonymous classes, etc.

Coupled with constantly being faced with similar issues and needing similar solutions, those experiences led to learning design patterns. And other experiences led to my explorations in testing and mocking frameworks.

But all along the way you may collect these bits of knowledge, which you may quickly forget the specifics because of non-use, but at least the general ideas and key concepts remain, and that makes a huge difference. They are what I would call heuristics.

They guide you when analyzing problems because you now know what is possible and you have more options to choose from. More importantly, you can quickly evaluate new and similar options and your past experiences will produce questions that should be answered. Or something like, Hmm... MVC might be useful here; I'm a bit fuzzy on it but I should look into this instead of just going ahead and start writing code.

A lot of times now when given a new problem, I find myself thinking at this higher level: I need to do  A,  B,  C.  What tools should I use to best accomplish these or where should start looking for the most appropriate solution? Do I write my own code or can I not reinvent most of the wheel?

I guess it's not restricted to programmers and is basically what you would call an expert: you know things and you can  put them together to come to conclusions in a variety of new situations.

My broad background helps me look for solutions in some creative places or when given something new,  a general framework of questions to figure out what to do.

And I guess it's also a productivity thing too: you are basically building on previous knowledge,  so you don't have to start from scratch each time. This makes you a much more efficient and versatile developer.

Friday, January 2, 2015

Using Anonymous Functions in C#

Recently started using a lot more anonymous functions in C#... probably due to JavaScript and Java's influence.

The first caveat with anonymous functions though is that they cannot be debugged. The whole block is basically a single command, you cannot step in while debugging.

I think that is also true in the other languages as well and related to how it's compiled.

So generally I would recommend you keep the functions in them small and simple, such as simple sorting or transformation logic.

You can replace any delegate parameter (including Predicate, Action, or Func, basically anything that wants a reference to a function) which an anonymous function.

For the 3 "special" types:

  • An Action again takes in 0 or more parameters and does something, returning no value.
  • A Func takes 0 or more parameters and returns 1 values.
  • A Predicate is a Func that usually returns -1, 0, 1 which defines the order between two input parameters.

http://stackoverflow.com/questions/4317479/func-vs-action-vs-predicate

If the anonymous function takes 0 parameters, you can pass it:

() => DoAction(someParameterInTheCallingFunction);

Sorry... can't remember a specific example... but it usually involves creating function calls which will be executed by another object that doesn't expect to pass it's own parameter values.

Or a you could define a block of code. I don't recommend this unless the block is small and pretty simple; the likelihood of debugging very close to 0.

() =>
{


}


If not, you can create a separate function matching the delegate signature and pass the function name as  the parameter itself:

MethodThatAcceptsFunc(DoSomething)

If you do that, you can debug the elements in the method body.

If the delegate accepts one or more multiple parameters like Func<object, int, int, int>

Use (int1, int2, int3) => return DoSomething(int1,int2,int3));

The signature for DoSomething would be object DoSomething(int a, int b, int c) and again you could just pass in the method directly.


Android Phone Keeps Rebooting When Powering Off

I've noticed a few times that when I try to turn off the phone with the Shut Down button, it restarts instead. I'm guessing there's some software bug which may or may not be related to my rooting the phone.

The reason I need to shutdown is because either because I'm low on power and I need to save what's left or it doesn't charge when plugged in... 

Usually, the "Power Off" command doesn't work so I would take out the battery, forcing it off. However, I have to take the phone out of the case and even then it's not the easiest thing to do when you're standing on a train (and you need to turn it off to save whatever power is remaining).

Well if you're rooted, you can restart into BootLoader (precise steps vary, but CyanogenMod has an Advanced Reboot menu where I can just tell it to restart into BootLoader). Once rebooted, one of the options is "Power Off". Selecting that seems to do it... which also suggests it's an OS related issue.