Menu
CoddyTech

Antarmuka Umum

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan Lua di Coddy. Pelajaran 40 dari 70.

Duck typing menunjukkan kepada kita bahwa class yang tidak saling berkaitan dapat bekerja sama jika memiliki nama method yang sama. Gagasan ini mengarah pada konsep desain yang kuat: antarmuka umum. Ketika kamu sengaja merancang beberapa class agar memiliki tanda tangan method yang sama, kamu menciptakan komponen yang dapat saling dipertukarkan.

Bayangkan kamu sedang membangun sistem pencatatan log. Kamu mungkin ingin mengirim pesan ke berbagai tujuan: file, layar, atau bahkan jaringan. Alih-alih menulis kode terpisah untuk setiap tujuan, kamu merancang semua class output agar menerapkan method :write() yang sama:

local LogFile = {}
LogFile.__index = LogFile

function LogFile:new(filename)
    local obj = {filename = filename}
    setmetatable(obj, LogFile)
    return obj
end

function LogFile:write(message)
    print("[FILE:" .. self.filename .. "] " .. message)
end

local Screen = {}
Screen.__index = Screen

function Screen:new()
    local obj = {}
    setmetatable(obj, Screen)
    return obj
end

function Screen:write(message)
    print("[SCREEN] " .. message)
end

Sekarang, kode apa pun yang perlu menampilkan pesan dapat menerima kedua tipe:

local function logMessage(output, msg)
    output:write(msg)
end

local file = LogFile:new("app.log")
local screen = Screen:new()

logMessage(file, "Starting up")    -- [FILE:app.log] Starting up
logMessage(screen, "Starting up")  -- [SCREEN] Starting up

Fungsi logMessage tidak tahu atau peduli class apa yang diterimanya. Fungsi itu hanya mengharapkan method :write(). Ini membuat kodemu fleksibel. Kamu bisa menambahkan jenis output baru nanti tanpa mengubah fungsi yang sudah ada.

challenge icon

Tantangan

Mudah

Mari bangun sistem pemrosesan pembayaran yang memungkinkan berbagai metode pembayaran digunakan secara bergantian! Kamu akan membuat dua class pembayaran yang sama sekali tidak terkait, tetapi memiliki antarmuka umum, yaitu method :process(amount). Dengan begitu, kode apa pun yang menangani pembayaran dapat bekerja dengan kedua jenis tersebut tanpa mengetahui perbedaannya.

Kamu akan mengatur kodemu dalam tiga file:

  • CreditCard.lua: Class pembayaran dengan konstruktor :new(cardNumber) yang menyimpan nomor kartu. Method :process(amount) harus mencetak Charging {amount} to card {cardNumber}.
  • BankTransfer.lua: Class pembayaran terpisah sepenuhnya dengan konstruktor :new(accountId). Method :process(amount) harus mencetak Transferring {amount} from account {accountId}.
  • main.lua: Buat fungsi bernama handlePayment(paymentMethod, amount) yang menerima object pembayaran apa pun dan sejumlah nilai, lalu memanggil :process(amount) pada object tersebut. Fungsi ini tidak perlu mengetahui apakah object yang ditangani adalah kartu kredit atau transfer bank. Fungsi ini hanya mengharapkan object tersebut memiliki method :process().

Kamu akan menerima tiga input:

  1. Nomor kartu kredit (misalnya, 4532-1234-5678)
  2. ID rekening bank (misalnya, ACC-9876)
  3. Jumlah pembayaran (misalnya, 150)

Di file utama, buat satu instance untuk setiap jenis pembayaran menggunakan dua input pertama. Lalu gunakan fungsi handlePayment untuk memproses jumlah yang diberikan melalui kedua metode pembayaran: pertama kartu kredit, lalu transfer bank.

Misalnya, jika inputnya adalah 1111-2222-3333, ACC-5555, dan 75, outputnya akan seperti berikut:

Charging 75 to card 1111-2222-3333
Transferring 75 from account ACC-5555

Keunggulan desain ini adalah fungsi handlePayment dapat bekerja dengan object apa pun yang mengimplementasikan :process(). Kamu dapat menambahkan class PayPal besok, dan selama class tersebut memiliki method :process(amount), class itu akan bekerja dengan fungsi yang sudah ada tanpa perubahan apa pun!

Coba sendiri

-- Impor class pembayaran
local CreditCard = require('CreditCard')
local BankTransfer = require('BankTransfer')

-- Baca input
local cardNumber = io.read()
local accountId = io.read()
local amount = tonumber(io.read())

-- TODO: Buat fungsi handlePayment yang menerima object pembayaran apa pun
-- dan jumlah, lalu memanggil :process(amount) pada object tersebut


-- TODO: Buat instance CreditCard dan BankTransfer menggunakan input


-- TODO: Gunakan handlePayment untuk memproses jumlah melalui kedua method pembayaran
-- Pertama kartu kredit, lalu transfer bank
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler Lua online