Clean Code: The Key for Code Reproducibility and Team Success

Kezia Irene Tesiman
LEARNFAZZ
Published in
6 min readMar 9, 2019

A code is a term used for both the statements written in a particular programming language — the source code, and a term for the source code after it has been processed by a compiler and made ready to run in the computer — the object code (Kogan, Hadass (2010)).

The code is clean if it can be understood easily — by everyone on the team. Clean code can be read and enhanced by a developer other than its original author. With understandability comes readability, changeability, extensibility, and maintainability (Martin (2009)).

Why clean code matters?

The programmer usually works in a group on a product. Bad code eventually brings a product down, because, during further development, productivity gradually approaches zero. Programmers must stand up for clean code just like managers stand up for requirements and schedules. But managers rely on programmers, not vice versa. And in order to go fast, we must have clean code.

Clean code is elegant, simple, efficient, straightforward, crisp, clear, literate, readable by others, unsurprising, has minimal and explicit dependencies, has automated tests, minimizes the number of classes and methods, expresses its design ideas, handles errors, has nothing obvious that one could do to make it better, looks like the author has cared.

Code gets read a lot (at least whenever someone is writing more code), so any school of clean code should emphasize readability. Cleaning up a little wherever you go is required to keep code clean. (Lutz Prechelt, 2013–2014)

General Rules:

According to the Software Development Project handbook (2019), the Clean Code application will not only help other people to read your code, instead, it also makes the architecture of the code more elegant so that it is easier to see for a long time, be modified and further developed. Here are six points about Clean Code that can help the quality of the code that you write to make it easier to understand and can continue to be developed:

  1. Efficient comment: Comments are usually needed to explain a “not-so-good” code. Instead of writing a comment to explain the code, the dictionary should improve the writing of the code so that it is easy to understand. Make sure the comments are only written for parts that require extra explanation and not because the program code written, is unclear or not good.
  2. Good naming: Make sure the name, variables, functions follow the general and standard reference set for the programming language or framework specified. Example: when using python, you need to follow PEP-8 guidelines.
  3. Writing a function (method) that is simple and effective: Each function/method can only do one thing. Avoid side-effects in creating functions that can make developers further mistaken in anticipating and understanding the behavior of these functions.
  4. Encoding Error and Exception Handling: Need to anticipate every possible exception with appropriate handling. Arrange good error code and agree with other team members.
  5. Don’t Repeat yourself: Do not have duplicate code and make a program that is modular and neatly structured. As much as possible apply the appropriate concepts/paradigms (eg Object Oriented, higher-order-function or design pattern.
  6. Layout Formatting: Apply the formatting code (layout) rules, apply linter tools that are compatible with the programming language technology used. Imagine the program code that you wrote is a series of poems and neatly arranged so that hours of watching will not be bored

Clean Test with F.I.R.S.T:

What is the FIRST principle? It is a concept from Martin (2009) book, “Clean Code” about the best practice for doing clean code test. Here is the summary from Brett Schuchert, Tim Ottinger (2009):

F → Fast: Tests must be fast. If you hesitate to run the tests after a simple one-liner change, your tests are far too slow. Make the tests so fast you don’t have to consider them.

I → Isolated: Tests isolate failures. A developer should never have to reverse-engineer tests or the code being tested to know what went wrong. Each test class name and test method name with the text of the assertion should state exactly what is wrong and where. If a test does not isolate failures, it is best to replace that test with smaller, more-specific tests.

R → Repeatable: Tests must be able to be run repeatedly without intervention. They must not depend upon any assumed initial state, they must not leave any residue behind that would prevent them from being re-run. This is particularly important when one considers resources outside of the program’s memory, like databases and files and shared memory segments.

S → Self-validating: Tests are pass-fail. No agency must examine the results to determine if they are valid and reasonable. Authors avoid over-specification so that peripheral changes do not affect the ability of assertions to determine whether tests pass or fail.

T → Timely: Tests are written at the right time, immediately before the code that makes the tests pass. While it seems reasonable to take a more existential stance, that it does not matter when they’re written as long as they are written, but this is wrong. Writing the test first makes a difference.

On doing these whole best practices, ones need to give a ton of hour to practice. Most people will take the shortcuts on writing fewer, fatter tests. Large tests are not fast, therefore it will not cut in the FIRST principle. Testing sometimes provides less value at higher costs. Often programmers feel guilty about how much time they spend on polishing the code that is already finished and is easily convinced to abandon the effort.

Applying Clean Code to Our Software Development Project:

  • For variables name: We make an agreement to use the camel case, the variable name should explain what does the variable do
class AccountPage extends StatefulWidget {
AccountPage({Key key, this.user}) : super(key: key);

final User user;
@override
_AccountPageState createState() => _AccountPageState();
}
  • For function: We make sure our function can be refactored later on by the other member of the group. This function has been used multiple time in the front-end pages that have forms in them
if (form.validate()) {
form.save();
try {
final AuthRepository authRepository =
AppConfig.of(context).authRepository;
final LoginResult response = await authRepository
.login(email: _email, password: _password);
Navigator.of(context).push<dynamic>(MaterialPageRoute<dynamic>(
builder: (BuildContext context) => DashboardPage(user: response.user),
));
} catch (e) {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(e.toString()), duration: Duration(seconds: 5)));
}
}
setState(() => _isLoading = false);
}
  • For every code: We try to refactor as much as possible without repeating the same code. For example, I am currently doing the front end. I have made a profile card in advance to be reused by my friends later on.
  • For Layout formatting: We have applied linter to our project. It reminds us, for example, to alphabetically sort the imported files, or to defines the type of a variable.
  • For Test: We have tried to make the test as small as possible, so it will be fast and specific. For example, these lines of code only test if the submit button can be clicked, and nothing else.
testWidgets('Submit button can be clicked', (WidgetTester tester) async {
await tester.pumpWidget(makeTestableWidget(child: page));
final Finder submit = find.widgetWithText(FlatButton, 'Enroll This Course');
await tester.tap(submit);
await tester.pump();

expect(find.byType(RichText), findsNWidgets(9));
expect(find.byType(FlatButton), findsNWidgets(2));
expect(find.text('Form submitted'), findsNothing);
});

References:

  1. Martin, R. C. (2009). Clean code: a handbook of agile software craftsmanship. Pearson Education.
  2. Nöcker, E. G. J. M. H., Smetsers, J. E. W., van Eekelen, M. C., & Plasmeijer, M. J. (1991, June). Concurrent clean. In International Conference on Parallel Architectures and Languages Europe (pp. 202–219). Springer, Berlin, Heidelberg.
  3. Lutz Prechelt, 2013–2014, The Essence of “Clean Code”
  4. Software Development Project Handbook 2019

--

--

Kezia Irene Tesiman
LEARNFAZZ

Biomedical Informatics Graduate Student at Harvard University. Interested in medical imaging, natural language processing, and machine learning.