Clean Code, Sebuah Seni 🎨

Nurul Faza S.
LEARNFAZZ
Published in
5 min readApr 1, 2019

A programmer who writes clean code is an artist who can take a blank screen through a series of transformations until it is an elegantly coded system.

— Robert C. Martin

Menulis Clean Code sangat mirip dengan melukis gambar. Kita tahu bagaimana suatu gambar dilukis bagus atau tidak, tetapi kita belum tentu tahu bagaimana cara untuk melukis gambar tersebut supaya menjadi bagus. Sama halnya dengan menulis kode, terkadang kita tahu kode kita belum bersih, tetapi kita juga bingung bagaimana cara membersihkannya. [1]

Clean Code

Kode yang baik bukan hanya kode yang bisa menyelesaikan permasalahan, tetapi kode tersebut juga harus efisien, mudah dibaca, dan mudah dikelola. Kode yang Anda tulis harus mudah dibaca oleh siapapun, baik diri Anda sendiri maupun orang lain. Hal ini sangat penting dalam pengembangan sebuah perangkat lunak, dimana Anda harus bekerja dalam tim dan kode Anda dituntut untuk bisa dipahami oleh anggota tim lainnya. [2]

Penerapan Clean Code merupakan suatu hal yang dapat menghemat waktu dengan cara menghabiskan waktu [3]. Dalam penerapannya, kita tentu memerlukan extra time untuk fokus terhadap desain kode dan arsitekturnya. Hal ini penting supaya kode yang kita tulis bisa dengan mudah dipahami. Walaupun demikian, penerapan Clean Code dapat menghemat waktu di kemudian harinya. Salah satunya, jika ada perubahan requirements, maka kode yang sudah kita buat akan lebih mudah dikelola dan diadaptasikan.

Berikut ini adalah 6 poin yang bisa dilakukan untuk menerapkan Clean Code :

  1. Komentar yang efisien — Komentar ditulis untuk menjelaskan hal-hal yang membutuhkan penjelasan ekstra, bukan untuk menjelaskan kode yang kurang baik.
  2. Penamaan yang baik — Penamaan yang baik adalah penamaan yang mengikuti acuan umum dan baku dari bahasa pemrograman atau framework yang digunakan.
  3. Penulisan fungsi/method yang simple dan efektif — Fungsi atau method yang ditulis hanya melakukan satu hal untuk mencegah kekeliruan dalam pemakaian fungsi.
  4. Pengkodean Error dan Exception Handling — Melakukan antisipasi kemungkinan exception dengan handling yang sesuai dan disepakati anggota tim lainnya.
  5. Don’t Repeat Yourself — Program dibuat secara modular dan terstruktur tanpa disertai duplikasi kode.
  6. Layout Formatting — Menerapkan aturan formatting code dan atau tool linter yang sesuai dengan bahasa pemrograman yang digunakan.

Penerapan Clean Code pada LEARNFAZZ

Pada proyek LEARNFAZZ, penamaan pada kode mengikuti aturan camel case. Cirinya adalah setiap kata menyatu dan terdapat huruf kapital yang menjadi pemisah antarkata. Penamaan fungsi/method juga sudah didefinisikan secara singkat dan jelas, sesuai dengan tujuan dari fungsi tersebut.

class CoursePage extends StatefulWidget {x
@override
_CoursePageState createState() => _CoursePageState();
}
class _CoursePageState extends State<CoursePage> {
ScrollController _scrollController;
bool get _showTitle {
return _scrollController.hasClients
}
}

Kami juga memastikan bahwa tidak ada duplikasi atau reptisi kode yang tidak diperlukan. Salah satu contoh penerapannya adalah dengan pembuatan kelas card. Card tersebut dipisahkan ke dalam suatu kelas tersendiri, sehingga tidak perlu dibuat ulang apabila diperlukan pada page lainnya.

Kami juga sudah menerapkan tool linter untuk layout formatting. Linter akan menandakan format-format kode yang belum sesuai beserta alasannya. Contohnya, dalam import package yang tidak dipakai serta aturan dalam mendefinisikan suatu variabel.

Linter menandakan import package yang tidak dipakai
Linter menandakan variable courseName belum terdefinisi

