Fungsi

Fungsi #

Fungsi adalah unit terkecil dari kode yang bisa diberi nama, diuji, dan digunakan kembali. PHP mendukung fungsi dalam berbagai bentuk — fungsi biasa bernama, closure anonim, arrow function satu baris, dan sejak PHP 8.1 bahkan sintaks first-class callable yang memungkinkan referensi ke fungsi bawaan seperti nilai biasa. Yang membedakan fungsi PHP yang ditulis dengan baik dari yang sekadar berjalan adalah: type declaration yang eksplisit, parameter yang bermakna dengan default yang masuk akal, tidak ada side effect tersembunyi, dan dokumentasi yang cukup lewat PHPDoc. Artikel ini membahas semua aspek fungsi PHP dari dasar hingga fitur modern — termasuk jebakan-jebakan yang sering membuat kode fungsi sulit dipahami dan di-test.

Anatomi Fungsi PHP #

Sebuah fungsi terdiri dari beberapa bagian yang masing-masing memiliki aturan dan opsi konfigurasi:

flowchart LR
    A["function"] --> B["nama()"]
    B --> C["(parameter)"]
    C --> D[": return_type"]
    D --> E["{ body }"]

    C --> C1["tipe $nama"]
    C --> C2["tipe $nama = default"]
    C --> C3["tipe ...$nama variadic"]
    C --> C4["&$nama reference"]

    D --> D1["int | string"]
    D --> D2["?string nullable"]
    D --> D3["void tidak return"]
    D --> D4["never selalu throw/exit"]

Mendefinisikan dan Memanggil Fungsi #

Fungsi didefinisikan dengan keyword function, nama, parameter opsional, dan body. Di PHP, fungsi bisa dipanggil sebelum didefinisikan — definisi fungsi di-hoist ke awal scope file saat parsing.

<?php
// Fungsi sederhana tanpa parameter dan return value
function salam(): void
{
    echo "Halo, Dunia!\n";
}

salam(); // Halo, Dunia!

// Fungsi boleh dipanggil sebelum definisinya di file
cetakVersi();

function cetakVersi(): void
{
    echo "PHP " . PHP_VERSION . "\n";
}
// Ini valid — PHP mem-parse seluruh file sebelum mengeksekusi

Aturan Penamaan Fungsi #

<?php
// ✓ Nama fungsi yang valid — konvensi camelCase untuk PHP modern
function hitungTotal(): float { /* ... */ }
function cariUserById(): ?array { /* ... */ }
function isValid(): bool { /* ... */ }
function formatRupiah(): string { /* ... */ }

// ✓ snake_case juga valid — sering ditemui di kode lama
function hitung_total(): float { /* ... */ }

// Nama fungsi TIDAK case-sensitive (tapi jangan manfaatkan ini)
function TEST(): void { echo "test"; }
test(); // valid, tapi hindari — membingungkan
TEST(); // juga valid

// ✗ Nama yang mendeskripsikan IMPLEMENTASI, bukan TUJUAN
function loopArrayDanJumlahkan(): float { /* ... */ } // jelek
function hitungSubtotal(): float { /* ... */ }        // lebih baik

Parameter dan Argumen #

Parameter adalah variabel yang dideklarasikan dalam definisi fungsi. Argumen adalah nilai aktual yang dikirim saat pemanggilan.

Type Declaration #

Type declaration membuat fungsi lebih aman dan self-documenting — PHP akan melempar TypeError jika tipe tidak cocok (ketika strict_types=1 aktif):

<?php
declare(strict_types=1);

// Tanpa type declaration — menerima apa saja
function tambahLama($a, $b)
{
    return $a + $b;
}

echo tambahLama("3", "4");  // "7" — berhasil karena konversi implisit
echo tambahLama([], true);  // error atau hasil tak terduga

// Dengan type declaration — jelas dan aman
function tambah(int $a, int $b): int
{
    return $a + $b;
}

echo tambah(3, 4);      // 7 — OK
// tambah("3", "4");    // TypeError — string bukan int (dengan strict_types)
// tambah(1.5, 2.5);    // TypeError — float bukan int

// Union type — menerima beberapa tipe
function formatId(int|string $id): string
{
    return is_int($id) ? "ID-{$id}" : strtoupper($id);
}

echo formatId(42);        // "ID-42"
echo formatId("abc-xyz"); // "ABC-XYZ"

