Your API should cover all the possible ways to use it

A good API guide your clients toward the right way to use it. Anyway, you should think about all the ways clients can use it, and handle these cases. Here are some examples:

Example 1 - config calss (Java):

class Config {
 public init () {
    // load config from file
 }
 
 public get (String key) {
    // return config value
 }
}

You want the users to call init() and then get(), but what if they call get() without init()? Sure, the best to way would be to force the client into the correct way to use it, and load the config from file in ctor. But let’s say you don’t want to use the ctor. Example: you are using a dependency injection framework that create the class instance for you and you want you client to be able to control when the havy loading happens.

You got two options here:

  1. Throw with a proper message if init is not called
  2. Init the configuration data is not initialized before.

Anyway, don’t leave this case unhandled.

Example 2 - convert module (Javascript):

You got a module that gets an object and convert some of its properties format.

function convert (value){
  //do some conversion and return
}
module.exports = data => {
  data.someProp = convert(data.someOtherProp);
}

With this API, your client needs to know that you are changing the parameter you got (which is debatable by itself). A better way would be to return the changed object, so event clients that use the returned value will get a good result:

A side note: I had a similar case, where I had many calculated fields, and I wanted to force a specific pattern so users can’t misuse the code. Javascript does not offer something a way to prevent function from change its parameter, but I found a nice solution: I added a .jshint file to the calculated fields folder - where all the calc. fields modules are, with one rule:

{
  "rules":{
    "no-param-reassign": ["error", { "props": true }]
  }
}

Basically it says that you can’t modify the function parameter. Eslint supports hierarchy in configuration, so all the other rules from the project .eslintrc file apply in this folder in addition to this specific rule.

Written on August 22, 2017

Comments

Can you solve this puzzle?

Update - the position is not open anymore. you can still answer the puzzle though…


Outbrain is looking for experienced, talented, enthusiastic web developers. You can read about the position here. Interested? Solve this quick puzzle and contact me: roy@royts.com

// We need to create a chat client. 
// The messages pulling policy to should be:

// 1. Get the latest messages from  the server
// 2. Wait 2 sec.
// 3. Back to no. 1 again

// Q: what is wrong with the following solution? 
//    What would be the right way to do that?

setInterval(function () {
 
    $.getJSON( "http://chat-server.com/10/message", function( data ) {
          updateChatWindow(data.messages);
      });
 
}, 2000);
Written on May 18, 2014

Comments

CSS Lazy Loading in AngularJS

_config.yml

The simple way

A classical Angular app starts with a HTML file. In the head tag you’ll put all the link tags for your templates style, and under the body tag you’ll stick the ng-app directive.

The Problem

  1. Every module should be an atomic unit: Each module (controller,template and a CSS) should function as an independent unit. We should be able to take a module out and add new one without major changes to the whole app.

In a classical angular app, with each module template taking in out out you should maintain the link tags in the Head. With many templates this is no a pretty sight…

The right way to too it would be adding the link tag inside the module template file. The problem is that link tag is not allowed inside the body tag, and although it will work, it ain’t going to be pretty.

  1. A template should be able to ask 3rd party style: In addition to it’s own style file, a template may use a 3rd party UI lib (like AngularUI, AngularStrap or a custom directive with a CSS file).

Maintaining this dependencies in the head tag by hand is not a big fun and error prone. In addition, multiple modules can use the same 3rd party lib, and we should make sure to load it’s CSS file only once because browsers are not smart to prevent it.

  1. Sometimes we have no access to the head tag: In our case, this application is wrapped with many JSP templates and pages, and it should be self contained. Touching the wrapping JSPs is not an option.

The first solution

I created an Angular service that can load a CSS file by appending a link tag to the head tag and I’ve using it in the controllers:

angular.module('cssLoadingService', []).factory("CssLoadingService", function () {
  return {
    loadCss: function (url) {
      if (document.createStyleSheet) {
        document.createStyleSheet(url); //IE
      } else {
        var link = document.createElement("link");
        link.type = "text/css";
        link.rel = "stylesheet";
        link.href = url;
        document.getElementsByTagName("head")[0].appendChild(link);
      }
    }
  };
});


function SomeController(CssLoadingService) {
  CssLoadingService.loadCss("style.css");
}

