• No results found

Improving maintainability on modern cross-platform projects

N/A
N/A
Protected

Academic year: 2021

Share "Improving maintainability on modern cross-platform projects"

Copied!
28
0
0

Loading.... (view fulltext now)

Full text

(1)

Institutionen för datavetenskap

Department of Computer and Information Science

Final thesis

Improving maintainability on modern

cross-platform projects

by

Dan Berglund

LIU-IDA/LITH-EX-A--13/022--SE

2013-06-13

Linköpings universitet

SE-581 83 Linköping, Sweden

Linköpings universitet

581 83 Linköping

(2)

Master thesis

Improving maintainability on modern

cross-platform projects

by

Dan Berglund

LIU-IDA/LITH-EX-A–13/022–SE

June 13, 2013

Supervisors: Simon Pantzare (Memoto), Anders Fröberg (LiU) Examiner: Erik Berglund

(3)

Abstract

As software systems grow in size they will also grow in complexity. If the increased complexity is not managed the system will be increasingly difficult to maintain. The effect of unmaintainable software is even more distinct when using a agile development process. By increasing the maintainability of the system these problems will be dealt with and the system can be extended with sustained efficiency.

This thesis will evaluate the development process of a modern, agile company in order to find changes that will promote increased maintainability. The result is an modified process that will increase the maintainability with the smallest possible overhead for the development organisation.

The result is based on earlier studies of development technologies that have proven to increase the maintainability. The implementation of these technologies are adjusted to fit the development team, and some of the technologies that are not suitable for the team are rejected.

(4)

Glossary

Term Description

Language A programming language is referred to simply as languagein this thesis. Platform A combination of hardware, operating system and languageis called a platform. iOS The operating system used in Apples mobile devices, mainlyphones and tablets. Android A mobile operating system developed by Google, mainlyused in phones and tablets. API Application Programming Interface, an interface for acomputer program.

Owner Term referring to the developer that has the bestunderstanding of a piece of software, often the only one that has broad understanding of it.[1]

Agile Software development methodology based around theconcept that software should grow iteratively, instead of the traditional waterfall approach.[2]

Regression testing Usage of automatic tests to ensure that changes doesn’tbreak the existing component.

IDE Integrated Development Environment, software used forprogramming, can be everything from a simple text-editor to a full program suite.

Development Velocity The speed at which the team are able to modify/addfunctionality in the software, a high development velocity is desirable.

Design Pattern A general solution for a common problem in software design,most popular design patters are found in the book Design Patterns. [3]

(5)

Contents

1 Introduction 6 1.1 Background . . . 6 1.2 Problem description . . . 6 1.3 Goal . . . 7 1.4 Motivation . . . 7 1.5 Approach . . . 8

1.6 Scope and limitations . . . 8

1.7 Thesis structure . . . 8

2 Concepts related to maintainability 9 2.1 Maintainability . . . 9 2.2 Code quality . . . 9 2.3 Knowledge transfer . . . 13 2.4 Documentation . . . 13 3 Existing technologies 15 3.1 Code reviews . . . 15 3.2 Pair programming . . . 15 3.3 Automatic testing . . . 15 3.4 Coding standards . . . 16 3.5 Test-Driven Development (TDD) . . . 16 4 Memoto 18 4.1 Development organisation . . . 18 4.2 Development workflow . . . 19

4.3 Phase in the product life cycle . . . 19

4.4 Individual developers . . . 19

5 Result 20 5.1 Improving code quality . . . 20

5.2 Facilitating knowledge transfer . . . 22

5.3 Documentation . . . 22

5.4 Conclusion . . . 22

6 Discussion 23 6.1 Developers . . . 23

6.2 Evaluating the workflow . . . 23

(6)

List of Figures

2.1 Overview of concepts related to maintainability. . . 9 2.2 Example of buildup of technical debt. . . 12

(7)

List of Listings

2.1 Example of poorly designed database accessor . . . 10 2.2 Example of documented code . . . 13 2.3 Example of self-documenting code . . . 13

(8)

Chapter 1

Introduction

The thesis was carried out as a final project at master level for a 5 year degree in Computer science and engineering at Linköping University.

1.1 Background

When software projects increase in size and duration some problems are bound to occur, the complexity is bound to increase and the quality of the product will likely decrease during the development. If steps to counter this are not taken early in the project then the development velocity is likely to decrease, more time is spent hunting bugs and trying to understand code. Ultimately the project won’t make any progress at all since the whole development team is busy trying to correct earlier mistakes. This is likely to occur in almost all software projects of notable size and the reasons are many, but the result is software that is difficult to maintain and extend.

The speed of the development is known as development velocity, it is a rather abstract concept since development speed is incredibly difficult to measure. It’s best thought of as the pace at which the development team can add or modify existing functionality. As stated above the velocity is likely to decrease when the project grows in complexity, something that is sub-optimal, where optimal would be a constant velocity.

1.2 Problem description

Most current software projects are multi-platform and multi-language projects. The reason for this is that the software should support multiple platforms, e.g. iOS and Android, and also have a backend-API to support these different clients. This will result in the project having a heterogeneous code-base where the different parts are often written by different programmers. The result is often that every developer has expertise in a small part of the software, but little or no understanding of the other parts of the software.

