New Year’s Resolutions for Developers

By | Development, Enterprise Mobility

I am not big on New Year’s resolutions, mainly because if you need to change something, don’t wait till the new year, just make the change. While I was driving home from vacation, stuck in traffic, I started wondering what the development teams I work with can do differently in the coming year.  Thinking about what we should focus our energies on,  I came up with some “resolutions” for the new year. As with any resolution or goal, not all are needed to be completed or followed, but as a developer, if you can accomplish any of these, you will improve your development skills and also help teach the developers that follow you.

Read More

System Architecture Design

By | Development, Enterprise Mobility

Whether building a single application or a large application suite, designing the appropriate system architecture is a critical step.  It is not just a technology selection or a collection of system component diagrams or flows; rather a result of decisions based on business, technical and operational requirements that impact the quality, maintainability, performance and successful implementation of an application or application suite.  In more than a decade’s worth of designing architectures for various systems, I’ve found the following key guidelines necessary in the design process, regardless of how you approach system design:

  • Define key requirements and constraints
  • Identify key scenarios
  • Application overview
  • Identify risk areas and potential issues
  • Communicate key architecture decisions

Define Requirements and Constraints

Defining clear and specific requirements up front creates boundaries necessary so you can focus on creating a design that solves for specific objectives.   It is important that these are specific, e.g. “System must be able to retrieve data from systems A and B” versus “System must be able to interface with existing systems.” Nonspecific objectives can take your design down a rabbit hole of designing for a very broad use case.  Constraints must be accounted for in the architecture design in order to prevent surprises down the road that can potentially result in significant time and/or cost.

Identify Key Scenarios

It is also important to identify the key scenarios that are architecturally significant.  These are the scenarios that define what the architecture needs to support and doesn’t necessarily delve into the actual flow for each objective.  Examples of these could be:

  • Login
  • Lookup Inventory Information
  • Update Inventory Details, etc.

App Overview DiagramApplication Overview

At this stage, a high level diagram of the application can be defined.  This should be at a level that exposes the interaction between the different pieces, e.g. where the user interacts with the application, how the application interacts with the various backend systems, etc.   It should also show where the different crosscutting concerns apply to the interacting components in the architecture.  These may include authentication/authorization, logging and instrumentation, configuration, and caching among others.

Identify Key Risk Areas and Potential Issues

Most of the mistakes made during the design of the architecture happen when the designers fail to evaluate the proposed architecture against risk areas and/or potential issues that may occur after the design is implemented.   Some of the questions may include “can we handle a million users”, “can we swap out software X with Y”, “how quickly can we change business rules”, “how do we audit user authentication”, etc.   Asking questions like these ultimately define decisions for the architecture “abilities” (extensibility, flexibility, reliability, security, etc.).  This may introduce additional requirements but it is cheaper to revisit them at this stage than later.

Communicate Key Architecture Decisions

All of the key decisions about the architecture must be documented and communicated to everyone involved with the development of the application.  When all the stakeholders understand the key decisions and the rationale for those decisions, it helps align expectations and enables them to make better decisions for improving the application.  Communicating architecture decisions to developers empowers them to build the application aligned to those decisions and the QA organization can focus on the high-risk areas identified by this design.

There are several ways of going about designing system architecture, and every system and application is different. Our experience has shown that accounting for the above mentioned guidelines during the design process gives a clear direction where everyone is on the same page on how the architecture fits within the business requirements, and how it should influence the final product.  It is important to remember that a sound architecture is one that is built for change, and by adhering to these guidelines you should have a solid foundation to build future changes on.

Take aways from a Friday Code Review

By | Development, Enterprise Mobility

Do you do code reviews? If so, why? What do you benefit from your code reviews?

Most companies do code reviews to prevent future program errors, but in my opinion a major benefit of code reviews is to ensure the code is maintainable, that others can read and follow the code.

If you have not read the book Clean Code by Bob Martin, I highly recommend it, as it will give you techniques for writing maintainable code.

code reveiwCode Review Fridays

Here at BlueFletch we have a standing weekly code review meeting.  The engineers meet as a group and review some portion of code from a current project.  This meeting does not replace individual project code reviews, but is meant to benefit everyone in the company not working on the project.

Some of the benefits are:

1. See what others in the company are working on
2. Get insight into different technologies
3. Get help with a tricky piece of code
4. Ideas on doing a project differently