Parameter Default #

Parameter dengan nilai default menjadi opsional saat pemanggilan. Nilai default harus berupa ekspresi konstan — tidak bisa berupa pemanggilan fungsi atau variabel:

<?php
function buatSlug(
    string $teks,
    string $separator = '-',
    bool   $hurufKecil = true,
    int    $maxPanjang = 100
): string {
    if ($hurufKecil) {
        $teks = mb_strtolower($teks);
    }

    // Ganti spasi dan karakter non-alphanumeric dengan separator
    $slug = preg_replace('/[^a-z0-9]+/i', $separator, $teks);
    $slug = trim($slug, $separator);

    return mb_substr($slug, 0, $maxPanjang);
}

echo buatSlug("Halo Dunia PHP!");           // "halo-dunia-php"
echo buatSlug("Halo Dunia", "_");           // "halo_dunia"
echo buatSlug("Halo Dunia", "-", false);    // "Halo-Dunia"
echo buatSlug("Judul Panjang", "-", true, 5); // "judul"

Parameter dengan nilai default harus diletakkan di akhir daftar parameter, setelah semua parameter yang wajib. Menempatkan parameter opsional sebelum parameter wajib menyebabkan parse error atau perilaku yang tidak terduga.

// ✗ Parameter opsional sebelum wajib — parse error di PHP 8+
function buat(string $judul = "Tanpa Judul", string $isi): string { }

// ✓ Parameter wajib lebih dulu
function buat(string $isi, string $judul = "Tanpa Judul"): string { }

Parameter Variadic #

Parameter variadic (...) menerima jumlah argumen tak terbatas sebagai array:

<?php
// Variadic sederhana
function jumlahkan(int ...$angka): int
{
    return array_sum($angka);
}

echo jumlahkan(1, 2, 3);          // 6
echo jumlahkan(10, 20, 30, 40);   // 100
echo jumlahkan();                  // 0 — array kosong, sum = 0

// Kombinasi parameter biasa dan variadic
// Parameter variadic harus selalu di posisi terakhir
function log(string $level, string ...$pesan): void
{
    $waktu = date('Y-m-d H:i:s');
    foreach ($pesan as $p) {
        echo "[$waktu][$level] $p\n";
    }
}

log('INFO', 'Server started', 'Listening on port 8080');
log('ERROR', 'Connection failed');

// Spread operator — kebalikan variadic: array menjadi argumen terpisah
$data = [3, 1, 4, 1, 5, 9, 2, 6];
echo jumlahkan(...$data); // sama dengan jumlahkan(3,1,4,1,5,9,2,6)
echo max(...$data);       // 9

Pass-by-Reference #

Secara default PHP meneruskan salinan nilai ke fungsi. Dengan &, fungsi menerima referensi langsung ke variabel asli:

<?php
// Swap dua variabel — kasus klasik untuk reference
function swap(mixed &$a, mixed &$b): void
{
    $temp = $a;
    $a    = $b;
    $b    = $temp;
}

$x = "pertama";
$y = "kedua";
swap($x, $y);
echo "$x $y"; // "kedua pertama"

// Banyak fungsi bawaan PHP menerima array by reference
$buah = ['mangga', 'apel', 'jeruk'];
sort($buah);       // mengubah $buah langsung — by reference
shuffle($buah);    // sama — by reference
array_pop($buah);  // sama

// ANTI-PATTERN: return by reference untuk kalkulasi sederhana
// Lebih sulit dibaca dan debugged daripada return by value
function &dapatkanKonfigurasi(): array
{
    static $config = ['debug' => false];
    return $config; // return referensi ke $config statis
}

// BENAR: return by value — lebih bersih dan mudah dipahami
function dapatkanKonfigurasiV2(): array
{
    return ['debug' => false, 'timeout' => 30];
}

Nilai Kembalian #

Fungsi mengembalikan nilai dengan return. Tanpa return eksplisit, fungsi mengembalikan null.

Return Type dan void #

<?php
declare(strict_types=1);

// Return type eksplisit — jelas dan di-enforce PHP
function hitungLuas(float $panjang, float $lebar): float
{
    return $panjang * $lebar;
}

// void — fungsi tidak mengembalikan nilai
function cetakGaris(int $panjang = 40): void
{
    echo str_repeat('-', $panjang) . "\n";
    // return; boleh, tapi return $nilai; tidak boleh
}