The result of this is that different developers are owning different parts of the code, making enhancements and changes very inflexible. The understanding of the developers owning the code will also decrease gradually as time passes, making future changes even more difficult. This is common in most software projects and is increased in multi-platform, multi-language projects, since different developers might not be comfortable with working on some parts of the project.

This thesis will examine different ways to improve maintainability, and thus stabilizing the development velocity, in a modern multi-platform project. The focus will be on the following areas:

• Maximizing maintainability • Improving code quality • Minimize technical debt • Promoting knowledge transfer

(9)

1.3 Goal

The goal of the thesis is to examine different approaches for increasing the maintainability of a project, and thus minimizing the problems described above, and their applicability for multi-platform, multi-language projects will be evaluated. The focus will be on increasing the maintainability of the project while at the same time make the overhead for the developers as small as possible. The result of the thesis is a summarized recommendation how Memoto can enhance their development workflow to improve the maintainability of their software. It might also be applicable to similar development teams that develops similar cross-platform software.

1.4 Motivation

In order to justify this thesis we must examine the needs for high maintainability and develop a solid motivation for keeping the maintainability high. Some motives are presented below.

1.4.1 Reduce risk

By having a maintainable code-base we will mitigate a lot of risks, some are presented below.

• Key developers leaving the project • Bugs that are difficult to locate and fix

• Features that are difficult to implement due to bad design

• New developers being unproductive since they aren’t able to navigate the project 1.4.2 Facilitate change

Since agile software development methods work in an iterative manner a lot of changes and additions will always be done to the existing software, this is the essence of agile development. By facilitating change the whole time this processes will be improved, and thus the development velocity will increase. Even if we aren’t using agile development we can benefit from ease of change, since there probably will be bugs that needs to be fixed and enhancements needed to be done after the project is finished.

"Software is a process, it’s never finished, it’s always evolving. That’s its nature. We know our software sucks. But it’s shipping! Next time we’ll do better, but even then it will be shitty. The only software that’s perfect is one you’re dreaming about. Real software crashes, loses data, is hard to learn and hard to use. But it’s a process. We’ll make it less shitty. Just watch!" [4]

1.4.3 Developer satisfaction

Software with high maintainability will likely make the developers happier, since they can focus on implementing the desired changes instead of focusing on putting out fires. They will need to put extra initial effort into making the software maintainable, but this will most likely pay of greatly as the size and complexity increases. As stated above happy developers are likely to stay on the project and also attract other good developers, something that reduces the employee turnover and will itself increase the maintainability.

(10)

1.5 Approach

The thesis has been made at Memoto in Linköping. Memoto is a small startup company developing a life-logging camera and the corresponding software to store, index and access the images taken. This means that everything from the camera hardware to mobile applications are developed at the company. The development team is currently consisting of about 15 persons, where most are specialized in a small part of the final software. This makes the above problem applicable on Memoto since the project is multi-platform and multi-language with different developers developing the different parts of the software.

1.6 Scope and limitations

One important limitation with this thesis is that the technologies presented will be impossible to test during the duration of the project. Since the focus is on long-term maintainability changes to the development life cycle would have to be implemented for several months before results would be visible. Code quality and maintainability is very difficult to test in a quantitative manner. Some conclusions could be drawn by e.g. measuring test-coverage and ease of change, but these metrics would probably not be representable for the maintainability as whole.

The above implicates that the result will have little to no hard data supporting the proposed technologies. The result will instead be supported by subjective opinions by the individual team-members and earlier studies where the results have been quantified.

1.7 Thesis structure

The rest of the thesis is structured as follows:

• Chapter two describes concepts used in this thesis

• Chapter three describes various different techniques for improving maintainability • Chapter four describes the specific situation at Memoto and the impact this will have

on the thesis

• Chapter five describes the result of the thesis

(11)

Chapter 2

Concepts related to maintainability

This thesis will use various concepts to describe attributes related to software maintainability, many of these are qualitative and rather abstract, their connection can be found in fig. 2.1.

Figure 2.1: Overview of concepts related to maintainability.

2.1 Maintainability

Maintainability is a qualitative measure about how easy it is to maintain and continue developing a software product. High maintainability implies that the software works with little external support and that it is easy to add features or correct bugs. High maintainability is achieved when the software is well-designed, well-implemented, well-documented and well-tested. High maintainability will help new developers getting started on the project quicker and help current developers changing focus between components.

In a project with high maintainability the development velocity will be constant, which is something good for the project as a whole. It will be easier to find the part of the software where the change should be made, documentation will increase understanding of the part that should be changed and regression tests will verify that nothing was broken by the change. This will make both addition/modification of functionality and resolving bugs much easier, and these are things that all software projects will have to handle eventually. Since most software projects spends a majority of its time in maintenance after the launch it is very important to develop the software with maintainability in mind, this is especially true for agile project that can be said to spend almost all of its time in maintenance. [5]

2.2 Code quality

High quality code is code that is easy to understand, easy to modify and easy to replace. This means that the code should be decoupled, have a good design and implement the design accordingly. Having a high code quality will mean that it is easier for a developer to understand how it is designed and implemented, whether it is a programmer new to the project or the developer that wrote the code two years ago.