During our code reviews we look for the following items:

1. Readability — is the code easy to read / follow
2. Maintainability — can our customers easily maintain it
3. Usability — are the classes easy to use, are they overly complicated?
4. Does the code make sense?

Additional items we look for can be found here

A Recent Review

On a recent Friday we reviewed a couple of Android projects we inherited from other companies. As per our practice, we reviewed the code from the aspect of clean code and best practices, discussing how we would make the code maintainable and easier to read.

During the review four major issues jumped out:

1. Pyramid of doom
2. Project organization
3. Code Reuse
4. Hardcode Strings

code reviewPyramid of doom (or Callback Hell)

Every engineer has run into this, regardless of the language or platform, you have a function that has many, many levels of indention. This could a HUGE if statement with many conditions or a series of callbacks within callbacks. The deeper the code, the harder it is to follow and maintain.

Example:


if ( conditionA) {
    if ( conditionB ) {
        if ( conditionC ) {
            block of code doing something 1
         } else {
            if ( conditionD ) {
                block of code doing something 2
            } else {
                block of code doing something 3
            }
        }
    } else {
       if ( conditionE ) {
            block of code doing something 4
       } else {
            block of code doing something 5
       }
    }
}

 

Tip: If you find yourself coding such a monstrosity, STOP! Refactor the code. Start with the inner code and place the code into separate methods. Yes, you end up with more methods, but the code will be more readable, and with smaller methods you get code that is easier to write unit tests.

A possible rewrite (one of many ways, but easier to write unit tests):

..
 if ( conditionA) {
    methodConditionA()
 }
..

methodConditionA() {
   if ( conditionB ) {
       methodCondtionB()
   } else {
       methodCondtionE()
   }
}
methodCondtionB() {
    if ( conditionC ) {
       methodHandlerProcssingLogic1 ()
    } else {
       methodCondtionD()
    }
}
methodCondtionD() {
    if ( conditionD ) {
        methodHandlerProcssingLogic2()
    } else {
        methodHandlerProcssingLogic3()
    }
}
methodCondtionE() {
    if ( conditionE ) {
        methodHandlerProcssingLogic4()
    } else {
        methodHandlerProcssingLogic5()
    }
}
methodHandlerProcssingLogic1() {
    block of code doing something 1
}
methodHandlerProcssingLogic2() {
    block of code doing something 2
}
methodHandlerProcssingLogic3() {
    block of code doing something 3
}
methodHandleProcssingLogic4() {
    block of code doing something 4
}
methodHandlerProcssingLogic5() {
    block of code doing something 5
}


 

Project organization

Within one of the projects we reviewed, there were 67 fragments, all within one package. For non-Java programmers, imagine 67 code files within one folder, with the files having similar names.

There were 11 fragments referring to devices; 4 related to signing in; various fragments for product registration, and 2 About fragments.

How are these 67 fragments related? Which ones need to be looked at when enhancing a feature of the application? Where do we start?

Tip: How you organize your code can help those that follow. If you make it easier to identify features and/or the process flow, then those that follow will be able to understand your project.

If the engineer building the project had separated the fragments out by features or relating the code in some manner, then working with the project would be easier.

Some suggestions for organization include placing all the “User” related (sign in, forgot password, account creation) into one package.   Place settings related fragments into another package.  Place device related fragments into another package.

Get the idea? Organize the project by context.

Code Reuse

Within one of the projects we reviewed the code utilized simple REST API calls to gather data. A simple pattern of URL creation with HttpUrlConnection classes and code to handle the result.

After some research we noticed the same endpoint was used in multiple places. Then we found the same exact code pattern, almost line for line, in 15 other places.  The code had been copied from place to place, with minor changes to suit the need.

And there was a bug within the code that required a major change within each piece of code. Yuck!

Another project we reviewed had a common error message display, but the display code was copied into each Activity (25 code files). Imagine if they decided to change the look/feel of the error display, 25 code files would have to be updated and tested. Dooh!

Yes, as software developers we need to get things done fast, but the consequences of copying code from one part of the project to another will cause you headaches down the road. As no code is perfect, at some point it will need to be fixed or enhanced, how many places do you want to make changes?

Tip: if you find yourself copying a block of code from one part of the project to another, almost line for line, then build a reusable code object, either a new method, a new base class, something common. This will reduce the amount of code to maintain, and if a bug does arise, you have one location to fix it.

