Object-Oriented Programming (OOP) adalah paradigma pemrograman yang mengorganisir kode ke dalam bentuk "objek" — entitas yang memiliki data (atribut/properti) dan perilaku (method/fungsi). Berbeda dari pemrograman prosedural yang berfokus pada urutan eksekusi fungsi, OOP berfokus pada modeling dunia nyata ke dalam kode.
Dalam konteks Internet of Things (IoT), OOP menjadi sangat powerful karena sistem IoT secara alami terdiri dari entitas-entitas yang bisa dimodelkan sebagai objek: sensor, aktuator, perangkat, gateway, pesan, dan lainnya. Setiap entitas ini memiliki data tersendiri dan perilaku tersendiri — persis seperti konsep objek dalam OOP.
Empat Pilar OOP
Pilar
Penjelasan Singkat
Contoh di IoT
Inheritance
Kelas anak mewarisi atribut & method dari kelas induk
SensorSuhu mewarisi dari kelas Sensor
Polymorphism
Method yang sama bisa berperilaku berbeda di tiap kelas
Metode baca() berbeda untuk sensor suhu vs sensor gas
Encapsulation
Menyembunyikan detail internal, hanya ekspos interface publik
Method kalibrasi sensor disembunyikan, hanya get_data() yang publik
Abstraction
Menyederhanakan kompleksitas dengan abstraksi tingkat tinggi
Kelas abstrak Device tanpa detail spesifik hardware
OOP vs Pemrograman Prosedural
Diagram: Perbandingan Paradigma
PROSEDURAL OOP
def baca_suhu(): class Sensor:
def baca_kelembaban(): def baca(self):
def kirim_mqtt(): def kirim(self):
def cek_threshold(): def cek_threshold(self):
data = baca_suhu() sensor = SensorSuhu(pin=4)
if data > 30: data = sensor.baca()
kirim_mqtt("panas") if data > 30:
sensor.kirim("panas")
Fokus: urutan fungsi Fokus: objek & interaksi
💡 Tips
Python secara teknis mendukung multi-paradigma — Anda bisa menulis kode prosedural, OOP, atau bahkan fungsional dalam satu file. Namun untuk proyek IoT yang berkembang, OOP akan menghemat banyak waktu karena kode lebih terstruktur dan mudah di-maintain.
2. Classes & Objects
Class adalah blueprint (cetakan) untuk membuat objek. Ibarat arsitektur rumah — satu desain bisa menghasilkan banyak rumah. Sedangkan object adalah instance (kejadian) nyata dari class tersebut — rumah yang sudah dibangun dari desain tadi.
2.1 — Membuat Class Pertama
8. Design Patterns untuk IoT
Design patterns adalah solusi template untuk masalah desain yang umum. Dalam pengembangan sistem IoT, beberapa pattern sangat membantu untuk membuat kode yang bersih dan scalable.
8.1 — Singleton Pattern
Memastikan hanya ada satu instance dari sebuah class — cocok untuk MQTT client, database connection, atau konfigurasi global.
Python — singleton.py
"""
Singleton Pattern untuk MQTT Manager
BeebaneLabs - https://beebanelabs.pages.dev
"""
class MQTTManager:
"""Singleton — hanya satu instance yang boleh ada."""
_instance = None
_initialized = False
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, broker="localhost", port=1883):
if MQTTManager._initialized:
return
self.broker = broker
self.port = port
self._connected = False
self._subscribers = {}
MQTTManager._initialized = True
print(f"[MQTT] Manager dibuat — broker: {broker}:{port}")
def connect(self):
self._connected = True
print(f"[MQTT] Terhubung ke {self.broker}:{self.port}")
def subscribe(self, topic, callback):
self._subscribers[topic] = callback
print(f"[MQTT] Subscribe: {topic}")
# Semua variabel ini menunjuk ke INSTANCE YANG SAMA
mqtt1 = MQTTManager("192.168.1.10", 1883)
mqtt2 = MQTTManager("broker-lain.com", 8883) # Parameter diabaikan!
print(f"mqtt1 is mqtt2: {mqtt1 is mqtt2}") # True
print(f"Broker: {mqtt2.broker}") # 192.168.1.10 (tetap dari inisialisasi pertama)
8.2 — Observer Pattern
Membangun sistem event-driven di mana perubahan pada satu komponen (sensor) secara otomatis memberitahu komponen lain (aktuator, logger, notifikasi).
Python — observer.py
"""
Observer Pattern untuk Event-Driven IoT
BeebaneLabs - https://beebanelabs.pages.dev
"""
class EventEmitter:
"""Base class untuk event system."""
def __init__(self):
self._listeners = {}
def on(self, event_name, callback):
"""Mendaftarkan listener untuk event tertentu."""
if event_name not in self._listeners:
self._listeners[event_name] = []
self._listeners[event_name].append(callback)
def emit(self, event_name, data=None):
"""Memancarkan event ke semua listener."""
if event_name in self._listeners:
for callback in self._listeners[event_name]:
callback(data)
class SensorMonitor(EventEmitter):
"""Sensor yang memancarkan event saat threshold terlampaui."""
def __init__(self, nama, threshold_high=None, threshold_low=None):
super().__init__()
self.nama = nama
self.threshold_high = threshold_high
self.threshold_low = threshold_low
self._nilai_terakhir = None
def update(self, nilai):
self._nilai_terakhir = nilai
if self.threshold_high and nilai > self.threshold_high:
self.emit("threshold_high", {
"sensor": self.nama,
"nilai": nilai,
"threshold": self.threshold_high
})
if self.threshold_low and nilai < self.threshold_low:
self.emit("threshold_low", {
"sensor": self.nama,
"nilai": nilai,
"threshold": self.threshold_low
})
self.emit("data_update", {"sensor": self.nama, "nilai": nilai})
# --- Penggunaan ---
monitor_suhu = SensorMonitor("Suhu", threshold_high=35, threshold_low=15)
monitor_gas = SensorMonitor("Gas MQ-135", threshold_high=1000)
# Daftarkan listener
def alert_handler(data):
print(f"🚨 ALERT: {data['sensor']} = {data['nilai']} (threshold: {data['threshold']})")
def log_handler(data):
print(f"📝 LOG: {data['sensor']} → {data['nilai']}")
def dashboard_handler(data):
print(f"📊 DASHBOARD: Update {data['sensor']}: {data['nilai']}")
monitor_suhu.on("threshold_high", alert_handler)
monitor_suhu.on("threshold_low", alert_handler)
monitor_suhu.on("data_update", log_handler)
monitor_suhu.on("data_update", dashboard_handler)
monitor_gas.on("threshold_high", alert_handler)
# Simulasi update
monitor_suhu.update(28) # Normal
monitor_suhu.update(36.5) # Threshold high triggered!
monitor_suhu.update(12) # Threshold low triggered!
monitor_gas.update(1500) # Gas bahaya!
Output:
📝 LOG: Suhu → 28
📊 DASHBOARD: Update Suhu: 28
🚨 ALERT: Suhu = 36.5 (threshold: 35)
📝 LOG: Suhu → 36.5
📊 DASHBOARD: Update Suhu: 36.5
🚨 ALERT: Suhu = 12 (threshold: 15)
📝 LOG: Suhu → 12
📊 DASHBOARD: Update Suhu: 12
🚨 ALERT: Gas MQ-135 = 1500 (threshold: 1000)
8.3 — Factory Pattern
Membuat object tanpa perlu tahu class spesifiknya — cocok untuk membuat sensor berdasarkan konfigurasi file.
Python — factory.py
"""
Factory Pattern untuk Membuat Sensor dari Config
BeebaneLabs - https://beebanelabs.pages.dev
"""
import json
class SensorFactory:
"""Factory untuk membuat object sensor dari konfigurasi."""
_registry = {}
@classmethod
def register(cls, tipe, class_ref):
"""Mendaftarkan tipe sensor ke factory."""
cls._registry[tipe] = class_ref
@classmethod
def buat(cls, config):
"""Membuat sensor dari dict konfigurasi."""
tipe = config.get("tipe")
if tipe not in cls._registry:
raise ValueError(f"Tipe sensor tidak dikenal: {tipe}")
sensor_class = cls._registry[tipe]
return sensor_class(**{k: v for k, v in config.items() if k != "tipe"})
@classmethod
def buat_dari_file(cls, filepath):
"""Membuat semua sensor dari file JSON config."""
with open(filepath, "r") as f:
configs = json.load(f)
sensors = []
for cfg in configs:
sensor = cls.buat(cfg)
sensors.append(sensor)
return sensors
# Register semua tipe sensor
# SensorFactory.register("dht22", SensorDHT)
# SensorFactory.register("ultrasonik", SensorUltrasonik)
# SensorFactory.register("ldr", SensorLDR)
# Contoh config JSON:
# [
# {"tipe": "dht22", "nama": "Suhu Ruang", "pin": 4},
# {"tipe": "ultrasonik", "nama": "Jarak Tangki", "pin_trigger": 17, "pin_echo": 27},
# {"tipe": "ldr", "nama": "Cahaya Taman", "pin": 22}
# ]
📋 Ringkasan Design Patterns
Pattern
Kegunaan di IoT
Singleton
MQTT client, database connection, config manager — hanya satu instance
Observer
Event-driven notifications — sensor threshold, alert system
Factory
Membuat sensor/aktuator dari konfigurasi — fleksibel dan scalable
Strategy
Ganti algoritma (filter data, format payload) secara dinamis
State
Menangani state perangkat (idle, running, error, sleep)
9. Quiz: Uji Pemahamanmu!
Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang OOP dalam Python untuk IoT:
Pertanyaan 1: Apa yang dimaksud dengan "self" dalam method class Python?
a) Nama class itu sendiri
b) Referensi ke instance/object yang sedang memanggil method
c) Variabel global yang bisa diakses semua class
d) Pointer ke class induk (parent)
Pertanyaan 2: Apa fungsi dari super().__init__() dalam inheritance?
a) Membuat instance baru dari class anak
b) Memanggil constructor dari class induk
c) Menghapus class induk dari memori
d) Membuat class abstrak baru
Pertanyaan 3: Dalam encapsulation, apa arti double underscore (__) sebelum nama atribut?
a) Atribut menjadi public
b) Atribut menjadi class variable
c) Atribut menjadi private (name mangling)
d) Atribut menjadi deprecated
Pertanyaan 4: Design pattern apa yang memastikan hanya ada SATU instance dari sebuah class?
a) Observer Pattern
b) Factory Pattern
c) Singleton Pattern
d) Strategy Pattern
Pertanyaan 5: Apa yang terjadi jika kita mencoba membuat instance dari class abstrak yang masih memiliki method @abstractmethod?
a) Object berhasil dibuat dengan method kosong
b) Python akan mengabaikan @abstractmethod
c) TypeError: Can't instantiate abstract class
d) Object terbuat tapi semua method mengembalikan None