Achieving high code quality is difficult, it is easy for a developer to conclude "it works" and then continue working on another piece of the software, since it takes some effort to increase the quality. This might seem like a good approach from a managerial point of view, since no assets are wasted on things that already work, "If it ain’t broke, don’t fix it". But this approach will likely reduce the maintainability of the software, since it will be more difficult to change or fix if it breaks in a later stage.

(12)

Code quality is somewhat related to technical debt, section 2.2.4, code with low quality will have a high technical debt and vice versa. One could say that high code quality is the result of several different factors, including technical debt.

Some of the factors of code quality are presented below. 2.2.1 Software Design

All software projects have a design, which specifies which modules are responsible for certain tasks, and how these modules should work together. In larger projects the design is often specified at the beginning in a more or less formal way. Traditional projects tend to have more formally specified designs and the design of agile projects are less formal and evolves with the software. In smaller projects the design might not be specified at all, though this does not mean that no design exists, it means that the design is not specified. Even if the design is formally specified both of these approaches will evolve into a state where the implementation does not match the design, either because the developers have taken shortcuts and broken the design, or because the design didn’t fit the problem. When the software evolves into this state either the design or the code needs to be fixed, or possibly both. If this is not fixed the maintainability of the software will decrease drastically, since future programmers will have a hard time understanding how the implementation works.

By taking a conscious decision about the design you will also be able to utilise design patterns to solve common problems, since most developers have a good understanding of design patterns they will be able to quickly identify what patterns are used and thus gain a better understanding of the software.

2.2.2 Code smell

Code smell is a term that describes code that is badly written, but not necessarily incorrect, i.e. the code does exactly what its supposed to do but in a bad or ugly way. Code smell is often used about code that has a weak design or is badly implemented overall. Code smell will reduce the overall development velocity since more time will be needed both for understanding and modify the code.

A good example of code smell is poor design of a class-API, listing 2.1 describes a database accessor. class Database : def get_record ( s e l f , x , y ) : pass def l i s t _ c a r s ( s e l f ) : pass def f i r s t _ c a r ( s e l f ) : pass def i n s e r t _ c a r ( s e l f , x , y , z ) : pass

Listing 2.1: Example of poorly designed database accessor

In this example various design-principles are broken, the accessors have no uniform structure, the parameters have non descriptive names, the abstraction level differs etc. A good list of code smells can be found in [6].

(13)

Code smell can usually be solved by refactoring the responsible class or component, but in some cases the overall structure of the program needs to be improved. More about code smell with concrete examples can be found in [7, Chapter 3].

2.2.3 Refactoring

Refactoring is when you revisit an old component and change the design and implementation to better fit the current state of the software. This will increase the quality of the component, since you will have a better understanding of how the component is used in the current state of the software than the original developer. Refactoring is the result of realizing that it’s nearly impossible to design and implement a component correct the first time, since not all information will be present and certain assumptions will be incorrect.

The need for refactoring is extra obvious when using an Agile development methodology, since this means you start with very basic functionality and continuously add more, something that will generate code smell unless you refactor at the same time. One approach is to refactor the code to ease the addition of functionality, this gives the code a up-to-date design and gives an understanding to the developer before making functional changes, this approach is encouraged in [7, p. 58].

2.2.4 Technical debt

Technical debt is a metaphor first used by Ward Cunningham in 1992 [8]. The idea is that the introduction of bad code leads to interest in the form of increased effort in future development until the bad code is improved.

"Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite. Objects make the cost of this transaction tolerable. The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object- oriented or otherwise." [8]

Technical debt is often divided into intentional and unintentional debt, where intentional debt is consciously taken as a strategy e.g. to finish a release on time. Unintentional debt is debt taken because of bad design, lack of understanding or some other condition, in this thesis unintentional debt will be in focus.

Both intentional and unintentional debt makes the software more difficult to extend and maintain, since it makes the code more difficult to understand and modify without side-effects. If the debt is not paid off it will just build up and force the developers to focus more and more on maintaining the debt and eventually have no time for adding features to the software.

As an example of technical debt we can use the database accessor in listing 2.1. The initial development of the component will likely have little impact on the development velocity, since there is no direct penalty in writing bad code. But when someone uses the API technical debt will occur, in this case because of two things.

First, the developer will have to spend more time understanding the API since the design makes it counterintuitive to use, this means that using the API takes more effort than necessary.

Secondly, when we, hopefully, correct the initial design we will have to change the usage of the API in all components depending on it. This can lead to a lot of overhead if it’s used in many components.

(14)

Figure 2.2: Example of buildup of technical debt.

The extra development effort when using the API is called the interest payment of the technical debt, both in the initial development phase and the eventual redesign of the API. This is illustrated in figure 2.2 where we can see that the technical debt will easily add-up and make the project very difficult to manage.

2.2.5 Problem domain

The problem domain is a description of the context in which the application is to be used, the problem domain is often rather stable unless the business perspective changes.

"Problem domain (or problem space) is an engineering term referring to all information that defines the problem and constrains the solution (the constraints being part of the problem). It includes the goals that the problem owner wishes to achieve, the context within which the problem exists, and all rules that define essential functions or other aspects of any solution product. It represents the environment in which a solution will have to operate, as well as the problem itself." [9]

