Tujuh chapter sebelumnya memberi kita seluruh bahan: komponen, callback, aliran data, plot, dan validasi. Chapter penutup ini merakitnya menjadi satu aplikasi utuh — Analisis Data Cuaca — dari nol, tetapi kali ini kebalikan urutannya: kita tidak mulai dari menyeret komponen. Perancangan app yang berhasil dimulai dari alur kerja pengguna, bukan dari tampilan. Cakupannya:

  • alur perancangan: user flow → wireframe → komponen → state → callback
  • struktur class app untuk aplikasi analisis
  • implementasi bertahap dan praktik terbaik
  • rencana pengujian manual dan pengujian fungsi inti
  • mengemas app agar mudah dibagikan

Alur Perancangan #

Kebutuhan kita: pengguna memilih kota dan tahun, memuat data cuaca, melihat grafik suhu dan curah hujan, lalu membaca ringkasan statistik. Rantai keputusan perancangannya berjajar sebagai berikut:

Diagram tersebut membaca kiri ke kanan: setiap tahap hanya menjawab satu pertanyaan. User flow menjawab “apa yang dilakukan pengguna?”; wireframe menjawab “di mana letaknya?”; daftar komponen menjawab “objek apa yang dibutuhkan?”; callback menjawab “apa reaksinya?”. Melompati tahap — misalnya langsung mendesain tampilan — adalah penyebab klasik app yang indah tetapi alurnya mengular.

Wireframe dan Tata Letak #

Wireframe app kita sederhana: tiga pita vertikal di dalam satu uigridlayout — kontrol di atas, grafik di tengah, ringkasan di bawah:

AreaBaris gridKomponenProperti penting
Kontrol'fit'DropDownKota, EditFieldTahun, MuatButtonItems, Limits [2000 2025]
Grafik'1x'UIAxeslabel sumbu, legend
Ringkasan'fit'PanelRingkasan + LabelRingkasanFontWeight bold

Pita tengah '1x' membuat grafik memakan semua sisa ruang — area paling penting bagi mata pengguna, sementara kontrol dan ringkasan cukup setinggi isinya.

Struktur Class App #

Dari wireframe, struktur class tersusun hampir sendirinya — komponen mengikuti area, state mengikuti alur data:

matlab
classdef appCuaca < matlab.apps.AppBase
    properties (Access = public)
        UIFigure        matlab.ui.Figure
        DropDownKota    matlab.ui.control.DropDown
        EditFieldTahun  matlab.ui.control.NumericEditField
        MuatButton      matlab.ui.control.Button
        UIAxes          matlab.ui.control.UIAxes
        PanelRingkasan  matlab.ui.container.Panel
        LabelRingkasan  matlab.ui.control.Label

        dataTable       double = []      % matriks [suhu, hujan]
        hasil           struct = struct()
    end

    methods (Access = private)
        function MuatButtonPushed(app, event)
            input = struct('kota', app.DropDownKota.Value, ...
                'tahunTeks', num2str(app.EditFieldTahun.Value));
            [ok, pesan] = validasiInput(input);
            if ~ok
                uialert(app.UIFigure, pesan, "Input Tidak Valid", ...
                    Icon="warning");
                return
            end

            app.MuatButton.Enable = "off";
            app.dataTable = readmatrix("data_cuaca.csv");
            app.hasil = analisisCuaca(struct( ...
                'kota',  input.kota, ...
                'suhu',  app.dataTable(:, 1), ...
                'hujan', app.dataTable(:, 2)));

            gambarGrafik(app);                 % method pembantu plot
            app.LabelRingkasan.Text = app.hasil.teksRingkasan;
            app.MuatButton.Enable = "on";
        end
    end
end

Mari kita bedah baris-baris kode di atas:

  1. Baris 3-9 (properti komponen): nama komponen mengikuti perannya (DropDownKota, bukan DropDown2) — setiap nama adalah dokumentasi mini.
  2. Baris 11-12 (dataTable, hasil): dua properti state — data mentah dan hasil analisis; keduanya dipisah agar hasil bisa digambar ulang tanpa memuat ulang berkas.
  3. Baris 17-24 (validasi): seluruh aturan form dilimpahkan ke validasiInput() — pola [ok, pesan] yang sama dengan chapter validasi, dengan aturan yang disesuaikan untuk field kota dan tahun; sementara rentang tahun sudah dijaga Limits di komponennya.
  4. Baris 26-31 (baca + hitung): pembacaan berkas dan komputasi statistik didelegasikan ke readmatrix dan analisisCuaca(); callback tetap setengah layar.
  5. Baris 33-36 (tulis hasil + pulihkan): grafik dan ringkasan diperbarui lewat method pembantu, lalu tombol diaktifkan kembali.