Hardcode Strings

Imagine opening a code file for the main activity of a project and having to scroll through 1,300 lines of hardcoded string literals? Yes, we had to do that during our code review.

We as engineers get lazy, we need to add a new UI label or a new error message, instead of doing it correctly we put the text directly in code. It never fails, later the project needs to be localized and now you have to pull all the strings out to a string resource file. How time consuming! How much time does it take to add the initial string to the resource file, less than a minute?

Tip: Take the time up front, do it right, and for the sanity of the engineer that follows you into the code base, do not hard code 1,300 lines of string literals into the main activity.

Conclusion

As software developers/engineers, we should take pride in our code. We should build our code to be readable, maintainable, and testable. Doing code reviews either as a group or individually will help you and others to learn and improve code.

And please: organize your code, write reusable modules, do not hard code strings, and break down your large unruly code blocks into smaller methods.

iOS 11 Features for the Enterprise

By | Development, Enterprise Mobility

WWDC has wrapped up and so now it is up to us in the world of iOS to make sense of all these newly unveiled features. Now, being a developer who is often working in the enterprise realm, I tend to look at many of these features from a slightly different angle. When people hear about ARKit adding augmented reality to iOS, they probably think about the implications for games like Pokémon GO and interior decorating apps that allow you to see a fake end table super imposed next to their couch. My first thoughts are about it’s possible use in retail and warehousing to help highlight objects of interest or present additional information for the user. With this post, I’ll be going over some of the new features and SDKs in iOS 11, and how they relate to the enterprise and working world.

ARKit, iOS11ARKit – Previously developers had to do all of this by hand, and truth be told, it’s not easy. Super imposing into an image isn’t very difficult, but however, super imposing graphics in a 3-dimensional space with depth, that is also moving, is extremely difficult. ARKit does the heavy lifting for developers by locating features and planes, and it allows you to create 2d or 3d objects via SceneKit or SpriteKit to super impose onto these features and planes. As stated earlier AR can be useful to locating and highlighting items, but when combined with some other technologies it can be so much more. For example, when paired with iOS 11’s Machine Learning and Vision frameworks, mechanic might be able to have their device see an unknown engine part, detect what part it is, and then super impose the documentation for that part on half of their screen. Obviously, this technology on a phone or tablet has some limitations, but as smart glasses become more mature they will be a fantastic candidate for augmented reality in the enterprise. Read More

ag Grid

Choosing a Data Grid Component For Your React Project

By | Development, Enterprise Mobility

In a React application I am working on we are using the Material UI component library, but immediately realized it’s table component did not have the features we needed. Many of the available grid components had the features we needed like sorting, filtering, search, and adjusting column order and size. However, there were only a few components that had the features we needed like exporting to excel and row grouping. Of those few, only ag-Grid had a built-in option for material theme styling. With a little css the grid was styled very similar to the Material UI table.

Top: Material-UI Table Component
Bottom: ag-Grid with material theme and some css

Another stand-out feature was the ability to pass through the gridOptions a context object that would be available to any custom cell renderer that you implement. This enabled us to pass props that included event handlers that could update the state of a parent component or launch async actions thus giving us the ability to make the grid even more interactive. For example, we were able to integrate commenting through the grid. Here is the table component code and the result.

import React from 'react';
import {AgGridReact} from 'ag-grid-react';
import 'ag-grid/dist/styles/ag-grid.css';
import 'ag-grid/dist/styles/theme-material.css';
import { columnDef } from '../table_util.js';
import DescriptionCellRenderer from '../descriptionCellRenderer.jsx';

const columnWidths = {
  'description': 400
};

class ExampleTable extends React.Component{
  constructor(props){
    super(props);
    this.data = props.data || [];
    this.columnDefs = this.columnDefs.bind(this);
    this.onGridReady = this.onGridReady.bind(this);
    this.gridOptions = {
      rowHeight: 56,
      headerHeight: 55,
      enableColResize: true,
      groupUseEntireRow: true,
      groupDefaultExpanded: -1,
      groupSuppressAutoColumn: true,
      groupSuppressRow: true,
      animateRows: true,
      suppressRowClickSelection: true,
      onRowClicked: this.onRowClicked,
      rowSelection: 'single',
      suppressMenuMainPanel: true,
      context: {
        currentUser: this.props.currentUser.user,
        handleCommentSave: this.props.handleCommentSave
      }
    };
  }