// Nullable return type — bisa mengembalikan tipe atau null
function cariProduk(int $id): ?array
{
    $data = ['id' => 1, 'nama' => 'Laptop'];
    return $data['id'] === $id ? $data : null;
}

$produk = cariProduk(1);
if ($produk !== null) {
    echo $produk['nama']; // "Laptop"
}

// never — fungsi tidak pernah kembali normal
function gagal(string $pesan): never
{
    throw new \RuntimeException($pesan);
}

function redirect(string $url): never
{
    header("Location: $url");
    exit;
}

Mengembalikan Multiple Nilai #

PHP tidak mendukung multiple return value secara native, tapi ada beberapa pola yang digunakan:

<?php
// Pola 1: return array — paling umum
function minMax(array $data): array
{
    return ['min' => min($data), 'max' => max($data)];
}

['min' => $min, 'max' => $max] = minMax([3, 1, 4, 1, 5, 9]);
echo "Min: $min, Max: $max"; // Min: 1, Max: 9

// Pola 2: return object (lebih type-safe, IDE-friendly)
class StatistikHasil
{
    public function __construct(
        public readonly float $min,
        public readonly float $max,
        public readonly float $rata,
    ) {}
}

function hitungStatistik(array $data): StatistikHasil
{
    return new StatistikHasil(
        min: min($data),
        max: max($data),
        rata: array_sum($data) / count($data),
    );
}

$stat = hitungStatistik([10, 20, 30, 40, 50]);
echo "Rata-rata: {$stat->rata}"; // 30

// Pola 3: readonly class / DTO (PHP 8.2+)
readonly class PaginasiHasil
{
    public function __construct(
        public array $data,
        public int   $total,
        public int   $halaman,
        public int   $perHalaman,
    ) {}

    public function totalHalaman(): int
    {
        return (int) ceil($this->total / $this->perHalaman);
    }
}

Closure — Fungsi Anonim #

Closure adalah fungsi yang tidak memiliki nama. Bisa di-assign ke variabel, dikirim sebagai argumen, atau dikembalikan dari fungsi lain. Ini membuat fungsi menjadi first-class value di PHP.

<?php
// Assign ke variabel
$kali2 = function(int $n): int {
    return $n * 2;
};

echo $kali2(5);  // 10

// Sebagai argumen — sangat umum untuk callback
$angka  = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$genap  = array_filter($angka, function(int $n): bool {
    return $n % 2 === 0;
});
$kali3  = array_map(function(int $n): int {
    return $n * 3;
}, $angka);

// Dikembalikan dari fungsi — membuat "fungsi konfigurable"
function buatMultiplier(int $faktor): Closure
{
    return function(int $n) use ($faktor): int {
        return $n * $faktor;
    };
}

$kali5  = buatMultiplier(5);
$kali10 = buatMultiplier(10);

echo $kali5(3);   // 15
echo $kali10(3);  // 30

use — Menangkap Variabel dari Scope Luar #

Closure tidak otomatis mengakses variabel dari scope sekitarnya — harus eksplisit dengan use:

<?php
$batas    = 100;
$kategori = "elektronik";

// Tanpa use — $batas tidak tersedia di dalam closure
$filter = function(array $produk): bool {
    return $produk['harga'] < $batas; // PHP Warning: Undefined variable $batas
};

// Dengan use — tangkap variabel secara eksplisit
$filter = function(array $produk) use ($batas, $kategori): bool {
    return $produk['harga'] < $batas
        && $produk['kategori'] === $kategori;
};

// use by value (default) — salinan nilai saat closure dibuat
$x = 10;
$fn = function() use ($x) { echo $x; };
$x = 99;
$fn(); // 10 — nilai $x saat closure dibuat, bukan saat dipanggil

// use by reference — mengikuti perubahan nilai
$counter = 0;
$increment = function() use (&$counter): void {
    $counter++;
};

$increment();
$increment();
$increment();
echo $counter; // 3 — counter asli berubah

Arrow Function — Closure Ringkas #

Arrow function (fn) diperkenalkan di PHP 7.4 sebagai shorthand closure satu ekspresi. Perbedaan utama dari closure biasa: otomatis menangkap variabel dari scope luar tanpa perlu use.

<?php
// Closure biasa vs arrow function
$kali2Closure = function(int $n): int { return $n * 2; };
$kali2Arrow   = fn(int $n): int => $n * 2;