Penamaan fungsi yang efektif adalah fungsi yang hanya melakukan satu hal. Contoh dari penerapan fungsi tersebut adalah fungsi initState() pada potongan kode di bawah ini. Fungsi ini tersebut sesuai dengan namanya, hanya melakukan inisiasi state untuk halaman course.

void initState() {
super.initState();
_scrollController = ScrollController()
..addListener(() => setState(() {}));
}

Antisipasi kemungkinan exception juga sudah diterapkan pada LEARNFAZZ. Berikut ini adalah penerapan exception handling untuk form yang kami terapkan pada bagian front-end. Penanganan dilakukan dengan memberikan pesan error jika gambar belum diunggah dan menampilkan snack bar jika terjadi exception lainnya.

if (_formKey.currentState.validate()) {
setState(() => _isSubmitting = true);
_formKey.currentState.save();
try {
if (_imageFile == null) {
throw RegisterFormPage.kNoImageErrorMessage;
}
final AuthRepository authRepository =
AppConfig.of(context).authRepository;
final LoginResponse response =
await authRepository.register(name: _name,
email: _email,
identificationNumber: _identificationNumber,
password: _password,
passwordConfirmation: _passwordConfirmation,
role: _role,
photo: _imageFile,);
Navigator.of(context).push<dynamic>(MaterialPageRoute<dynamic>(
builder: (BuildContext context) =>
ShowApiResponsePage(apiResponse: response)));
} catch (e) {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(e.toString()), duration: Duration(seconds: 5)));
}
setState(() => _isSubmitting = false);
}

Prefix k pada variabel

throw RegisterFormPage.kNoImageErrorMessage;

Pada kode di atas, terdapat variable kNoImageErrorMessage yang di awali dengan huruf k kecil. Berdasarkan Style guide for flutter repo, Prefix “k” pada variable tersebut menandakan bahwa variable merupakan sebuah konstanta global.

Operator “.."

void initState() {
super.initState();
_scrollController = ScrollController()
..addListener(() => setState(() {}));
}

Pada kode di atas terdapat operator .. yang merupakan dart cascade operator. Operator ini berguna untuk chaining operations yang tidak mempedulikan return value.

Contohnya adalah operator ini akan membuat kode di bawah ini

final foo = Foo()
..first();
..second();

Bekerja sama saja seperti

final foo = Foo();
foo.first():
foo.second();

Manfaat dari penggunaan cascade operator adalah untuk membuatnya lebih mudah untuk menulis interface yang lebih lancar. Biasanya interface yang lancar bergantung pada method chaining. Contohnya, pada saat ingin menambahkan banyak elemen pada suatu tabel :

myTokenTable.add(“aToken”);
myTokenTable.add(“anotherToken”);
// many lines elided here
// and here
// and on and on
myTokenTable.add(“theUmpteenthToken”);

Mungkin penulisannya akan menjadi lebih mudah jika seperti ini

myTokenTable.add(“aToken”)
.add(“anotherToken”).
// many lines elided here
// and here
// and on and on
.add(“theUmpteenthToken”);

Namun fungsi add() juga membutuhkan myTokenTable sebagai penerimanya. Oleh karena itu, dapat digunakan cascade operator untuk melakukan hal ini.

myTokenTable
..add(“aToken”);
..add(“anotherToken”);
// many lines elided here
// and here
// and on and on
..add(“theUmpteenthToken”);

Referensi :

  1. Martin, R. C. (2009). Clean code: a handbook of agile software craftsmanship. Pearson Education.
  2. CLEAN CODE: EXPLANATION, BENEFITS & BOOKS. Web. 1 April 2019. https://apiumhub.com/tech-blog-barcelona/clean-code-explanation-benefits-books/
  3. Clean Code in five minutes. Web. 1 April 2019. https://issuu.com/softhouse/docs/cleancode_5minutes_120523
  4. What does that 2 dots mean? What is the difference between 1 and 2?.Stack Overflow. Web, 15 April 2019. https://stackoverflow.com/a/53137022
  5. Style guide for flutter repo. Github. Web. 15 April 2019. https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#begin-global-constant-names-with-prefix-k

--

--