Understanding the problem domain is crucial when designing software. The understanding will enable the developer to use proper abstractions suitable to the particular problem instead of using generic abstractions. Even though the use of generic abstractions might be compelling at first they will make the quality of the software degrade, since they will not be optimal to solve the problem. This means that some "hacks" will have to be used in order to solve the problem. [10]

With a good understanding of the problem domain a developer will be able to design the software in a fashion that will help solving the problem, solutions to problems will come naturally and the component will be intuitive to understand. Knowledge of the problem domain will also help the developer to use proper constraints in the project and will make the software easier to extend if the problem domain is reasonably stable.

2.2.6 Developer culture

The culture in the development team is crucial for dictating the code quality. In a team where code quality is regarded important developers will put effort into improving the quality, thats how culture works. A good culture will also improve the results of code

(15)

reviews, section 3.1, since the reviewing developer will have higher standards for the code quality.

Lack of a good culture will encourage developers to perform tasks as quick as possible, without taking pride in the result. This means that the quality will decrease and none of the developers will work to improve it.

A good culture can be very difficult to accomplish, especially if there already exists a culture of bad coding and little pride in the resulting product.

2.3 Knowledge transfer

In order to increase the maintainability of the software there exists a need to have multiple developers proficient in every separate component, otherwise one single developer will need to do all the maintenance on that component, and if this developer leaves the project the knowledge of the component will vanish. One way to achieve this is by managing knowledge and to include knowledge transfer in the development process.

Some ways to include knowledge transfer is by utilizing code reviews, section 3.1, or pair programming, section 3.2, these techniques ensures that at least two developers have a good understanding of the component in question. Another way is to arrange internal sessions where the responsible developers demonstrates the design and specific inner workings of a component, other developers will then gain and understanding to the component and have an opportunity to ask questions about it.

2.4 Documentation

Documentation is the act of writing explanations about what the code does and how it works, the documentation can span from documenting a single statement to whole modules. Good documentation will help a new developer to quickly understand which components are responsible for which functionality, and understand how the original developer was reasoning when writing the component. [11]

A simplified case of documented code is shown in listing 2.2. def getRecord ( id ) :

#Gets the person with i d and r e t u r n s as JSON record = database . person . get ( id=id )

return record . to_json

Listing 2.2: Example of documented code

The scope of the documentation is often discussed, and examples varies from documenting each statement to no documentation at all. A good balance needs to be found, it is often desirable to document each non-trivial function and everything bigger. Too much documentation leads to a lot of overhead, both in the development and also during maintenance, since the documentation needs to be kept up to date.

In the above case documentation could, and should, be omitted in favor of self-documenting code, as seen in listing 2.3.

def getPersonAsJSON ( personId ) :

person = database . person . get ( id=personId ) return person . to_json

Listing 2.3: Example of self-documenting code

(16)

Documentation should capture the intent of the code, preferably in the language of the problem rather than the language of the implementation. This means that documentation largely should be language agnostic and written in a way that every developer familiar with the project should be able to understand. The documentation for a public API in e.g. a framework have even higher demands since the developer using the API shouldn’t have to be aware of the implementation in order to use the API.

(17)

Chapter 3

Existing technologies

The problem of code quality and maintainability is not new in the software development community, the motives for this dates back a long time and many methods have been developed to increase the quality and maintainability.

This chapter presents some of the most acclaimed technologies for improving maintainability that can be applicable on Memoto.

3.1 Code reviews

A code review means that the code in question are reviewed, often by another developer, in order to detect bugs and reveal bad coding practices. Regular code reviews are an excellent tool to improve the quality and maintainability of the software. It will reveal code smells since the reviewing developer will have less initial understanding about the code than the developer that wrote it and thus has no assumptions about how it works.

Code reviews can be performed on a regular basis and is often performed in a pair with the responsible developer and another developer unfamiliar with the code. This approach enables the unfamiliar developer to gain understanding of the code and detect bugs. The code can then be refactored to increase maintainability and ease of understanding, and the bugs can be fixed. This will increase maintainability since another developer will gain understanding of the inner working of the component in question. It is likely that both developers will benefit from the review as well, the original developer will get feedback on bad programming practices and the reviewing developer will likely learn new concepts used in the code.

Some sources claims that the quality of the original code will increase if the developer is aware that the code will be reviewed, the developer will thus put more effort into increasing the quality of the code to avoid "looking bad" to the rest of the team. [12] [13]

3.2 Pair programming

Pair programming is a technique where two developers uses one computer to develop software, this means that only one of them can write code and the other one can review the code written at the same time, the roles are switched frequently. The developers can also address design problems together and get a better initial design, these factors improve the quality and maintainability of the code.

Pair programming is however a rather expensive technique since it requires two developers to do a task one developer could handle, studies on the subject have varied results, some say that the two developers pair programming performs roughly as good as the better of them would have done alone [14], while some say that they perform much better [15].

3.3 Automatic testing

Most software projects are using automatic testing, which means that developers write tests that can exercise the software by a specific test runner. The main benefits of automatic testing are listed below, this thesis focuses on the latter two.