echo $kali2Arrow(5); // 10

// Arrow function otomatis capture variabel luar
$ppn    = 0.11;
$markup = 0.2;

$hargaAkhir = fn(float $harga): float => $harga * (1 + $ppn) * (1 + $markup);
echo $hargaAkhir(100000); // 133200.0

// Sangat berguna sebagai callback array
$produk = [
    ['nama' => 'Laptop',  'harga' => 15000000],
    ['nama' => 'Monitor', 'harga' => 5000000],
    ['nama' => 'Mouse',   'harga' => 250000],
];

$namaProduk = array_map(fn($p) => $p['nama'], $produk);
$mahal      = array_filter($produk, fn($p) => $p['harga'] > 1000000);

usort($produk, fn($a, $b) => $a['harga'] <=> $b['harga']);

// Arrow function bersarang — capture dari scope yang lebih luar
$diskon = 0.1;
$prosesSemua = fn($items) => array_map(
    fn($item) => [
        ...$item,
        'harga_diskon' => $item['harga'] * (1 - $diskon), // $diskon di-capture
    ],
    $items
);

Closure vs Arrow Function — Kapan Mana #

Gunakan Arrow Function jika:
  ✓ Logika satu ekspresi
  ✓ Butuh variabel dari scope luar (tanpa use yang verbose)
  ✓ Sebagai callback array_map, array_filter, usort, dll.

Gunakan Closure biasa jika:
  ✓ Logika lebih dari satu baris / perlu statement
  ✓ Perlu return early dengan kondisi
  ✓ Butuh kontrol eksplisit variabel yang di-capture (by value vs reference)
  ✓ Closure cukup kompleks sehingga nama variabel use membantu keterbacaan

First-Class Callable (PHP 8.1+) #

Sebelum PHP 8.1, untuk meneruskan fungsi bernama sebagai callable ke array_map atau fungsi lain, kamu harus membungkusnya dalam closure atau menggunakan string nama fungsi. PHP 8.1 memperkenalkan sintaks nama_fungsi(...) yang lebih bersih:

<?php
// Cara lama — membungkus dalam closure yang tidak perlu
$panjang  = array_map(function(string $s): int { return strlen($s); }, $kata);
$panjang2 = array_map('strlen', $kata); // string — tidak type-safe, tidak IDE-friendly

// Cara baru — first-class callable syntax
$panjang3 = array_map(strlen(...), $kata);         // fungsi bawaan
$panjang4 = array_map(mb_strlen(...), $kata);      // juga bawaan

// Bekerja untuk semua callable: fungsi, method statis, method instance
class Formatter
{
    public static function formatRupiah(int $nilai): string
    {
        return 'Rp ' . number_format($nilai, 0, ',', '.');
    }

    public function formatPersen(float $nilai): string
    {
        return number_format($nilai * 100, 1) . '%';
    }
}

$harga       = [15000000, 5000000, 250000];
$formatter   = new Formatter();

// Method statis
$formatted   = array_map(Formatter::formatRupiah(...), $harga);

// Method instance
$persen      = [0.1, 0.2, 0.15];
$formattedPc = array_map($formatter->formatPersen(...), $persen);

// Simpan referensi ke fungsi untuk dipanggil nanti
$fn = strlen(...);
echo $fn("Halo"); // 4

Fungsi Rekursif #

Rekursi adalah teknik di mana fungsi memanggil dirinya sendiri untuk memecah masalah menjadi sub-masalah yang lebih kecil. Setiap fungsi rekursif harus memiliki base case — kondisi yang menghentikan rekursi.

<?php
// Faktorial — contoh klasik rekursi
function faktorial(int $n): int
{
    if ($n < 0) {
        throw new \InvalidArgumentException("Faktorial tidak terdefinisi untuk negatif");
    }

    // Base case — hentikan rekursi
    if ($n <= 1) {
        return 1;
    }

    // Recursive case — panggil diri sendiri dengan input yang lebih kecil
    return $n * faktorial($n - 1);
}

echo faktorial(5);  // 120 — 5 × 4 × 3 × 2 × 1
echo faktorial(0);  // 1   — 0! = 1 by definition

Rekursi dengan Memoization #

Rekursi naif untuk Fibonacci sangat lambat karena menghitung nilai yang sama berkali-kali. Memoization menyimpan hasil yang sudah dihitung:

<?php
// Rekursi naif — sangat lambat untuk n besar
function fibNaif(int $n): int
{
    if ($n <= 1) return $n;
    return fibNaif($n - 1) + fibNaif($n - 2);
    // fibNaif(40) membutuhkan ~330 juta pemanggilan!
}

// Dengan memoization menggunakan variabel statis
function fibMemo(int $n): int
{
    static $cache = [];

    if ($n <= 1) return $n;
    if (isset($cache[$n])) return $cache[$n];

    $cache[$n] = fibMemo($n - 1) + fibMemo($n - 2);
    return $cache[$n];
}

echo fibMemo(50); // 12586269025 — instan, bukan menit

// Rekursi untuk traversal pohon direktori
function scanDirRekursif(string $dir, int $level = 0): void
{
    $indent = str_repeat('  ', $level);
    echo "{$indent}" . basename($dir) . "/\n";

    foreach (scandir($dir) as $entry) {
        if ($entry === '.' || $entry === '..') continue;

        $path = $dir . DIRECTORY_SEPARATOR . $entry;

        if (is_dir($path)) {
            scanDirRekursif($path, $level + 1); // rekursi ke subdirektori
        } else {
            echo "{$indent}  {$entry}\n";
        }
    }
}

Batasan Stack Rekursi #

PHP memiliki batas kedalaman rekursi yang ditentukan oleh ukuran stack. Rekursi yang terlalu dalam menyebabkan fatal error:

<?php
// ANTI-PATTERN: rekursi untuk operasi yang bisa diiterasi
function jumlahRekursif(array $arr, int $i = 0): int
{
    if ($i >= count($arr)) return 0;
    return $arr[$i] + jumlahRekursif($arr, $i + 1);
    // Gagal untuk array besar — stack overflow!
}

// BENAR: gunakan iterasi untuk operasi linier sederhana
function jumlahIteratif(array $arr): int
{
    return array_sum($arr); // atau loop biasa
}

// Rekursi paling tepat untuk: pohon, graf, divide-and-conquer
// (struktur yang secara alami rekursif)

Pure Function dan Side Effect #

Fungsi yang paling mudah dipahami, di-test, dan di-debug adalah pure function — fungsi yang hasilnya hanya bergantung pada input dan tidak mengubah state di luar dirinya.

<?php
// Pure function — input sama → output sama, tidak ada side effect
function hitungPPN(float $harga, float $tarif = 0.11): float
{
    return $harga * $tarif;
}

// Selalu menghasilkan 1100 untuk input (10000, 0.11) — predictable
// Mudah di-unit test tanpa setup apapun

// Fungsi dengan side effect — bergantung pada state eksternal
class OrderService
{
    private array $log = [];

    // Side effect: menulis ke $this->log dan database
    public function buatOrder(array $data): int
    {
        $orderId = $this->db->insert('orders', $data); // side effect: DB write
        $this->log[] = "Order $orderId dibuat";         // side effect: mutate state
        $this->email->kirim($data['email'], $orderId);  // side effect: network call
        return $orderId;
    }
}

// Pola yang lebih bersih: pisahkan pure calculation dari side effect
class OrderCalculator
{
    // Pure — bisa di-test tanpa DB atau email
    public function hitungTotal(array $items, float $diskon): float
    {
        $subtotal = array_reduce(
            $items,
            fn($carry, $item) => $carry + ($item['harga'] * $item['qty']),
            0.0
        );
        return $subtotal * (1 - $diskon) * 1.11; // termasuk PPN
    }
}

Named Arguments (PHP 8.0+) #

Named arguments memungkinkan memanggil fungsi dengan menyebut nama parameternya secara eksplisit, terlepas dari urutannya:

<?php
function buatUser(
    string $nama,
    string $email,
    string $role    = 'viewer',
    bool   $aktif   = true,
    ?string $avatar = null,
): array {
    return compact('nama', 'email', 'role', 'aktif', 'avatar');
}

// Cara lama — harus ingat urutan, semua argumen ditulis
$user = buatUser('Budi', '[email protected]', 'viewer', true, null);

// Named arguments — hanya tulis yang perlu, urutan bebas
$user = buatUser(
    nama:  'Budi',
    email: '[email protected]',
    role:  'admin',   // lewati $aktif dan $avatar yang punya default
);