  columnDefs(){
    let columns = Object.keys(this.data[0]);
    let cols = [];
    columns.forEach((name, i) => {
      let col = columnDef(name.toUpperCase(), name);

      if (name === 'description') {
        col.cellRendererFramework = DescriptionCellRenderer;
      }

      if (columnWidths[name]) {
        col.width = columnWidths[name];
      }

      col.headerClass = 'table-header';
      cols.push(col);
    });

    return cols;
  }

  onGridReady(params) {
    this.api = params.api;
    this.columnApi = params.columnApi;
  }

  render(){
      return(
      
<div style={{height: '770px', width: '100%', backgroundColor: 'white'}} className="ag-material">
        <AgGridReact 
          onGridReady={this.onGridReady} 
          columnDefs={this.columnDefs()} 
          gridOptions={this.gridOptions} 
          rowData={this.data} 
          enableSorting='true' 
          enableFilter='true'>
        </AgGridReact>
      </div>

    );
  }
}

Integrating comments into an ag-Grid table.

Ag-Grid is an excellent choice to use as your data grid component. It has all the powerful features you would expect from a solid grid component such as multi-sort and search and essentially every aspect of the grid is customizable so it was easy to adapt to design changes. If you choose ag-Grid you are likely to have a smoother development process.

5 Essential React Native Libraries

By | Development, Enterprise Mobility

React Native is an increasingly popular framework for building cross-platform mobile apps. Unlike other cross-platform development frameworks, React Native compiles down to true native instead of running Javascript inside web views. On its own, React Native is powerful, and with the introduction of a few great libraries, it becomes even more valuable.

Read More

Lab Happenings vol. 5

By | Development, Enterprise Mobility

3D printing, also called  additive manufacturing, is the process of making three dimensional solid objects from a digital file. An object is created by laying down successive layers of material, usually molten plastic. Each of these layers can be seen as a thinly sliced horizontal cross-section of the eventual object. The advent of 3D printing has lowered the barrier of entry for industrial printing. What used to require machines, tools, and skilled technicians can now be accomplished by anyone with a laptop. The possibilities are both fascinating and endless. From fashion to food to  medical prosthesis, the speed and affordability of 3D printers has opened up a world of possibilities across a spectrum of industries.

3D printingWhen we first opened the BlueFletch IoT Lab the 3D printer was our very first purchase. In the Lab we use the STL file format native to CAD software and the 3D modeling app SketchUp to create 3D model images. Creating the STL file takes an engineering mind – taking the measurements so they translate correctly is a detailed process that is easy to bungle. Read More

Specifying your Android Host URL using Gradle

By | Development, Enterprise Mobility

Using Gradle has many cool features, the one that I really like is the ability to change configurations based on build type (release or debug).

Background

One of the headaches of building Internet enabled applications is pointing your application to a different API service based on the stage of development. For instance, for a QA build of a product I have had the need to point an application to a QA API Instance, or during initial development of APIs, to a development server. There are many ways to accomplish this, from reading a configuration file loaded on the device or changing a string resource to a new host. But I have started using my Gradle configurations to point my Android applications to different API host servers.

Gradle

Common Configuration Switching

A common method for switching host configurations is a complicate if statements:

if (BuildConfig.Debug) {
… use host A
} else {
… use host B
}

Of course, using this approach has many downsides, one of which is ugly “if” statements scattered through out your code. And when you have multiple flavors of the product with different debug versus release host API’s, it can get really ugly.

Another method is to use string resources that are loaded per flavor of build. A debug resource string file could contain Host A URL, which Staging flavor could contain Host B URL. This keeps the complicated if statements to a simple string load. But now your URL’s are in different files, and maintaining the multiple files always leads to ‘which is getting loaded’, ‘what is the current host’, etc.

This is where Gradle configurations can help clean up the code, and to me the main benefit is there is one source of truth of the host configuration settings.

Read More

GraphQL from a Postgres Database in Minutes

By | Development, Enterprise Mobility

Devs,

Have you ever found yourself in any of the following situations?:
Deadline is getting mighty close and the backend team still hasn’t supplied the very much needed data and REST endpoint yet
The app development team has requested an urgent change to the structure of the data being returned and you have way higher priorities at the moment
The sprint retrospective has your front end team going against your back-end team in a Royal Rumble match?

Read More