• Reduce the number of bugs

(18)

• Increase development velocity • Document the use of the component

With a good test suite the development velocity can be increased since the developers easily can detect if their changes has broken anything, this is much more effective than doing a manual tests every time some change are made. The tests can also be used as a mean to understand what the code is supposed to do, since a basic test describes the expected output of a certain input. [16]

The optimal extent of testing can be difficult to determine, more testing will result in better results, but will of course cost more. It is very difficult to find a good balance between cost and testing extent. A good test suite should contain at least a few valid and a few invalid tests for each method of a class and preferably edge cases, cases that are almost-valid or almost-invalid.

The value of good automatic testing might also be difficult to grasp. Most software will work good without good testing initially, but when the size and complexity increases the efforts to manually test that changes do not break the system will increase. When the software is in this state it will be a bigger effort to write tests, and since the release often is approaching developers will likely avoid the extra effort. The best approach is to always write tests parallel to writing the actual code, or after writing the code.

If no tests are written they can be written as a part of understanding the code when modifying the code later in the project, as suggested in [7, p. 7].

3.4 Coding standards

A coding standard might be something as simple as whether to use tabs or spaces for indentation, it is often simply guidelines about how to name variables, order the methods of a class etc. This makes it fairly easy for a developer to use and can often be enforced by settings in the IDE and it is highly recommended that a coding standard is enforced and documented for new developers.

By utilizing coding standards in a project the code will be written in a uniform way, something that will make it easier for developers to move between different parts of the code since the code will look similar and follow certain patterns. A good structure of the overall code will also make it easier for developers to detect programming mistakes, and thus reducing the number of bugs in the finished software. Many languages and frameworks promotes a coding standard, it is often enough to follow this standard in the project. The problem can be that developers jump between different parts of the project and thus needs to use different standards, in these cases it might be good to adjust the standards to be more uniform over the project.

Lots of good tips on organizing and designing code are presented in [17]. They might not be applicable for all languages or platforms but are a good starting point.

3.5 Test-Driven Development (TDD)

When utilizing test driven development you start the development of a component with writing a test-case that encapsulates some functionality of the requirement you are implementing. After the test is written the minimum code to make the test pass is written and verified. After the test succeeds the code is refactored and the cycle is continued until all requirements are implemented.

The benefit of using TDD is that the developer will always focus on solving a small subset of the requirement, e.g. the functionality encapsulated in the test-case. This will

(19)

prevent the developer to use a overly complicated solution unless necessary, since the solution is iterated with the addition to test-cases. The refactoring will ensure that the resulting code have a high quality and good design, without overly complex logic.

TDD is related to Automatic Testing, section 3.3, and by utilizing both a lot of the tests will be written during the development phase rather than in a later testing phase, something that probably will improve the quality of the tests since they are written to reflect actual functionality.

(20)

Chapter 4

Memoto

In order to decide which changes can be made at Memoto to increase the maintainability it is important to understand the development organisation. This includes how the current development workflow is, the current phase in the product life cycle for Memoto and the needs and experiences of the individual developers.

4.1 Development organisation

Since Memoto are developing software for a variety of different platforms the organisation of the development department is pretty complex, the different projects/platforms are currently: • Backend-service • Image-processing • Client applications – iOS application – Android application • Uploader applications – OSX application – Windows application

The backend-service is the core-component that acts as an intercommunication-medium for the other components. This means that images are sent from the OSX/Windows-applications to the backend where they are processed using the image-processing component and finally served to the iOS/Android-applications. This means that the backend is the most critical of all components, since the other components will be largely unusable without a working backend. The backend must also be highly scalable since it must be capable of handling thousands of users using the uploaders and mobile-clients.

Most of the components are currently developed by separate developers, with the big exception being the backend where more developers are involved. This leads to a problem regarding knowledge transfer, that isn’t occurring naturally on most components since there are only one developer working on them.

Some other problems arises from this organisation, since most other components is dependent on the backend the development in these components might be stalled due to required functionality in the backend missing. Some solutions to this exist, one would be that the backend is developed one iteration "ahead" of the rest components, but this means losing a lot of the advantages of iterative development. Another solution is that more developers are proficient in the backend and can add the functionality to support the feature they are currently developing, but this leads to a lot of overhead since the knowledge transfer isn’t naturally occurring between the components.

(21)

4.2 Development workflow

Most development is performed in an iterative manner. Since new features require functionality in multiple components this approach is preferable, otherwise integration of the components would induce a great risk.

Iterative development is well-suited for some of the technologies examined, since deliveries are made often it might be possible to add steps to the development workflow, e.g. to perform a code review before the delivery is approved or to always run automated tests before deployment. This will also make it easy to evaluate technologies, it is easy to add a step in the workflow, and if the result is dissatisfying we can remove it just as easy.

4.3 Phase in the product life cycle

Memoto is currently rather close to a launch, the product is set to launch in May 2013. The impact is that most of the changes suggested in this thesis probably won’t be implemented, since this would induce a great risk at this stage in the project life cycle. This is especially true for changes that will require changing the developers workflow or otherwise introduce overhead in the development, these changes will have to be introduced after the critical launch has been completed. This is an excellent example of technical debt, even though the product will benefit from increased maintainability this will have to wait until after the launch, rendering a greater cost but at a more suitable point in time.