// Sangat berguna untuk fungsi bawaan PHP yang punya banyak parameter opsional
$hasil = array_slice(
    array:        [1, 2, 3, 4, 5],
    offset:       1,
    length:       3,
    preserve_keys: true,
);

// htmlspecialchars dengan named args — lebih jelas dari urutan posisional
$aman = htmlspecialchars(
    string:  $input,
    flags:   ENT_QUOTES | ENT_HTML5,
    encoding: 'UTF-8',
);

Anti-Pattern Fungsi yang Sering Ditemui #

<?php
// ✗ Anti-pattern 1: fungsi yang melakukan terlalu banyak hal
function prosesDataUser(array $data): void
{
    // validasi input
    // simpan ke database
    // kirim email
    // update cache
    // log ke file
    // kirim notifikasi Slack
    // ... 150 baris kode
}
// Sulit di-test, sulit di-debug, sulit diubah tanpa merusak yang lain

// ✓ Satu fungsi, satu tanggung jawab
function validasiDataUser(array $data): array { /* ... */ }
function simpanUser(array $data): int         { /* ... */ }
function kirimEmailSelamatDatang(int $id): void { /* ... */ }

// ✗ Anti-pattern 2: parameter boolean yang mengubah perilaku fungsi
function dapatkanUser(int $id, bool $denganRelasi): array
{
    if ($denganRelasi) {
        // query dengan JOIN
    } else {
        // query sederhana
    }
}
// dapatkanUser(1, true) — apa arti true? Tidak jelas dari sisi pemanggil

// ✓ Dua fungsi terpisah yang lebih jelas
function dapatkanUser(int $id): array                { /* ... */ }
function dapatkanUserDenganRelasi(int $id): array    { /* ... */ }

// ✗ Anti-pattern 3: output via echo di dalam fungsi bisnis
function hitungDiskon(float $harga, float $persen): float
{
    echo "Menghitung diskon..."; // side effect tersembunyi!
    return $harga * $persen;
}
// Tidak bisa digunakan di konteks yang tidak ingin output ke layar

// ✓ Fungsi hanya return nilai — caller yang putuskan apa yang dilakukan
function hitungDiskonV2(float $harga, float $persen): float
{
    return $harga * $persen;
}

// ✗ Anti-pattern 4: menggunakan variabel global sebagai "parameter tersembunyi"
$koneksiDb = new PDO(/* ... */);

function ambilProduk(int $id): array
{
    global $koneksiDb; // hidden dependency
    // ...
}

// ✓ Dependency injection — kirim lewat parameter
function ambilProdukV2(PDO $db, int $id): array
{
    // mudah di-test dengan mock DB
}

Ringkasan #

  • Type declaration pada parameter dan return type membuat fungsi self-documenting dan memungkinkan PHP dan IDE mendeteksi bug lebih awal. Aktifkan declare(strict_types=1) untuk enforce type secara ketat.
  • Parameter default harus berupa ekspresi konstan dan diletakkan setelah semua parameter wajib. Parameter opsional yang tidak relevan di pemanggilan bisa dilewati dengan named arguments.
  • Named arguments (PHP 8.0+) memungkinkan menyebut nama parameter saat memanggil fungsi — sangat berguna untuk fungsi dengan banyak parameter opsional.
  • Closure menangkap variabel dari scope luar dengan use — by value secara default, atau by reference dengan use (&$var). Arrow function (fn) menangkap variabel luar secara otomatis dan paling tepat untuk ekspresi satu baris.
  • First-class callable (fungsi(...)) adalah cara modern merujuk fungsi bernama sebagai nilai — lebih bersih dan type-safe dari string nama fungsi.
  • Rekursi paling tepat untuk struktur yang secara alami rekursif (pohon, graf, divide-and-conquer). Gunakan memoization untuk menghindari komputasi ulang, dan preferensikan iterasi untuk operasi linier sederhana.
  • Pure function — hasil hanya bergantung pada input, tidak mengubah state eksternal — lebih mudah dipahami, di-test, dan di-debug. Pisahkan kalkulasi murni dari side effect (I/O, DB, email).
  • Satu fungsi, satu tanggung jawab — jika fungsi membutuhkan kata “dan” untuk mendeskripsikan tugasnya, kemungkinan besar perlu dipecah.

← Sebelumnya: Perulangan   Berikutnya: Kelas →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact