Wednesday, June 22, 2016

The Three Dimensional Views of Software Development



Introduction

This document classifies the current software development into three dimensional views. Each view consists of existing industry methodologies, standards, Best Practices, and Principles with the new view to focus on the contextual activities targeting various audience such as users, business analysts, managers, executives, architects, developers, and machines/devices to achieve higher quality, efficiency, usability, speed, agility, sale, integration, and scalability in order to maximize revenue and long term high return of investment. It will not describe the methodologies, standards, Best Practices, and Principles since they are readily available online and textbooks.

The Three Dimensional Views of Software Development

At the top level of current software development, it can be classified into three views such as User View, Development View, and machine/device view.  These views should cut across all phrases of software development. The following sections elaborate these views with their respective targets in detail.

User View

In this view, the target audience are the users. In addition to a software system that provides all the functions as specify in the business requirements, the User View also focuses on the users experiencing every aspect of the system they interact with. Some of the examples include, but not limited to, ease of use, intuition, navigation, flow, default values, and number of clicks to get the job done. All the business functional and non-functional requirements of the system that we deliver should be targeted for the end users starting from the beginning and at the top level down. Every feature or function of the system being delivered needs to simplify but not complicate the tasks of the users. There is little value of the system if the users cannot use it due to its complexity. 


Some of the questions the architects and developers focus on are: 
  • Is there a better way to simplify this feature for the user?
  • Is this system intuitive and ease to navigate?
  • Is the process flow short and concise?
  • Does this system require minimal user interaction to get the job done by minimizing user-click?
  • Does the system provide default values and minimize user type-in?
  • Does the system show its processing status and respond to users as defined in SLAs?
  • Is it easy to add new functionalities to the system?

In addition to an architect’s normal responsibilities, for example, to work with various stakeholders to understand their needs and identify the key significance of the software system, what each component does, which components it depends on, which components use it, and their relationships to the external environments, he also needs to focus on the users that will be using this software system. The architects may need to know the skill sets of the development teams in order to select the right tools, frameworks, and technologies for them. The architects also bridge the business and the development teams and serve their best interests. But the end users must always be one of the key factor.


Developers also need to focus on the users when developing the software system to optimize user experience.

Development View

The Development View focuses on the stakeholders, including, the current and future development teams. It includes, but not limited to, business analysts, users, architects, managers, executives, technical leads, and developers. While the architects create the architecture, with various design patterns and principles, using various methodologies, styles, or decomposition strategies, the architects need to focus on the stakeholders. Different stakeholder has different concerns and different level of knowledge. The architects may need to provide different architecture diagrams and documents for a particular group of stakeholders. For example, executives may need to know only at a high level the key significant components of the software system, what each component does, how they communicate, the flow of data to and from these components. On the other hand, the development teams may be interested to know the lower level technical design, technology selection, and Proof of Concept (POC). 


Some of the questions architects may need to remind themselves are:
  • Does the system I architect fulfill the business needs and simplify the job of the users?
  • Do I create separate architecture diagrams and documents targeting for a particular group of audience?
  • Is my architecture easy for other architects to understand?
  • Does each architecture diagram serve a single purpose?
  • Is each architecture diagram intuitive?
  • Does each diagram have more horizontal and vertical lines and less diagonal lines?
  • Does my architecture diagram have minimal crossing lines?
  • Does my architecture diagram have consistent color, size, and shape?
  • Does each architecture diagram have a legend to define colors, shapes, and lines?
  • Do I use foreground and background colors correctly?
  • Do I use UML correctly if I create UML diagrams?
  • Do the development teams understand my architecture?
  • Do I select the tools and technologies that the development teams already have skills or easy to learn?
  • Do I provide the bridge between the business and the development teams and serve their best interests?
An architecture diagram should be self-explanatory. It should serve a single purpose or a single context of data flow processing just like a small method in programming that does one thing and does quickly, efficiently, and correctly. 

