During my interviews of young newcomers into the IT field, I notice that many of them have trouble differentiating "coding" from the discipline of "software engineering."
This is unfortunate, for there is a hugely important difference between the two that young software engineers must appreciate. This article discusses some of these software engineering aspects, with learning's from Virtusa's Technology Office.
A statement by Booch is very relevant to the topic at hand: "Dog houses have been built. You can't build a skyscraper the way you build a dog house." The "engineering" part of software engineering becomes really important-neigh, critical-for large-scale complex projects-the software equivalent of skyscrapers. So what are the important engineering aspects of building the software equivalent of skyscrapers?
First, it's important to understand what attributes are expected from the skyscrapers of the software world. Besides accurately and fully supporting immediate business requirements, the software also needs to support future expansion and scale.
Future expansion translates to both increasing business volume and changing business requirements. The software also needs to adhere to industry best practices that helps future maintainability of the code.
The use of the proper software engineering practices can result in software that adheres to the above attributes, while at the same time facilitating the productive use of a large team to improve time-to-result and enhance productivity of the software development process itself.
Requirements
Requirements gathering is usually the starting point of the software engineering cycle. Verbal and informal methods of gathering requirements, while quick and useful in small projects, are insufficient for large-scale projects.
At the same time, the traditional waterfall method of first gathering all the requirements before proceeding to design and development tends to also fail in a world where time-to-result is becoming a prime differentiator.
Instead, modern agile development techniques tend to engage customers earlier and more frequently and also provide for shorter iterations, enabling customers to see the product earlier and decide implementation priorities. In our experience, agile methods are growing in acceptance and momentum, and are even becoming the approach of choice in offshore development projects.
Metrics, such as the Requirements Clarity Index and Requirements Stability Index, are useful measures of the requirements gathering and management processes. One interesting tool I've come across is an Automated Requirements Measurement tool from NASA.
The tool can scan a requirements document and capture many requirements-related metrics; for example, the usage of weak English phrases that lead to ambiguities, structural inconsistencies, etc. The output of this tool can be very useful to optimize manual requirements reviews.
Requirements gathering includes both business requirements and technical requirements.
The project architect is responsible for visualising the technical solution, and must therefore ensure that any technical requirements and constraints are fully captured during the requirements process.
Architecture and Design
For large projects to be delivered on-time, it is important to effectively engage a large team, and parallelise as much work as possible.
Software architecture provides the means to decompose a large project into smaller sub-systems or sub-projects. Decomposition involves identifying the functional modules, architectural layers and cross-cutting concerns.
Architectural layers focus on specific functions, such as the user interface, business logic or access to database/external systems.
By organising these layers such that, for example, the user interface layer can only access the business logic layer, and the business logic layer can only access the persistence layer, layered architecture reduces the interconnections between components and reduces the complexity of the resulting software. Cross-cutting concerns deal with common technical requirements that go across layers, such as security, error handling, transactions, etc.
A technical requirements checklist of the right questions to ask in these areas can help avoid expensive requirements gaps in new development engagements.
Defining the architecture requires broad and deep knowledge of technology choices and best practices. The team should leverage industry standards and best practices associated with its technology selections.
These standards should not be limited to the main programming language, but should also address user interface (HTML, accessibility, XHTML standards, etc.), database (database object naming conventions, SQL standards, etc.), and any other specific technologies in use. Virtusa's Technology Office provides a portal with all these specific standards and best practices, from which teams can select the subset they require for each project.
In many industries, existing blueprints are used to create new applications. So rather than architecting from scratch, it is often better to use established architecture blueprints as a starting point. Creating an architecture blueprint in code during the early stages of the design process is a highly-recommended best practice that results in better quality code aligned with the architectural vision.
This approach has the advantage of mitigating technical risks early in the project and describing the architecture in developers' language. This thin slice of code representing all the architectural layers can also be run through profiling tools to capture potential performance and scalability bottlenecks with the architecture.
Architecture blueprint generators exist that can generate the early architecture blueprint for new applications.
The architecture blueprints generated by these tools already adhere to best practices and can be a huge boost to both quality and productivity. Virtusa's Technology Office provides a custom blueprint generator for the standard Java/Spring technology stack, and also provides a list of recommendations and guidance for different sets of technologies.
Architecture blueprint generators can go a long way to ensuring that the technologies and standards used in an enterprise are consistent.
Virtusa has also created custom architecture blueprint generators for customers, based on their unique technology decisions and nuances.
Automated Unit Testing
As teams start doing parallel development work, a good team infrastructure and rigorous engineering practices are needed to ensure that conflicts are avoided, and any defects are caught early.
Defects that are caught later in the lifecycle cost much more to fix than those that are caught early in the lifecycle. Also, as the code base starts to grow in the thick of the construction cycle, there is a growing risk of developers not considering dependencies sufficiently and breaking functionality that worked earlier. Such defects can be extremely destabilizing and can easily reduce the productivity of both development and quality assurance (QA) teams to the breakpoint.
Dependency-based defects can be easily avoided by creating a suite of automated unit tests. In fact, developers must be informed that development is not considered complete until their code is sufficiently covered by automated unit tests.
Frameworks, such as JUnit for Java and NUnit or MSTest for Microsoft .NET, can be used to create and run automated unit tests. Code coverage tools, such as Emma for Java and NCover or MS Code Coverage for .NET, provide valuable information about exactly how much of the code is covered by the unit tests.
They point out which lines of code are covered and which lines are not covered by the unit tests-valuable information, indeed, for technical leaders assessing test coverage and thus stability of the code base.
Having a suite of automated unit tests can also be a huge benefit for the maintenance phase of the lifecycle, as it ensures that defect fixes or enhancements don't end up causing instability in the system.
An interesting side note is the relationship between code complexity and unit testing. Code complexity can be measured using McCabe's Cyclomatic complexity metric, which effectively counts the number of conditional branches through the system.
A rule of thumb is that the number of unit tests should at least be equal to the Cyclomatic complexity. Another interesting metric, called the CRAP metric (Change Risk Analyzer and Predictor), provides a measure of the maintainability of software. The CRAP metric increases as the complexity increases, and decreases as the code coverage from unit tests increases.
A high CRAP count can be lowered either by refactoring code to reduce complexity, or by increasing test coverage using more unit tests.
Team Infrastructure
Standard team infrastructure includes source control and defect/change tracking systems, team collaboration portals and continuous integration (CI) build servers. CI servers promote frequent code integration, by "listening" to the source control system, building the code automatically at frequent intervals, and, if automated unit tests exist, executing these unit tests.
CI servers are usually configured to send an email to the team on each build or if a build or unit test failure occurs. Having a CI server ensures that any integration failures are caught early and are therefore much easier to fix.
A defect tracking system can provide useful information on the trending of defects and the readiness to release software to the customer-typically, the number and density of defects decrease and the time to find a defect increases as the system moves closer to release.
Code Analysis
The percentage of defects caught before delivery to the customer as a percentage of the total number of defects (also called the defect removal efficiency) can provide a very useful indicator of the overall efficiency of the QA processes.
Configuration and release management is a well defined activity that can reduce conflicts and ensure a smooth transition of code and other artifacts between the Development, QA and production support teams.
Automation is key to ensuring software quality in a large project. Code analysis tools, such as Checkstyle and Findbugs for Java or FxCop for NET, automatically check code against coding conventions and best practices.
Virtusa's Technology Office provides an integrated development environment (IDE) based on Eclipse that bundles the Virtusa coding standards and conventions, as well as a standard set of code-analysis plug-ins.
Developers are expected to run these tools and correct any errors reported before code is checked in. Another custom tool provided by the Technology Office is installed on the build servers, analyses the code base and publishes metrics to an enterprise-level metrics dashboard.
These metrics are available for technical leadership to analyze and act upon, providing an additional safety net for code quality. Such infrastructure can reduce the subjectivity of code assessments and can focus manual code reviews on higher-order activities, such as finding logical and design-level issues with code.
Software development is often seen as an industry with low barrier to entry. While this may be true for small projects, complex projects that leverage large teams require a very high degree of professionalism and engineering discipline to be successful.
This is especially true as customers also become more sophisticated, demanding high quality solutions to complex business problems with significantly reduced time-to-results.
In an increasingly competitive industry, it's the "architecture and engineering" aspect of software engineering that separates the men from the boys.
No comments :
Post a Comment