Prinsip SOLID ing Laravel: conto lengkap
SOLID minangka sakumpulan prinsip kanggo pangembangan piranti lunak berorientasi obyek.
Prinsip kasebut mbantu njamin piranti lunak bisa dijaga, bisa digunakake maneh, lan bisa ditambah.
Ing artikel iki kita bakal nliti luwih jero babagan aplikasi prinsip SOLID ing Laravel
Perkiraan wektu maca: 5 menit
Prinsip SOLID lagi:
- Prinsip Tanggung Jawab Tunggal (SRP)
- Prinsip Open-closed (OCP)
- Prinsip Substitusi Liskov (LSP)
- Prinsip Segregasi Antarmuka (ISP)
- Prinsip Pembalikan Ketergantungan (DIP)
Cara ngetrapake prinsip SOLID ing Laravel
- Prinsip Tanggung Jawab Tunggal (SRP) Prinsip iki nyatakake yen kelas kudu mung siji alasan kanggo ngganti. Ing tembung liyane, kelas kudu mung siji tanggung jawab.
- Conto: Coba kelas sing diarani
Order
. Tinimbang duwe kabeh fungsi related kanggo urutan ing siji kelas, kita bisa break menyang kelas cilik kayaOrderCalculator
,OrderRepository
, eOrderMailer
.
- Conto: Coba kelas sing diarani
- Mbukak-Tutup Prinsip (OCP) Prinsip iki nyatakake yen kelas kudu mbukak kanggo ekstensi nanging ditutup kanggo modifikasi. Ing tembung liyane, kita kudu bisa nambah fitur anyar tanpa ngganti kode sing wis ana.
- Conto: Coba kelas sing diarani
PaymentGateway
. Tinimbang ngowahi kelas iki saben-saben kita nambah cara pembayaran anyar, kita bisa nggawe kelas anyar kanggo saben cara pembayaran sing ngluwihiPaymentGateway
kelas.
- Conto: Coba kelas sing diarani
- Prinsip substitusi saka Liskov (LSP): asas iki netepake sing obyek saka superclass kudu bisa diganti karo obyek saka subclass tanpa compromising bener saka program.
- Conto: Coba kelas sing diarani
Shape
karo subkelasCircle
,Rectangle
, eSquare
. Yen kita duwe fungsi sing nampa obyek saka jinisShape
, kita kudu bisa ngliwati obyek saka jinisCircle
,Rectangle
utawaSquare
tanpa mengaruhi prilaku fungsi.
- Conto: Coba kelas sing diarani
- Prinsip Segregasi Antarmuka (ISP): asas iki nyatakake yen klien ora kudu dipeksa gumantung ing cara sing ora digunakake.
- Conto: Coba antarmuka sing diarani
PaymentMethod
karo metode kayapay
,refund
, egetTransactions
. Tinimbang duwe kabeh cara iki ing antarmuka siji, kita bisa nggawe antarmuka kapisah kanggo saben cara lan kelas ngleksanakake mung antarmuka sing perlu.
- Conto: Coba antarmuka sing diarani
Principio di inversione delle dipendenze
(DIP) : Prinsip iki nyatakake yen modul tingkat dhuwur ora kudu gumantung marang modul tingkat rendah. Loro-lorone kudu gumantung ing abstraksi.- Conto: Coba kelas sing diarani
Order
kang gumantung ing kelas disebutOrderRepository
. Tinimbang instantiating langsungOrderRepository
inOrder
, kita bisa nggunakake injeksi katergantungan kanggo inject conto sakaOrderRepository
inOrder
.
- Conto: Coba kelas sing diarani
Wuku
Kanthi netepi prinsip kasebut SOLID in Laravel, kita bisa nulis kode resik, maintainable, lan extensible.
Kanggo luwih nggambarake carane entuk prinsip SOLID ing Laravel, ayo goleki conto praktis.
Upaminipun kita duwe aplikasi sing ngidini pangguna kanggo nggawe pesenan produk. Kita pengin ngleksanakake fungsi kanggo ngetung rega total pesenan lan ngirim email menyang customer karo rincian pesenan. Kita bisa entuk iki kanthi ngetutake prinsip SOLID.
Prinsip Tanggung Jawab Tunggal (SRP)
Kanggo tindakake SRP, kita bisa nggawe kelas kapisah kanggo ngetung total rega pesenan lan ngirim email kanggo customer. Contone:
class OrderCalculator
{
public function calculateTotal(Order $order): float
{
// Calculate total price of order
}
}
class OrderMailer
{
public function sendEmail(Order $order, User $user)
{
// Send email to customer with order details
}
}
Prinsip Open-closed (OCP)
Kanggo tindakake OCP, kita bisa nggunakake wadhah layanan lan injeksi katergantungan saka Laravel kanggo nggawe sistem fleksibel sing ngidini kita nambah fitur anyar tanpa ngganti kode sing wis ana. Tuladhane:
interface PaymentGateway
{
public function pay(Order $order): bool;
}
class PayPalGateway implements PaymentGateway
{
public function pay(Order $order): bool
{
// Process payment using PayPal API
}
}
class StripeGateway implements PaymentGateway
{
public function pay(Order $order): bool
{
// Process payment using Stripe API
}
}
class OrderProcessor
{
private PaymentGateway $gateway;
public function __construct(PaymentGateway $gateway)
{
$this->gateway = $gateway;
}
public function process(Order $order): void
{
// Process order using PaymentGateway
}
}
// In application service provider
$this->app->bind(PaymentGateway::class, StripeGateway::class);
Kene, kita digawe PaymentGateway
antarmuka lan loro implementasine kanggo PayPal lan Stripe. Dadi ayo nggawe kelas OrderProcessor
kang njupuk conto PaymentGateway
liwat pabrikane. Ing panyedhiya layanan aplikasi, kita ngiket antarmuka PaymentGateway
kanggo implementasine StripeGateway
, nanging kita bisa gampang ngowahi kanggo nggunakake implementasine PayPalGateway
se kabutuhan.
Prinsip Substitusi Liskov (LSP)
Kanggo tindakake LSP, katelu saka prinsip padhet, kita kudu mesthekake yen sembarang subclass saka superclass bisa digunakake ing panggonan superclass tanpa mengaruhi prilaku program. Ing conto kita, kita bisa nggawe manawa iki kanthi nggunakake pitunjuk jinis lan antarmuka. Contone:
interface OrderRepository
{
public function save(Order $order): void;
}
class DatabaseOrderRepository implements OrderRepository
{
public function save(Order $order): void
{
// Save order to database
}
}
class InMemoryOrderRepository implements OrderRepository
{
public function save(Order $order): void
{
// Save order to in-memory cache
}
}
class OrderService
{
private OrderRepository $repository;
public function __construct(OrderRepository $repository)
{
$this->repository = $repository;
}
public function placeOrder(Order $order): void
{
// Place order and save to repository
}
}
// In application service provider
$this->app->bind(OrderRepository::class, DatabaseOrderRepository::class);
Ing kene, kita wis nggawe antarmuka OrderRepository
lan loro implementasine kanggo database lan cache ing memori. Dadi ayo nggawe kelas OrderService
sing nampa aplikasi OrderRepository
liwat pabrikane. Ing panyedhiya layanan aplikasi, kita ngiket antarmuka OrderRepository
kanggo implementasine DatabaseOrderRepository
, nanging kita bisa gampang ngowahi kanggo nggunakake implementasine InMemoryOrderRepository
yen perlu, tanpa mengaruhi prilaku program.
Prinsip Segregasi Antarmuka (ISP)
Kanggo ngetutakeISP, kaping papat saka prinsip padhet, kita ora kudu meksa klien gumantung ing antarmuka sing ora digunakake. Ing conto kita, kita bisa njamin iki dening nggawe cilik, antarmuka luwih fokus tinimbang gedhe, antarmuka monolitik. Contone:
interface OrderTotalCalculator
{
public function calculateTotal(Order $order): float;
}
interface OrderEmailSender
{
public function sendEmail(Order $order, User $user);
}
class OrderProcessor
{
private OrderTotalCalculator $calculator;
private OrderEmailSender $mailer;
public function __construct(OrderTotalCalculator $calculator, OrderEmailSender $mailer)
{
$this->calculator = $calculator;
$this->mailer = $mailer;
}
public function process(Order $order, User $user): void
{
$total = $this->calculator->calculateTotal($order);
$this->mailer->sendEmail($order, $user);
// Process order using total and mailer
}
}
Ing kene, kita wis nggawe rong antarmuka sing luwih cilik kanggo ngitung rega total pesenan lan ngirim email. Dadi ayo ngowahi kelas OrderProcessor
kanggo njupuk conto saka antarmuka iki tinimbang siji, antarmuka gedhe. Iki ngidini klien mung gumantung ing antarmuka sing dibutuhake, tinimbang dipeksa gumantung ing siji antarmuka monolitik sing gedhe.
Prinsip Pembalikan Ketergantungan (DIP)
Kanggo ngetutake DIP, kita kudu ngandelake abstraksi tinimbang implementasi konkrit. Ing conto kita, kita bisa entuk iki kanthi nggunakake injeksi dependensi lan antarmuka ing saindhenging kode kita. Tuladhane:
interface PaymentGateway
{
public function pay(Order $order): bool;
}
interface OrderRepository
{
public function save(Order $order): void;
}
interface OrderTotalCalculator
{
public function calculateTotal(Order $order): float;
}
interface OrderEmailSender
{
public function sendEmail(Order $order, User $user);
}
class OrderProcessor
{
private PaymentGateway $gateway;
private OrderRepository $repository;
private OrderTotalCalculator $calculator;
private OrderEmailSender $mailer;
public function __construct(
PaymentGateway $gateway,
OrderRepository $repository,
OrderTotalCalculator $calculator,
OrderEmailSender $mailer
) {
$this->gateway = $gateway;
$this->repository = $repository;
$this->calculator = $calculator;
$this->mailer = $mailer;
}
public function process(Order $order, User $user): void
{
$total = $this->calculator->calculateTotal($order);
$this->mailer->sendEmail($order, $user);
$this->gateway->pay($order);
$this->repository->save($order);
// Process order using gateway, repository, calculator, and mailer
}
}
Ing kene kita wis nggawe antarmuka kanggo kabeh dependensi lan ngowahi kelas kasebut OrderProcessor
kanggo njupuk conto antarmuka kasebut liwat konstruktor. Iki ngidini kita gampang ngganti implementasi nalika runtime lan ngidini kita gumantung ing abstraksi tinimbang implementasi konkrit.
Ringkesan, kita bisa entuk prinsip SOLID ing Laravel kanthi nggunakake injeksi ketergantungan, antarmuka, lan wadhah layanan Laravel kanggo nggawe sistem sing fleksibel lan bisa dijaga sing gampang diowahi lan dilanjutake.