4.4 Individual developers

Since all developers at Memoto have different backgrounds there will be different opinions about changing the workflow, some might be resilient due to earlier experiences with some of the technologies or vice versa.

One must also consider that many of the proposed technologies depend on how proficient the developers are with different techniques. A developer that have never written tests will likely have a hard time to do extensive automatic testing or using TDD. This can of course be taught but is something that we must take into consideration.

(22)

Chapter 5

Result

5.1 Improving code quality

Maintaining a high code quality is the greatest contribution to a high maintainability, high quality code makes extension easy, bug tracking easy, makes it easy for new developers to join the project etc. The result is that we will focus on raising the code quality since this is one of the biggest factors in maintainable software, this is probably also the area that face the greatest challenges, since it might require a big change in the development workflow.

While there exists lots of methods to improve code quality [18], the following sections contains the changes that are most likely to improve the code quality at Memoto with the lowest possible overhead.

5.1.1 Code Reviews

Many sources agree that code reviews is the single best way to improve the code quality [20], in addition to detect simple errors it will also make sure that coding standards is followed, that the component follows the architecture and that the design is sensible. Code reviews also makes knowledge transfer a natural part of the development, since the reviewing developer will gain knowledge about the design and implementation of the component in question.

To enable a fast adoption of code reviews at Memoto we will have to chose a implementation with a very low overhead for the developers. A good tool to use would be something that the development team already uses in their daily work, such as GitHub. GitHub has a feature called Pull Requests, that can be used as a tool for code reviews [19].

5.1.2 Pair programming

Pair programming provides mostly the same benefits as code reviews; verification that the design is good, the code is correct and improves knowledge transfer.

The main benefit with pair programming is that the feedback is instant, the reviewer is sitting beside the developer and can make comments on the code directly. This means that the code will be written and reviewed in one pass. When utilizing regular code reviews the feedback might take hours or even days to arrive, resulting in overhead in each cycle since the developer and reviewer will have to familiarize themselves with the code again. [21]

Another benefit with pair programming is that the reviewer must do the code review and properly understand the code, in regular code reviews the reviewer might just skim the code and look for obvious mistakes, without actually understanding how the code works. This will certainly improve the quality of the feedback compared to code reviews.

The opposition against pair programming is that the effort for writing the code is doubled when counted in man-hours, since we need two developers to do the same work as one developer. This is not necessarily true since the code quality will almost certainly be better and knowledge is transfered immediately. This is a standpoint that each team will have to take, pair programming have a lot of benefits but they are not trivial to understand and it will take some time before they are apparent.

(23)

My opinion is that Memoto could benefit greatly from pair programming, especially where the different components meet, e.g. where the mobile applications communicate with the backend-API. Here one developer familiar with the mobile framework could work with one developer proficient with the backend. They can thus combine their knowledge and review the code at the same time.

5.1.3 Automatic Testing

Automatic testing gives a lot of benefits to the development organisation, they will add some overhead to the development work but will greatly improve the maintainability.

When writing tests for a component the developer will be able to capture the intended functionality in a domain-specific way, this means that the tests will serve as a form of documentation. When new developers start working on the code they can use the tests as a way to understand the intent of the code.

Tests will also be helpful during the development, they can be run continuously to ensure that nothing is being broken. This means that the developer can focus on the development rather than avoid breaking something.

The main drawback of automatic tests is that they will add some overhead to the development work. Both the initial development and further maintenance will take extra time since the tests will need to be maintained as well as the code.

At Memoto automatic tests is encouraged but not enforced, and in my opinion they are not used enough. I think that Memoto can benefit greatly from more tests, they will help uncover subtle bugs and be usable in regression testing when adding features.

Automatic testing can be done at various different levels in the software hierarchy unit-level, system-level etc. I would encourage Memoto to use automatic testing at several of these levels as they work as good compliments to each other. System-level makes it easy to ensure that the system works, while unit-level makes it easy to isolate and change a unit.

Regarding TDD I think that Memoto can benefit from it as well, this will however depend on how comfortable the developers are writing tests. This is something I think Memoto should wait to implement until the development organisation has evolved further regarding testing.

5.1.4 Coding guidelines

Developing common coding guidelines for the development team means that it will be easier for developers to quickly start working on a different component without having to understand the syntax, this is of course preferable to developers spending time understanding the code. [22]

A problem with coding standards are that they are not usable in different languages, e.g. a coding standard for python might be inappropriate for C, this means that a common coding standard needs to be compromised to cover all languages used in the project. The result of this will often be that the coding standard is a mess that suites each language badly, and it might not even be possible to use in each language due to syntactic restraints. The method that often is to prefer is to use the coding guidelines for each language or platform, this means that there might be big differences between components, but the guidelines will fit the language and be well documented within the language or platform community.

At Memoto at least 5 different languages are used on even more platforms, this means that the guidelines for the language or platform is used exclusively. The impact is a

(24)

overhead if a developer is switching to a component on a different platform or in a different language, but the components are using a common coding standard that suits the language. This would be my recommendation if it was not already used. The overhead of having a coding standard spanning many different languages will almost always be bigger than the gain, especially for developers proficient in one language or platform.

5.2 Facilitating knowledge transfer

The most important aspect of knowledge transfer is that more than one developer has an understanding about each component in the software, this mitigates the risk of developers leaving the project or being unavailable for some time. By using code reviews, section 3.1, or pair programming, section 3.2, this will come naturally, and this is something that I think that Memoto would benefit greatly from.

Other forms of knowledge transfer, e.g. about different technologies or frameworks that are used in the product could be provided by hosting internal lectures regularly. This means that some member of the development team would be responsible for a lecture on some specific subject relevant to the product, this is a common in some companies and something that I think Memoto will benefit from.

While internal knowledge transfer is important it is also important to refresh knowledge using external sources. This can be achieved by sending employees to relevant conferences or courses. This is something that Memoto already permits, and encourages, but in my opinion this could be utilized much more, since it creates a value for both the company and the individual employee.

5.3 Documentation

Documentation is something that is required for pretty much all software, and something that I think Memoto could be better at. Documentation gives a great value since the developer reading the documentation quickly can understand how the original developer reasoned when writing the code.

There are two main difficulties when writing documentation, using the best scope for the documentation and capturing the intent rather than the implementation.

In order to improve the documentation practices I think that the best way is to change the culture among the developers, if the common understanding is that documentation should be present the developers will hopefully put some focus on writing documentation along with the code. The quality of the documentation can also be controlled with a good culture. If developers that are writing no documentation, or documentation of poor quality, is called upon they will likely change for the better.

5.4 Conclusion

I think that Memoto should start using code reviews or pair programming at least when developing bigger features, this will increase the quality and facilitate knowledge transfer. They would also benefit from knowledge transfer between the different components, e.g. by working on another component than their own once in a while. The usage of automatic testing and documentation could also be improved to rise the maintainability even further.

(25)

Chapter 6

Discussion

In this chapter I discuss the importance of improving the maintainability at Memoto and how that work could be continued.

6.1 Developers

The developers at Memoto are already very capable, but this is something that always can be improved. Good developers will improve the maintainability as much as a good workflow. This is also something that will help hiring more good developers, since a workplace with high standards are likely to attract good developers.

6.2 Evaluating the workflow

In order to verify and justify changing the workflow, every change needs to be evaluated. The evaluation should take into consideration both the quantitative and qualitative aspects of the change. Some opinions about the proposed methods can be found by reading earlier studies and understanding how they apply to the specific situation at Memoto, but the best tool is to evaluate the resulting workflow.

Since it is very difficult to measure the overall maintainability the best way to justify a change is by letting the developers decide if they are happy with the workflow. Since the motivation for improving the maintainability is to support the developers they are the ones to decide which methods are the best.

6.3 Impact at Memoto

By improving the maintainability of the software Memoto will be able to maintain a high development velocity and reduce the number of bugs. High maintainability will also make it easier for new developers to join the team and help minimize the losses if some developer leaves the team or has a extended leave.

All these factors will make the development organization at Memoto more effective and the resulting product will have a higher quality, something that will improve the overall result for the company.

(26)

Bibliography

[1] Jim Bird, swreflections.blogspot.ca Code Ownership - Who Should Own the Code?, 2013-04-25

http://swreflections.blogspot.ca/2013/04/code-ownership-who-should-own-code. html [2013-05-25]

[2] The Agile Manifesto, 2001-02

http://agilealliance.org/the-alliance/the-agile-manifesto/ [2013-03-03] [3] Gang of Four (Gamma, Helm, Johnson and Vlissides), Design Patterns: Elements of

Reusable Object-Oriented Software, 1994

[4] Jeff Atwood, codinghorror.com, We Make Shitty Software.. With Bugs!, 2004-10-06 http://www.codinghorror.com/blog/2004/10/we-make-shitty-software-with-bugs. html [2013-04-26]

[5] Basil Vandegriend, basilv.com, The Importance of Maintainable Software, 2006-02-01 http://basilv.com/psd/blog/2006/the-importance-of-maintainable-software [2013-03-19]

[6] Jeff Atwood, codinghorror.com, Code Smells 2006-05-18

http://www.codinghorror.com/blog/2006/05/code-smells.html [2013-04-08] [7] Martin Fowler, Refactoring, Improving the design of existing code, 1999

[8] Ward Cunningham, The WyCash Portfolio Management System, 1992-03-26 http://c2.com/doc/oopsla92.html [2013-02-11]

[9] Don Mills, c2.com,

http://c2.com/cgi/wiki?ProblemDomain [2013-05-25]

[10] Uncle Bob Martin, blog.8thlight.com Screaming Architecture 2011-09-30

http://blog.8thlight.com/uncle-bob/2011/09/30/Screaming-Architecture. html [2013-04-08]

[11] Anders Abel, coding.abel.nu, On Code Documentation, 2013-01-27

http://coding.abel.nu/2013/01/on-code-documentation/ [2013-03-25]

[12] Stephane Lussier, Macadamian Technologies, New Tricks: How Open Source Changed the Way My Team Works, 2004-01

