Friday, July 21, 2017

On software development and discovery

Excellent article about software development: http://www.developerdotstar.com/mag/articles/reeves_design.html

Monday, June 6, 2016

Thinking about abstractions

Begin by coding abstractions for the concepts of your application before you write the application itself.

When writing a Object Oriented program, your unit of abstraction is an object. This is important, although fairly straightforward. On every paradigm, what rules it is its unit of abstraction: on procedural languages, the abstraction is a procedure; on functional languages, the main abstraction are functions; And, if I may say, on LISP-style languages, the main abstraction are lists.

Abstraction are very important to computer development. A computer is made of such, otherwise, it would be impossible to deal with all the complexity that it englobes. It's something very particular to the field of Software Development. A civil engineer thinks of bricks and mortar. A doctor does think about cells, organs, and other basic stuff that make up our body. (of course, a quark is the most non-abstract way for thinking about anything, and if a doctor thinks of organs, he's not thinking of cells individually -- still, organs abstract over very little when thinking about a living organism).

A computer is simply a machine that runs instructions written on a memory one-by-one, so it's formed by three basic components, the memory which is a "string" of bytes, a program counter that points to a location at this memory, and the CPU which executes the instruction at the location where the program counter is pointing to. Given this, we could program anything ever, but the complexity would be unmanageable.

So we come up with abstractions. Instead of memory locations, we have variables, pointers maybe or references. Instead of a program counter, we have lines on a text editor.

Back to OOP, as soon as you can realize a abstraction is part of your program, you should create a class for it. No abstraction is smaller than a class in OOP; A bunch of methods loose within some other class aren't. However, you can build abstractions from other abstractions, so objects can be made of other objects.

An example: let's abstract over a INI file:

class IniFile
{
    public IniFile(string fileName)
    {
        // ... open a stream, and read the file if it exits
    }
   
    public string Get(string keyName)
    {
        // returns a value based on the key or null
    }
   
    public string Put(string keyName, string value)
    {
        // Store a key/value pair
    }   
   
    public void Save()
    {
        // Write the file back to the disk
    }
}
Now, this is a simple example; We can build a better abstraction than that using other language features, but it doesn't matter. The main benefit of the abstraction has been leveraged: clients of this code don't have to think about how the IniFile works:
class Configurator
{     private const string _properties = @".\config.ini";       public Configuration GetConfiguration()     {         var ini = new IniFile(_properties);         var url = ini.Get("URL");               return new Configuration { Url = url; }     } }

