Tugas 3 Pemrograman Berbasis Desktop - Sistem Pemesanan Restoran
Oleh: Khafid Ilham
#TetaplahBerbeda
Catatan Penting: Artikel ini adalah penjelasan dari arsip Tugas 3 yang sudah selesai dikerjakan. Tujuan saya membagikan ini adalah untuk membantu teman-teman yang mungkin masih kesulitan memahami konsep pemrograman desktop, khususnya implementasi sistem restoran sederhana menggunakan Java. Mari kita belajar bersama! 😊
Pendahuluan
Hai teman-teman! Hari ini saya akan berbagi pengalaman dalam mengembangkan aplikasi manajemen restoran sederhana menggunakan Java. Aplikasi ini merupakan bagian dari Tugas 3 mata kuliah Pemrograman Berbasis Desktop di Universitas Terbuka.
Penjelasan terkait konsep-konsep tugas:
-
Abstraksi dan Inheritance:
- Abstraksi diterapkan dengan membuat kelas abstrak
MenuItem
yang memiliki metode abstraktampilMenu()
. Kelas ini menjadi dasar bagi kelas-kelas turunan sepertiMakanan
,Minuman
, danDiskon
. - Inheritance digunakan dengan kelas
Makanan
,Minuman
, danDiskon
yang merupakan subclass dariMenuItem
. Kelas-kelas ini mewarisi atribut dan metode dariMenuItem
dan mengimplementasikan metodetampilMenu()
untuk menampilkan informasi yang lebih spesifik.
- Abstraksi diterapkan dengan membuat kelas abstrak
-
Encapsulation:
- Atribut-atribut dalam kelas seperti
nama
,harga
, dankategori
diMenuItem
, serta atribut-atribut lainnya sepertijenisMakanan
,jenisMinuman
, dandiskon
, bersifat private dan hanya dapat diakses melalui metode getter (misalnyagetNama()
,getHarga()
, dll). Ini adalah penerapan prinsip encapsulation.
- Atribut-atribut dalam kelas seperti
-
Polymorphism:
- Polymorphism terjadi saat metode
tampilMenu()
dipanggil pada objekMenuItem
. Setiap objek turunan sepertiMakanan
,Minuman
, danDiskon
memiliki implementasitampilMenu()
yang berbeda. Meskipun menggunakan tipe dataMenuItem
, hasil yang ditampilkan tergantung pada jenis objek yang sebenarnya (polymorphism).
- Polymorphism terjadi saat metode
-
Exception:
- Pengecualian digunakan dalam kelas
Menu
saat mencari menu yang tidak ada dengan metodecariMenu()
. Jika item tidak ditemukan, maka akan dilemparkan exception yang menangani kasus tersebut. - Juga digunakan saat memuat atau menyimpan file, jika ada kesalahan dalam I/O, pengecualian akan ditangani dengan pesan error.
- Pengecualian digunakan dalam kelas
-
I/O dan Operasi File:
- Operasi I/O digunakan untuk menyimpan dan memuat menu serta struk pesanan ke dan dari file dengan menggunakan
BufferedWriter
danBufferedReader
. - Program memungkinkan untuk memuat file menu dari disk, menyimpan perubahan ke file, serta menyimpan dan memuat struk pesanan pelanggan.
- Operasi I/O digunakan untuk menyimpan dan memuat menu serta struk pesanan ke dan dari file dengan menggunakan
-
Struktur Keputusan dan Pengulangan:
- Struktur keputusan digunakan di banyak tempat, seperti dalam pemilihan jenis menu pada menu utama (
switch
), serta dalam memeriksa kategori item menu pada saat menyimpan dan memuat file. - Struktur pengulangan (looping) digunakan di berbagai tempat, seperti dalam iterasi ArrayList
daftarMenu
dandaftarPesanan
untuk menampilkan daftar menu atau pesanan.
- Struktur keputusan digunakan di banyak tempat, seperti dalam pemilihan jenis menu pada menu utama (
-
Array dan String:
- Array digunakan untuk menyimpan item menu dan pesanan dalam bentuk
ArrayList<MenuItem>
. - String digunakan untuk menyimpan dan memanipulasi data, seperti nama menu, jenis menu, dan dalam operasi I/O (membaca dan menulis file).
- Array digunakan untuk menyimpan item menu dan pesanan dalam bentuk
- Full Code :
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
// 1. Buatlah sebuah kelas abstrak MenuItem yang akan menjadi kelas dasar
// untuk semua menu item dalam restoran. Kelas ini harus memiliki atribut nama
// (String), harga (double), dan kategori (String). Definisikan metode abstrak
// tampilMenu() yang akan digunakan untuk menampilkan informasi tentang item menu.
abstract class MenuItem {
private String nama;
private double harga;
private String kategori;
public MenuItem(String nama, double harga, String kategori) {
this.nama = nama;
this.harga = harga;
this.kategori = kategori;
}
public String getNama() {
return nama;
}
public double getHarga() {
return harga;
}
public String getKategori() {
return kategori;
}
// Kelas abstrak adalah kelas yang tidak dapat langsung diinstansiasi atau dibuat objeknya.
// Kelas ini dirancang untuk menjadi kelas dasar atau superclass yang akan diwarisi
// oleh kelas-kelas lainnya.
public abstract void tampilMenu();
// Kelas biasa adalah kelas yang dapat langsung diinstansiasi,
// artinya Anda bisa membuat objek dari kelas ini secara langsung.
// public void tampilMenu() {
// System.out.println("Menu: " + nama + " | Harga: " + harga + " | Kategori: " + kategori);
// }
}
// 2. Buatlah tiga kelas turunan dari MenuItem: Makanan, Minuman, dan Diskon.
// • Kelas Makanan dan Minuman adalah subkelas dari MenuItem dan harus memiliki
// atribut tambahan yang sesuai dengan jenisnya (misalnya, jenisMakanan dan jenisMinuman).
// Implementasikan metode tampilMenu() untuk menampilkan informasi khusus tentang makanan dan minuman.
class Makanan extends MenuItem {
private String jenisMakanan;
public Makanan(String nama, double harga, String kategori, String jenisMakanan) {
super(nama, harga, kategori);
this.jenisMakanan = jenisMakanan;
}
// Getter untuk jenisMakanan
public String getJenisMakanan() {
return jenisMakanan;
}
@Override
public void tampilMenu() {
System.out.println("Makanan: " + getNama() + " | Harga: Rp" + getHarga() + " | Jenis: " + jenisMakanan);
}
}
class Minuman extends MenuItem {
private String jenisMinuman;
public Minuman(String nama, double harga, String kategori, String jenisMinuman) {
super(nama, harga, kategori);
this.jenisMinuman = jenisMinuman;
}
// Getter untuk jenisMinuman
public String getJenisMinuman() {
return jenisMinuman;
}
@Override
public void tampilMenu() {
System.out.println("Minuman: " + getNama() + " | Harga: Rp" + getHarga() + " | Jenis: " + jenisMinuman);
}
}
// • Kelas Diskon adalah subkelas dari MenuItem yang akan digunakan untuk menerapkan
// diskon khusus pada menu. Kelas ini harus memiliki atribut diskon (double) dan
// mengimplementasikan metode tampilMenu() untuk menampilkan informasi tentang diskon yang ditawarkan.
class Diskon extends MenuItem {
private double diskon;
public Diskon(String nama, double harga, String kategori, double diskon) {
super(nama, harga, kategori);
this.diskon = diskon;
}
// Getter untuk diskon
public double getDiskon() {
return diskon;
}
@Override
public void tampilMenu() {
System.out.println("Diskon: " + getNama() + " | Persentase Diskon: " + diskon + "%");
}
public double hitungHargaDiskon() {
return getHarga() - (getHarga() * diskon / 100);
}
}
// 3. Buatlah sebuah kelas Menu yang akan digunakan untuk mengelola semua item menu
// dalam restoran. Kelas ini harus memiliki atribut berupa sebuah ArrayList untuk
// menyimpan semua item menu.
class Menu {
private ArrayList<MenuItem> daftarMenu = new ArrayList<>();
public void tambahMenu(MenuItem item) {
daftarMenu.add(item);
System.out.println(item.getNama() + " berhasil ditambahkan ke menu.");
}
public void tampilkanMenu() {
System.out.println("\n--- Daftar Menu ---");
for (MenuItem item : daftarMenu) {
item.tampilMenu();
}
}
public MenuItem cariMenu(String nama) throws Exception {
for (MenuItem item : daftarMenu) {
if (item.getNama().equalsIgnoreCase(nama)) {
return item;
}
}
throw new Exception("Item tidak ditemukan!");
}
public MenuItem cariDiskon(double harga) throws Exception {
for (MenuItem item : daftarMenu) {
if (harga >= item.getHarga() && item instanceof Diskon) {
return item;
}
}
throw new Exception("Diskon tidak ditemukan!");
}
// Menyimpan menu ke file
public void simpanMenuKeFile(String namaFile) {
// Membuat folder jika belum ada
File folder = new File("File Tugas");
if (!folder.exists()) {
folder.mkdirs(); // Membuat folder
}
// Menyimpan file
try (BufferedWriter writer = new BufferedWriter(new FileWriter(namaFile))) {
for (MenuItem item : daftarMenu) {
String data = item.getNama() + "," + item.getHarga() + "," + item.getKategori();
if (item instanceof Makanan) {
data += "," + ((Makanan) item).getJenisMakanan();
} else if (item instanceof Minuman) {
data += "," + ((Minuman) item).getJenisMinuman();
} else if (item instanceof Diskon) {
data += "," + ((Diskon) item).getDiskon();
}
writer.write(data);
writer.newLine();
}
System.out.println("Menu berhasil disimpan ke file: " + namaFile);
} catch (IOException e) {
System.out.println("Kesalahan saat menyimpan menu: " + e.getMessage());
}
}
// Memuat menu dari file
public void muatMenuDariFile(String namaFile) {
try (BufferedReader reader = new BufferedReader(new FileReader(namaFile))) {
String baris;
while ((baris = reader.readLine()) != null) {
String[] data = baris.split(",");
String nama = data[0];
double harga = Double.parseDouble(data[1]);
String kategori = data[2];
if (kategori.equals("Makanan")) {
daftarMenu.add(new Makanan(nama, harga, kategori, data[3]));
} else if (kategori.equals("Minuman")) {
daftarMenu.add(new Minuman(nama, harga, kategori, data[3]));
} else if (kategori.equals("Diskon")) {
double diskon = Double.parseDouble(data[3]);
daftarMenu.add(new Diskon(nama, harga, kategori, diskon));
}
}
System.out.println("Menu berhasil dimuat dari file: " + namaFile);
} catch (IOException e) {
System.out.println("Kesalahan saat memuat menu: " + e.getMessage());
}
}
}
// 4. Buatlah kelas Pesanan yang akan digunakan untuk mencatat
// pesanan pelanggan. Kelas ini harus memiliki atribut berupa ArrayList
// untuk menyimpan item-item yang dipesan oleh pelanggan.
class Pesanan {
private ArrayList<MenuItem> daftarPesanan = new ArrayList<>();
public void tambahPesanan(MenuItem item) {
// Validasi: pastikan diskon hanya ditambahkan sekali
if (item instanceof Diskon) {
// Periksa apakah sudah ada item diskon dalam daftar pesanan
boolean diskonSudahAda = false;
for (MenuItem pesananItem : daftarPesanan) {
if (pesananItem instanceof Diskon) {
diskonSudahAda = true;
break;
}
}
// Jika diskon sudah ada, tampilkan pesan dan tidak tambahkan item
if (diskonSudahAda) {
// System.out.println("Diskon hanya bisa diterapkan satu kali.");
return; // Keluar dari metode jika diskon sudah ada
}
}
daftarPesanan.add(item);
System.out.println(item.getNama() + " ditambahkan ke pesanan.");
}
public void tampilkanPesanan() {
System.out.println("\n--- Daftar Pesanan ---");
// Menyimpan item-item tanpa diskon
ArrayList<MenuItem> pesananTanpaDiskon = new ArrayList<>();
// Menyimpan item-item yang memiliki diskon
ArrayList<MenuItem> pesananDenganDiskon = new ArrayList<>();
// Memisahkan item-item yang memiliki diskon dan yang tidak
for (MenuItem item : daftarPesanan) {
if (item instanceof Diskon) {
pesananDenganDiskon.add(item);
} else {
pesananTanpaDiskon.add(item);
}
}
// Menampilkan item tanpa diskon
for (MenuItem item : pesananTanpaDiskon) {
item.tampilMenu();
}
// Menampilkan item dengan diskon terakhir
for (MenuItem item : pesananDenganDiskon) {
item.tampilMenu();
}
}
public double hitungTotal() {
double total = 0;
for (MenuItem item : daftarPesanan) {
if (item instanceof Diskon) {
total -= (total * ((Diskon) item).getDiskon() / 100);
} else {
total += item.getHarga();
}
}
return total;
}
// Menyimpan struk pesanan ke file
public void simpanStrukPesanan(String namaFile) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(namaFile))) {
writer.write("--- Struk Pesanan ---");
writer.newLine();
// Menyimpan item-item tanpa diskon
ArrayList<MenuItem> pesananTanpaDiskon = new ArrayList<>();
// Menyimpan item-item yang memiliki diskon
ArrayList<MenuItem> pesananDenganDiskon = new ArrayList<>();
// Memisahkan item-item yang memiliki diskon dan yang tidak
for (MenuItem item : daftarPesanan) {
if (item instanceof Diskon) {
pesananDenganDiskon.add(item);
} else {
pesananTanpaDiskon.add(item);
}
}
// Menulis item tanpa diskon ke file
for (MenuItem item : pesananTanpaDiskon) {
writer.write(item.getNama() + " - Rp" + item.getHarga());
writer.newLine();
}
// Menulis item dengan diskon ke file
for (MenuItem item : pesananDenganDiskon) {
writer.write(item.getNama() + " - Rp" + item.getHarga());
writer.newLine();
}
// Menulis total ke file
writer.write("Total: Rp" + hitungTotal());
writer.newLine();
writer.write("--------------------");
writer.newLine();
System.out.println("Struk berhasil disimpan ke file: " + namaFile);
} catch (IOException e) {
System.out.println("Kesalahan saat menyimpan struk: " + e.getMessage());
}
}
// Memuat struk pesanan dari file
public void muatStrukPesanan(String namaFile) {
try (BufferedReader reader = new BufferedReader(new FileReader(namaFile))) {
String baris;
// System.out.println("--- Struk Pesanan ---");
while ((baris = reader.readLine()) != null) {
System.out.println(baris);
}
} catch (IOException e) {
System.out.println("Kesalahan saat membaca struk: " + e.getMessage());
}
}
}
// 5. Implementasikan konsep inheritance dengan benar antara kelas-kelas ini.
// 6. Implementasikan konsep encapsulation dengan membatasi akses ke atribut-atribut kelas.
// 7. Pergunaan pengecualian (exception) yang mungkin terjadi, seperti ketika mencoba
// mengakses item yang tidak ada dalam menu.
// 8. Program harus memiliki menu utama yang memungkinkan pengguna untuk:
// • Menambahkan item baru ke menu (makanan, minuman, atau diskon).
// • Menampilkan menu restoran.
// • Menerima pesanan dari pelanggan dan mencatatnya.
// • Menghitung total biaya pesanan dengan mempertimbangkan diskon yang mungkin diterapkan.
// • Menampilkan struk pesanan pelanggan.
// • Keluar dari program.
// 9. Implementasikan operasi I/O dan operasi file untuk menyimpan dan memuat daftar
// menu dari sebuah file teks, dan juga menyimpan struk pesananan pelanggan dan memuat dari file teks.
// 10. Gunakan struktur keputusan dan pengulangan sesuai dengan kebutuhan, seperti saat
// menampilkan menu dan memproses pesanan.
public class ManajemenRestoran {
public static void main(String[] args) {
Menu menu = new Menu();
Pesanan pesanan = new Pesanan();
Scanner scanner = new Scanner(System.in);
// Muat menu dari file saat program dimulai
menu.muatMenuDariFile("D:/KULIAH/2. TUTON/KHAFID/SEMESTER 5/Pemrograman Berbasis Desktop - LAPRAK/Aktivitas Belajar 12/File Tugas/IO/menu.txt");
while (true) {
System.out.println("\n--- Menu Utama ---");
System.out.println("1. Tambah Menu");
System.out.println("2. Tampilkan Menu");
System.out.println("3. Buat Pesanan");
System.out.println("4. Hitung Total Pesanan");
System.out.println("5. Simpan Menu ke File");
System.out.println("6. Simpan Struk Pesanan");
System.out.println("7. Muat Struk Pesanan");
System.out.println("8. Keluar");
System.out.print("Pilih opsi: ");
int pilihan = scanner.nextInt();
scanner.nextLine();
try {
switch (pilihan) {
case 1:
System.out.println("1. Makanan");
System.out.println("2. Minuman");
System.out.println("3. Diskon");
System.out.print("Pilih jenis menu: ");
int jenis = scanner.nextInt();
scanner.nextLine();
System.out.print("Nama: ");
String nama = scanner.nextLine();
System.out.print("Harga: ");
double harga = scanner.nextDouble();
scanner.nextLine();
if (jenis == 1) {
System.out.print("Jenis Makanan: ");
String jenisMakanan = scanner.nextLine();
menu.tambahMenu(new Makanan(nama, harga, "Makanan", jenisMakanan));
} else if (jenis == 2) {
System.out.print("Jenis Minuman: ");
String jenisMinuman = scanner.nextLine();
menu.tambahMenu(new Minuman(nama, harga, "Minuman", jenisMinuman));
} else if (jenis == 3) {
System.out.print("Diskon (%): ");
double diskon = scanner.nextDouble();
menu.tambahMenu(new Diskon(nama, harga, "Diskon", diskon));
}
break;
case 2:
menu.tampilkanMenu();
break;
case 3:
System.out.print("Masukkan nama item yang dipesan: ");
String namaItem = scanner.nextLine();
MenuItem item = menu.cariMenu(namaItem);
pesanan.tambahPesanan(item);
MenuItem itemDiskon = menu.cariDiskon(item.getHarga());
pesanan.tambahPesanan(itemDiskon);
break;
case 4:
pesanan.tampilkanPesanan();
System.out.println("Total Harga: Rp" + pesanan.hitungTotal());
break;
case 5:
menu.simpanMenuKeFile("D:/KULIAH/2. TUTON/KHAFID/SEMESTER 5/Pemrograman Berbasis Desktop - LAPRAK/Aktivitas Belajar 12/File Tugas/IO/menu.txt");
break;
case 6:
pesanan.simpanStrukPesanan("D:/KULIAH/2. TUTON/KHAFID/SEMESTER 5/Pemrograman Berbasis Desktop - LAPRAK/Aktivitas Belajar 12/File Tugas/IO/struk.txt");
break;
case 7:
pesanan.muatStrukPesanan("D:/KULIAH/2. TUTON/KHAFID/SEMESTER 5/Pemrograman Berbasis Desktop - LAPRAK/Aktivitas Belajar 12/File Tugas/IO/struk.txt");
break;
case 8:
System.out.println("Keluar dari program.");
return;
default:
System.out.println("Opsi tidak valid.");
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}