http://idi.ntnu.no/grupper/su/bibliography/pdf/newoyvh/lussier2004.pdf [2013-02-12]

[13] Esther Schindler, CIO.com, 5 Reasons for Software Developers to Do Code Reviews, 2008-12-22

http://cio.com/article/472377/5_Reasons_for_Software_Developers_to_Do_ Code_Reviews_Even_If_You_Think_They_re_a_Waste_of_Time [2013-02-08]

[14] Are Two Heads Better Than One For Software Development? The Productivity Paradox of Pair Programming, MIS Quaterly; Mar 2009, Vol. 33, pages 91-118

(27)

[15] Matthew Heusser, CIO.com, Using Pair Programming Practices in Code Inspections, 2012-05-09

http://cio.com/article/706050/Using_Pair_Programming_Practices_in_Code_ Inspections [2013-03-19]

[16] Frank Kelly, softarc.blogspot.se, Automated Regression Testing, 2008-06-22

http://softarc.blogspot.se/2008/06/automated-regression-testing-why-what. html [2013-05-25]

[17] Steve McConneell, Code Complete, Second Edition, 2004

[18] Allan Kelly, allankelly.blogspot.se, Things to do to improve code quality, 2010-06-03 http://allankelly.blogspot.se/2010/06/things-to-do-to-improve-code-quality. html [2013-03-26]

[19] Steven Occhipinti, blog.stevenocchipinti.com, Code review workflow with GitHub, 2012-09-18

http://blog.stevenocchipinti.com/2011/09/code-review-workflow-with-github. html [2013-05-27]

[20] Anders Abel, coding.abel.nu, How we Achieved che Best Code Quality in my Career, 2012-12-20

http://coding.abel.nu/2012/12/how-we-achieved-the-best-code-quality-in-my-career/ [2013-01-25]

[21] Jeff Atwood, codinghorror.com, Pair Programming vs. Code Reviews, 2007-11-18 http://www.codinghorror.com/blog/2007/11/pair-programming-vs-code-reviews. html [2013-04-04]

[22] Joshua Hanson, bitly.com Improving Frontend Code Quality 2012-12-11

http://word.bitly.com/post/37725436365/improving-frontend-code-quality [2013-05-25]

(28)

På svenska

Detta dokument hålls tillgängligt på Internet – eller dess framtida ersättare –

under en längre tid från publiceringsdatum under förutsättning att inga

extra-ordinära omständigheter uppstår.

Tillgång till dokumentet innebär tillstånd för var och en att läsa, ladda ner,

skriva ut enstaka kopior för enskilt bruk och att använda det oförändrat för

ickekommersiell forskning och för undervisning. Överföring av upphovsrätten

vid en senare tidpunkt kan inte upphäva detta tillstånd. All annan användning av

dokumentet kräver upphovsmannens medgivande. För att garantera äktheten,

säkerheten och tillgängligheten finns det lösningar av teknisk och administrativ

art.

Upphovsmannens ideella rätt innefattar rätt att bli nämnd som upphovsman i

den omfattning som god sed kräver vid användning av dokumentet på ovan

beskrivna sätt samt skydd mot att dokumentet ändras eller presenteras i sådan

form eller i sådant sammanhang som är kränkande för upphovsmannens litterära

eller konstnärliga anseende eller egenart.

För ytterligare information om Linköping University Electronic Press se

förlagets hemsida http://www.ep.liu.se/

In English

The publishers will keep this document online on the Internet - or its possible

replacement - for a considerable time from the date of publication barring

exceptional circumstances.

The online availability of the document implies a permanent permission for

anyone to read, to download, to print out single copies for your own use and to

use it unchanged for any non-commercial research and educational purpose.

Subsequent transfers of copyright cannot revoke this permission. All other uses

of the document are conditional on the consent of the copyright owner. The

publisher has taken technical and administrative measures to assure authenticity,

security and accessibility.

According to intellectual property law the author has the right to be

mentioned when his/her work is accessed as described above and to be protected

against infringement.

For additional information about the Linköping University Electronic Press

and its procedures for publication and for assurance of document integrity,

please refer to its WWW home page:

http://www.ep.liu.se/

References

Related documents

There are different approaches to develop this booking system for a mobile device and one approach is to develop one application for each platform in the their respective

Features Grade • External components Satisfactory • Device specific functionality Good • Security Satisfactory • Offline support Good • GUI tools Good • API/Extensions

When both panels rotate around the lower edge, as in Figure 20, the ideal distance of the translational motion is described by Equation (1) where L is the panel

2) RhoMobile: applications are developed mostly in Ruby language using a Model View Controller (MVC) architecture, separating the logic (Ruby) from the UI design (HTML). The

In 2011 I accompanied two delegations to Kenya and Sudan, where the Swedish Migration Board organized COPs for people who had been granted permanent Swedish residence

As discussed earlier in the chapter for educators (page 12, to be more specific), the internal workings of different schools can be very specific, so a game that is tailor-made to fit

The image data such as the motion-vector and the transformed coefficients can usually be modelled by the Generalized Gaussian (GG) distribution and are then coded using

The goal of this thesis is to identify the critical success factors in an agile project from various literature that has been analyzed, to see how the contributing attributes in the