Praktik Terbaik Perancangan #

Praktik yang membedakan app buatan pemula dan app yang terpelihara:

PraktikAlasan
Ukuran jendela minimum wajar (Position bawaan tidak terlalu kecil)komponen 'fit' bisa saling menimpa di jendela sempit
FontSize ≥ 12 dan kontras warna cukupketerbacaan untuk semua pengguna
Nomenklatur komponen per peranapp.EditFieldTahun terbaca; app.EditField3 tidak
Callback pendek, logika di fungsi modelfungsi model bisa diuji; callback tidak
Uji urutan fokus Tab saat mengujipengguna keyboard mengisi form tanpa mouse

Pengujian Aplikasi #

Pengujian app berlapis dua. Lapisan fungsi inti berjalan otomatis — analisisCuaca() dan validasiInput() adalah fungsi murni yang teruji tanpa GUI (bab sebelumnya memakai keduanya). Lapisan manual menguji jalan app sebagai satu kesatuan:

SkenarioAksi penggunaHasil yang diharapkan
Alur normalpilih kota, isi tahun 2023, klik Muatgrafik tampil, ringkasan terisi
Input salahtahun 1999, klik Muatuialert rentang tahun, tidak ada eksekusi
Data kosongmuat berkas tanpa barispesan jelas, app tetap hidup
Klik gandaMuat ditekan cepat dua kalitombol terkunci selama proses
Ubah ukuranperbesar jendelagrafik ikut membesar, ringkasan tetap 'fit'

Fungsi Inti, Teruji #

Fungsi analisisCuaca() adalah jantung app — seluruh angka yang tampil di grafik dan ringkasan lahir dari sini. Berkas contoh.m membuktikannya dengan data satu minggu:

matlab
data = struct( ...
    'kota',  'Bandung', ...
    'suhu',  [23.1 24.5 22.8 25.2 26.1 24.9 23.6], ...
    'hujan', [0 2.5 0 12.3 8.1 0 4.4]);

hasil = analisisCuaca(data);

fprintf('Analisis %s (%d hari data)\n', data.kota, numel(data.suhu));
fprintf('suhu  : rata=%.1f min=%.1f maks=%.1f\n', ...
    hasil.suhu.rata, hasil.suhu.min, hasil.suhu.maks);
fprintf('hujan : total=%.1f mm hari-hujan=%d intensitas-maks=%.1f\n', ...
    hasil.hujan.total, hasil.hujan.hariHujan, hasil.hujan.maks);
fprintf('Panel ringkasan menerima teks:\n   "%s"\n', ...
    hasil.teksRingkasan);

Output yang Dihasilkan:

text
Analisis Bandung (7 hari data)
suhu  : rata=24.3 min=22.8 maks=26.1
hujan : total=27.3 mm hari-hujan=4 intensitas-maks=12.3
Panel ringkasan menerima teks:
   "Bandung: suhu rata-rata 24.3 C, hujan total 27.3 mm"
UIAxes menerima 7 titik untuk seri suhu dan hujan

Nilai 24.3 dan 27.3 itulah yang di app sungguhan mengalir ke app.LabelRingkasan.Text dan ke sumbu UIAxes — callback hanya menyalinnya, tidak pernah menghitungnya.

Mengemas App untuk Dibagikan #

Cara tercepat membagikan app kepada pengguna MATLAB: kirim berkas .mlapp-nya dan penerima menjalankan nama app-nya. Untuk distribusi yang lebih rapi — app beserta data contoh dan fungsi pendukungnya sebagai satu paket terpasang — gunakan fitur Package App di lingkungan MATLAB: paket menghasilkan berkas .mlappinstall yang pengguna pasang sekali lewat Add-On Explorer, lalu app muncul di galeri Apps mereka bersama ikon dan keterangan yang kita tulis.

Ringkasan #

Merancang app analisis menempuh alur tetap: kebutuhan → user flow → wireframe tiga pita (kontrol 'fit', grafik '1x', ringkasan 'fit') → daftar komponen dan state → callback per aksi. Class appCuaca menyimpan komponen bernama per peran plus state dataTable dan hasil; callback MuatButtonPushed hanya berurutan: validasi (validasiInput), muat (readmatrix), hitung (analisisCuaca), tulis (grafik + ringkasan). Pengujian berlapis — fungsi inti teruji otomatis di contoh.m, alur app diuji manual dengan skenario yang didominasi input salah — dan app siap dibagikan lewat berkas .mlapp atau Package App.