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:
| Area | Baris grid | Komponen | Properti penting |
|---|---|---|---|
| Kontrol | 'fit' | DropDownKota, EditFieldTahun, MuatButton | Items, Limits [2000 2025] |
| Grafik | '1x' | UIAxes | label sumbu, legend |
| Ringkasan | 'fit' | PanelRingkasan + LabelRingkasan | FontWeight 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:
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
endMari kita bedah baris-baris kode di atas:
- Baris 3-9 (properti komponen): nama komponen mengikuti perannya (
DropDownKota, bukanDropDown2) — setiap nama adalah dokumentasi mini. - Baris 11-12 (
dataTable,hasil): dua properti state — data mentah dan hasil analisis; keduanya dipisah agarhasilbisa digambar ulang tanpa memuat ulang berkas. - 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 dijagaLimitsdi komponennya. - Baris 26-31 (baca + hitung): pembacaan berkas dan komputasi statistik didelegasikan ke
readmatrixdananalisisCuaca(); callback tetap setengah layar. - 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:
| Praktik | Alasan |
|---|---|
Ukuran jendela minimum wajar (Position bawaan tidak terlalu kecil) | komponen 'fit' bisa saling menimpa di jendela sempit |
FontSize ≥ 12 dan kontras warna cukup | keterbacaan untuk semua pengguna |
| Nomenklatur komponen per peran | app.EditFieldTahun terbaca; app.EditField3 tidak |
| Callback pendek, logika di fungsi model | fungsi model bisa diuji; callback tidak |
Uji urutan fokus Tab saat menguji | pengguna 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:
| Skenario | Aksi pengguna | Hasil yang diharapkan |
|---|---|---|
| Alur normal | pilih kota, isi tahun 2023, klik Muat | grafik tampil, ringkasan terisi |
| Input salah | tahun 1999, klik Muat | uialert rentang tahun, tidak ada eksekusi |
| Data kosong | muat berkas tanpa baris | pesan jelas, app tetap hidup |
| Klik ganda | Muat ditekan cepat dua kali | tombol terkunci selama proses |
| Ubah ukuran | perbesar jendela | grafik 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:
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:
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 hujanNilai 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.