Let me rephrase all that:
The main benefit of using proper abstractions is that you can focus your thoughts. When coding the abstraction itself, you do not need to consider the rest of the application, only the abstraction (the IniFile above cares not if it's part of a Instant Messaging app, a game, or a scientific experiment). When coding the clients of the abstraction, you do not need to care how it works internally -- abstractions are opaque -- so you can focus on whatever the client needs to do.
If for some reason your clients have to look inside your abstraction, violating it's principle, we have a leak abstraction and it should be reviewed.

When designing your abstractions an important factor to consider is coupling. Whenever an abstraction depends (uses!) another, it's coupled to it. So when the depended abstraction changes, the depending abstraction also changes. So it's important to reduce your dependency graph on your abstractions. The most common abstractions should depend on nothing but frameworks libs, which are your building blocks.

(however, coupling is, ultimately, inevitable; our responsibility is to make our couplings loose instead of tight)

Finally, abstractions can backfire. Abstract too much and your program gets difficult to understand. Also, you may create a lot of couplings that, loose or not, make your program difficult to evolve and maintain.

Wednesday, December 30, 2015

Is it possible to instantiate an object from a generic parameter in Java?

No.

The reason I’m posting this is because this question has been asked many, many, many times… and a few more.
And the answer is usually this:
You'll need an instance of the class. The generic type T isn't enough. So you'll do:
class Server <T extends RequestHandler> {
    Class<T> clazz;
    public Server(Class<T> clazz) {
        this.clazz = clazz;
    }

    private T newRequest() {
        return clazz.newInstance();
    }
}
Which lacks the straght no. While the answer above may lead a reader such as myself to believe that you can work around and use Class<T>, this is wrong. Class<T> is a type declaration, but you’ll still need a instance of it to be able to call newInstance.
Now, in c# is rather trivial to do:

class Foo<T> where T : new
{    private T getInstance()
    {
        return Activator.CreateInstance(typeof(T));
    }
}
And, as my long time readers¹ will know, I’m a C# guy. And being that, I expected to be able to do the same in Java. Now, why isn’t it possible? See, Java doesn’t really have generics… It’s implementation of generics is all done in the compiler instead of in the JVM. And this being the case, generic type information isn’t compiled to bytecode (the only answer in StackOverflow I found mentioned it was this one), and exists only during compile time. This is called Type Erasure. Now, Oracle sells it as a good thing (I disagree, of course).

Footnotes
1. As is “nobody”.

Thursday, October 8, 2015

The Cook

Robert "Uncle Bob" C. Martin, in his singular book "Agile Software Development, Principles, Patterns, and Practices" (Amazon), compares refactoring to cleaning a dirty kitchen. The more I think of it, the more I believe its a wonderful analogy for our work.

Analogies, abstractions and metaphors are important, as they help us understand and explain concepts more easily; most of our knowledge is built upon previous knowledge. When the subject is something as abstract as software development, it's even more important to have a concrete example to reason about.

I was used to compare developing software to building houses. It's very easy to reason about the task of house building. Most people have seem a house being built; it's partly art, partly technical; you design first (the blueprint), then you build it. Heck, the term Design Patterns came from the field of architecture. But there were are many failures in the comparison! As one of my managers once put it, one can predict exactly how many bricks¹ it'll be necessary to build the house. But we can't predict how many lines of code, classes, etc. are going to be necessary to create a software: the buildings' blueprint is definite, but no design for a software is, up until you write the code².

Now, let's think about the activy of a cooking. It helps that I don't know much about it - my cooking skills are limited to scrambled eggs, grilled steaks and anything a microwave oven can offer - so I can talk about it as the next guy.
  • When cooking, there are many ways of doing the same thing: you have recipes for doing most stuff, but you can mix and match... You can replace ingredients, you can change procedure... Times can vary, so maybe you will heat the oven for 10 minutes instead of 8... As with writing software, there is always a myriad ways of reaching the same result.
  • Techniques abound.
  • You don't need a college degree for doing it, but specialized education exists and helps.
  • Results are not guaranteed to be the same - you can do the same dish twice, and get very different flavors. And that doesn't mean screwing it up! 
  • Accidents may happen (this is true of any profession, but let's highlight it here, lest we forget).
  • While you cook, you are getting stuff dirty. Later on, to keep on using the kitchen, you must clean this up. This means that while you can get a dish done in less time, you'll pay for it when doing your next dish.
Everything on this list relates to the craft of software. Like cooking, creating software is exciting but hard work. We love it, but it tires us.

And like cooking, it's best we know what we are doing or we may end up ordering delivery.

Footnotes

  1. Houses here in Brazil are made of bricks. Don't ask me why.
  2. I happen to agree with Jack W. Reeves that code is design. But most people don't get it yet, so, let's go with the idea that a class diagram or something is the last stage of design and code is building.

Friday, July 24, 2015

A bookmarklet to open a entity by Guid in Dynamics CRM

So I colleague of mine passed me a number of CRM 2013 bookmarklets that do all sorts of things, like showing the guid of the entity, enabling all fields, removing the business required attribute, etc. The 'god mode' one is the most fun.

Anyway, I decided to write one of mine: a bookmarklet that enables you to open an entity using it's guid. Unfortunately, right now, I ask that you also give me the entity name, but other than that, it's pretty useful while debugging applications that make extensive use of the SDK.

So, without any more delays: get it here.

If you are curious, you can check the bookmarklet code below.

javascript:var entity = window.prompt("Enter the name of the entity to open the default form for:", "");var guid = window.prompt("Enter the guid of the entity to open thedefault form for:", "");var o = new Object(); o.uri = "main.aspx?etn=" + entity + "&pagetype=entityrecord&id=%7B" + guid + "%7D";window.top.document.getElementById("navBar").control.raiseNavigateRequest(o);

Here's the same code block in a more readable way:

javascript:
var entity = window.prompt("Enter the name of the entity to open the default form for:", "");
var guid = window.prompt("Enter the guid of the entity to open thedefault form for:", "");

var o = new Object(); 
o.uri = "main.aspx?etn=" + entity + "&pagetype=entityrecord&id=%7B" + guid + "%7D";
window.top.document.getElementById("navBar").control.raiseNavigateRequest(o);