If it contains all data flow contexts, it must contain all required components, and all connected lines.  This makes your architecture diagram looks like a complex electronic schematic. But it is worse than electronic schematics because it contains diagonal lines and crossing lines in addition to vertical and horizontal lines. I have not seen an electronic schematic with diagonal lines or crossing lines. But I have seen countless architecture diagrams like complex electronic schematics with a lot of diagonal lines, and crossing lines, along with vertical and horizontal lines with various colors. An architecture diagram like this is like a God method in programming which it contains hundreds or thousands of line of code. 

Many people created UML architecture diagrams in the wrong context and used UML incorrectly. This causes a lot of confusion. UML, if use correctly, sets the target audience's minds in the right level of context so that they can grasp and understand the architecture quickly and easily. If the architects do not use UML correctly, the target audience will not be on the same page as the architects.

An architect does not create an architecture diagram for oneself. An architecture diagram is created for a person, a particular group or multiple groups of people. So, architects need to focus on how the target audience will consume, and react toward, their products, namely architecture diagrams and documents.

The development teams are the people that write the code to fulfill business requirements while following the architecture guidelines. When writing the code, the developers also need to focus on the target audience such as the end users, the future developers, and the machines/devices. Below are some of the high level Best Practices that developers need to remind themselves while writing the code:
  • Write small and reusable code to fulfill business requirements (15 lines or less per method)
  • Write code to simplify the users in using the software system
  • Write clean and quality code that follow architecture guidelines, Best Practices, and Principles
  • Write easy and concise code for future developers to understand quickly
  • Use the language library (Java Collections Framework) correctly
  • Do not re-invent the wheel when there is readily available library
  • Write code as secure as possible
  • Write code that minimizes un-necessary API exposure

Writing code to fulfill business requirements


Writing code to fulfill business requirements is the main purpose of developing software. It has to satisfy business requirements. The business pays the cost. Developers write code according to business specifications. They develop all the features required by the business. Nothing more and nothing less. During testing, all the software features are validated according to business specifications.


Writing code for future developers


Before the software is delivered into production, it is tested based on business requirements but that is done at a point in time. Business keeps changing; therefore, the software also needs to change the existing features and add new features.  However, not all developers stay for the same positions and the same company forever. Some move up and some move out. So, the code that one developer writes today is for other developers to maintain and extend in the future. One of the best way to achieve this is to write the code as simple and clean as possible. All developers should strive to follow industry Best Practices, Coding Standard, and Principles and make them as their instinct to produce high quality code, code that runs quickly and efficiently in space and time and yet is very easy to understand, maintain, and extend by other developers. In order to have a long term and high return of investment of the software system, it must be in a clean and quality state at all time.


Some projects have Java class like

public class CreateAccount {
   ...
}

a delete method is embedded in getAccount method like

public Account getAccount(String accountId) {
  ...
  if (succeeded == true)
      deleteAccount(accountId)
   ...
}

a logic like 

if (myObject != null) {
...
} else if (myObject == null) {
...
}

and a switch case like

