btw
https://t.me/dotnetcore_id/34404
dapet insight dari ini
biasanya nama file nya sama kaya yang pak ronny tulis, tapi pake nya factory
dan tetep pake kondisi buat misah2 nya wkwkkw
waduh
bad oop practice ya wkwkw
OOP itu ibarat gini
tanpa OOP:
si A ngirim paket. paketnya ditulis alamat si B. kurir kirim ke alamat si B. B ngerasa dia expecting paketnya, B terima paket. kalau ternyata A salah alamat kekirim ke alamat si C, si C reject paketnya
dengan OOP:
si A ngirim paket, alamatnya diverifikasi sistem dan diprint. ngga mungkin salah. kurir nganter ke alamat si B. B terima aja ngga perlu cek ulang karena udah pasti alamatnya bener.
kalau misal alamatnya salah, ngga bakal keprint
jadi tanpa OOP, kita coding pakai pengecekan, validasi, dan conditional
dengan OOP, kita coding dengan jaminan
yang satu dicek, yang satu dijamin
misal di C#
class Hero {
public int MaxHP { get; private set; }
public int HP { get; private set; }
public Hero(int hp, int maxHP) {
if (hp < 0) throw ....
if (maxHP <= 0) throw ....
if (hp > maxHP) throw ....
HP = hp;
MaxHP = maxHP;
}
public void Heal(int healAmount) {
if (healAmount < 0) throw ....
if (HP + healAmount > MaxHP) {
HP = MaxHP;
} else {
HP += healAmount;
}
}
}
di class ini dijamin HP ngga bisa melebihi MaxHP. karena ngga ada satu pun cara untuk bikin HP di atas MaxHP
udah dicegah di semua tempat: di constructor ada validasi, setter private ngga bisa diakses dari luar, dan satu2nya method yaitu Heal ngga bisa menghasilkan invalid state
jadi ketika ada instance dari class Hero
ini diterima sebagai parameter, fungsi yang terima ngga perlu ngecek lagi apa yang sudah dijamin oleh class ini
Sulit oop pake golang
Ya karena ga OOP language kan
salah satu spaghetti code itu biasanya di ordering system
if (order.Status === "Paid" && order.PaidAt !== null && !order.Canceled && order.PaidAmount === order.Total dst dst)
conditionnya panjaaaang bener
dan diulang2 di mana2
ada perubahan dikit, the system breaks
nah di situlah inheritance dipake
misal ordering system alurnya gini:
NewOrder:
kalau kita pake cara barbar, modelnya:
struct Order {
public Status Status;
public DateTime Ordered;
public DateTime? Confirmed;
public DateTime? Completed;
public void Confirm() { ... }
public void Complete() { ... }
}
dari sini udah kebayang bakal jadi if
statement mess kan
kalau kita pakai polymorphism, jadinya:
abstract record OrderBase();
record NewOrder(
DateTime Ordered
) : OrderBase {
ConfirmedOrder Confirm(DateTime confirmed) =>
new ConfirmedOrder(Ordered, confirmed);
}
record ConfirmedOrder(
DateTime Ordered,
DateTime Confirmed
) : OrderBase {
CompletedOrder Complete(DateTime completed) =>
new CompletedOrder(Ordered, Confirmed, completed);
}
record CompletedOrder(
DateTime Ordered,
DateTime Confirmed,
DateTime Completed
) : OrderBase();
ini saya singkat aja pake minimal safety. karena kalau pake full safety codenya panjang
perbedaannya dengan code sebelumnya:
Status
, kita bedakan order dari typenyaDi golang kan struct driven, cuma bisa dititipin receiver
golang bisa OOP
pakai some library yang namanya golangci-lint untuk apply some clever rules
Di EFcore afaik ga ada tabel per type, jadi kalo dijadiin ef object, jadiny 1 tabel besar
you can apply mandatory constructor, immutable pattern, encapsulation, etc
yes
Wait what? Mandatory constructor bisa? Menarik
ini OOP di domain modelnya. bukan persistence
Pin
bisa. cukup bikin aja linter rule yang cuma bolehkan struct dicreate di file yang sama dengan deklarasinya
Hal kayak gini bsa diatasi dengan domain model dan persistemt model kan?
Ya di kantor diajakin pake dotnet👀👀👀
👀 👀 👀
👀
Ya kan tadi saya bilang juga kalo dijadiin entity
Nanti lah kalo engineers ny sampe ribuan