But this is not a good solution. First, it don’t prevent loading the 3rd party CSS files over multiple times. Second’ it is ugly! the CSS let the browser know how it should render the template. It’s place is in the template and not in the controller!

A better solution

I’ve created a new directive and used it in the templates. I added a peace of logic to verify we are loading each style file only once:

app.directive('lazyStyle',
  function () {
    var loadedStyles = {};
    return {
      restrict: 'E',
      link: function (scope, element, attrs) {

        var stylePath = attrs.href;

        if (stylePath in loadedStyles) {
          return;
        }

        if (document.createStyleSheet) {
          document.createStyleSheet(stylePath); //IE
        } else {
          var link = document.createElement("link");
          link.type = "text/css";
          link.rel = "stylesheet";
          link.href = stylePath;
          document.getElementsByTagName("head")[0].appendChild(link);
        }

        loadedStyles[stylePath] = true;

      }
    };
  });

// In the template:
<lazy-style href="style.css"/>

Calculated paths

In my app, we are using a server mechanism to calculate the path to all of our resources, so the href value should be calculated:

<lazy-style href="style/myModule/style.css"/>

The problem is that the directive code is executed before the basicResourcePath is being evaluated which leads to a wrong CSS path. The solution I’ve found is to use the ``$observe` on the attributes to the directive:

app.directive('lazyStyle',
  function () {
    var loadedStyles = {};
    return {
      restrict: 'E',
      link: function (scope, element, attrs) {

        attrs.$observe('href', function (value) {

          var stylePath = value;

          if (stylePath in loadedStyles) {
            return;
          }

          if (document.createStyleSheet) {
            document.createStyleSheet(stylePath); //IE
          } else {
            var link = document.createElement("link");
            link.type = "text/css";
            link.rel = "stylesheet";
            link.href = stylePath;
            document.getElementsByTagName("head")[0].appendChild(link);
          }

          loadedStyles[stylePath] = true;

        });
      }
    };
  });

link to the original post with comments

Written on June 23, 2013

Comments

The damned 'init' method

You probably saw this pattern many times before:

class MyClass {
 public init () {
 ...
 }
 
 public execute () {
 }
}

where the ‘init’ method prepares the object and do things like: loading configuration, initializing internal objects, etc. and the method ‘execute’ do the actual work.

Why is it bad?

Your client (who is using your class) can easily use this class in a way that will broke it. What will happen is he’ll create the instance and run the ‘execute’ method with calling the ‘init’ method before?

Like every piece of code we write, this class has a public API. A good API should direct the user to use it properly, in other words - do what can be done to prevent misuse. The critical information about the right way of doing things inside this class should be kept there as well.

So what is the right way? Well, all the actions that are related to creating the object and the things he need to do it’s job - should be be in the constructor. All the actions that are related to the ‘execute’ method, should be in it.

Finding the right way I can think of situations where the pattern above is a must-have.Still, in most cases it is bad to use it and you can find other solutions that will make your API more solid. For example, in C++ you can’t call a ctor from other ctor so instead of creating many ctors with different signatures you will be tempted to create a set on ‘init’ methods. One solution to this problem is creating a set on private ‘init’ methods and call it from to ctros. (thanks to @danprinz for this example)

Written on October 29, 2012

Comments

Remove the 'i' from your interfaces

_config.yml

Let’s say I’m creating two classes - A and B, when A is using B.

Because I don’t want A to be coupled to B, I’am injecting an interface that B implements.

Until today, even if I had only one implementation for this interface, I created an interface called IB, implement it in B and inject it to A.

The idea of creating an interface just to allow me to change the implementation of B in the future always felt like violation of YAGNI.

Well, yesterday I reached the “Interfaces and implementations” section in Clean Code of Uncle Bob.

He recommends to prevent from adding an I to interface name because the client (who uses the implementation) shouldn’t know that he’s getting an interface:

I prefer to leave interfaces unadorned. The preceding I, so common in today’s legacy wads, is a distraction at best and too much information at worst. I don’t want my users knowing that I’m handing them an interface…. So if I must encode either the interface or the implementation, I choose the implementation.

Then I thought about the fact that there are many classes in Java libraries that don’t starts with an ‘I’ although they are an interfaces: CharSequence , Connection etc.

So, I have decided to stop adding the ‘I’ prefix to my interfaces. This way I can create a single implementation and extract an interface in the future if I’ll need it.

Written on January 3, 2012

Comments