StringBuilder buf = new StringBuffer(msg.length());
for (int i = 0; i < msg.length(); i++) {
char c = msg.charAt(i);
switch(c) {
    case '\\' :
    case '_' :
    case  '%' : buf.append('\\');
}

where the entire switch case can simply be written as

if (('\\' == c) || ('_' == c) || ('%' == c))
   buf.append('\\');

There was a web-based project that was developed by a technical lead. It had a single Java class with only one method that overrides the servlet service method. This method does everything and it has close to 4000 lines of code but nicely indented. So you have to keep track of the section of indented lines while scrolling in horizontal left to right and right to left. I asked the technical lead what kind of programming it was. The answer was “Object Oriented Programming”. I also encountered another project and it has one POJO class that has a single method but this method contains more than 5900 lines of code. Code like this is hard to understand, maintain, extend, and test.

A deployed production software system that is hard for other developers to maintain and extend will not provide a long term investment. The cost to maintain and extend it will be higher than the value it provides; therefore, it will be abandoned and started to code a new software system to replace it. The cycle begins again and repeats the same problem of bad design and bad code unless the development teams follow Best Practices, Coding Standard, and Principles.


Compiler, JVM, Machine, and Device View


The code that the developers write will need to be parsed and processed based on a programming language specification, Java for example, and ultimately translated into bytecode or executable instruction codes and executed in a machine or device. It may also store data in that machine or device or make connection to other remote machines and devices and store data there or retrieve data from there. Therefore, this view focuses on the (JVM) compiler, machine code executor (Java interpreter), physical machines and devices such as servers, routers, and smart devices (smart phone).


Write code for the Compiler, JVM, Machine, and Device


While developers write code, they also need to think about how the compiler will compile their source code and generate byte code or machine executable instruction code. By knowing how your compiler compiles and translates your source code, it helps you to write concise and efficient source code for your compiler to generate less and efficient bytecode or machine code. One of the best way to make your code runs fast and efficiently is to write as less code as possible. The goal is to produce as minimal machine executable instruction code as possible.

During my graduate study in Computer Science, my advisor, Dr. Gary Monnard, recommended a book to help in writing research and thesis. It is called "The Elements of Style" by Oliver Strunk. One thing that I still remember and put it into use is in page five, soft copy, and it said:

"Vigorous writing is concise. A sentence should contain no unnecessary words, a paragraph no unnecessary sentences, for the same reason that a drawing should have no unnecessary lines and a machine no unnecessary parts."

I have applied that into computer as:

"Quality code is concise and in one place. A line of code should contain no unnecessary tokens, a method no unnecessary lines, for the same reason that a component should have no unnecessary libraries/jars and an architecture no unnecessary components, and an architecture diagram with no unnecessary parts and lines, but that everything works coherently in a context or within sub-contexts of a context. "

Many projects create global static variables in a Java Interface like below.

public interface IConstant {
   public static final String CONSTANT_NAME = "something";
   ... 
}

and then many classes implementing this interface and other classes in other systems use these implemented classes. One of the many risks here is that once another system uses a global static variable in the interface through your class, you are stuck. The solution is to declare global static variables in a final class and explicitly declare a private constructor as shown below.

public final class Constants {
   private Constants() {}
   public static final String CONSTANT_NAME = "something";
...
}

this class tells other developers that you do not want it to be subclassed or instantiated. Any class that wants to use its global variables has to do Constants.CONSTANT_NAME, including your classes. Other components will not be able to see and access the global variables you use in your classes, through the front door.

Another project has java code like

public boolean checkIfAccountIsValid(String accountId) {
  ...
}

would be better to write as

public boolean isAccountValid(String accountId) {
  ...
}

 If (succeeded == true) {
  ...
}

It would be better to write as

If (isSucceeded) {
  ...
}

because it is less verbose, more concise, easier to read and understand by other developers. The parser also has less tokens to parse and ultimately produces less executable instruction code. Not all compilers are the same. Some compilers and interpreters may be able to optimize and combine instruction codes. But developers should optimize their code for speed and efficiency rather than depending for smart compilers, interpreters, and fast machine.


Some questions developers need to ask themselves while writing code are:
  • How will the compiler compile and translate this to bytecode/machine code?
  • Is my program too chunky or too chatty when communicating to other components/software systems?
  •  How fast and efficient will my code run in this machine or device?
  • Does the machine or device have enough memory to run my program?
  • How will the information be displayed on each screen of this machine/device?
  • Do I write less and efficient code for (JVM)Compiler, machine, and device?
  • How well do the network and protocol handle my payload?

Summary

This document classifies the current software development into three dimensional views such as the User View, Development View, and Machine/Device View. Each view consists of the current software development methodologies, Best Practices, and Principles with the new focus of targeting the activities in that view toward one or multiple groups of audience. It requires you to know who are your target audience whatever you are working on. You almost always need to know the end users and how they will use your product or service so that you can serve them better and faster.  When you apply these views to cut across all phases of  software development, you will have a higher level of quality, efficiency, usability, speed, agility, sale, integration, and scalability. These enable you to maximize revenue and long term high return of investment.


No comments:

Post a Comment