5 nguyên tắc SOLID (phần 2)
SOLID là viết tắt của 5 chữ cái đầu trong 5 nguyên tắc lập trình hướng đối tượng:
- Single Responsibility Principle (SRP) - Nguyên tắc Trách nhiệm Duy nhất.
- Open/Closed Principle - Nguyên tắc Mở / Đóng.
- Liskov’s Substitution Principle (LSP) - Nguyên tắc thay thế Liskov.
- Interface Segregation Principle (ISP) - Nguyên tắc phân tách giao diện.
- Dependency Inversion Principle (DIP) - Nguyên tắc đảo ngược phụ thuộc.
Tiếp lối bài viết 5 nguyên tắc SOLID (phần 1) https://blog.haposoft.com/5-nguyen-tac-cua-solid-pha/ chúng ta đi tìm hiểu tiếp về 2 nguyên tắc cuối:
Interface Segregation Principle (ISP).
Theo tác giả Robert Martin
trong quyển The Interface Segregation Principle
thì nguyên tắc này được định nghĩa:
A client should never be forced to implement an interface that it doesn’t use, or clients shouldn’t be forced to depend on methods they do not use.
Ở đây có thể hiểu: một client
không bao giờ được implement một interface
mà client
đó không sử dụng, hoặc các client
không phải phụ thuộc và các method mà chúng không dùng.
Trong quyển Design Principles and Design Patterns
cũng của tác giả Robert C. Martin (Uncle Bob)
thì nguyên tắc này được phát biểu:
“Many client-specific interfaces are better than one general-purpose interface.”
Theo đó chúng ta có thể hiểu có nhiều các interface
riêng biệt thì tốt hơn là việc sử dụng một interface lớn dùng chung.
Ví dụ:
app/GardenInterface.php
namespace App;
{
public function grow($advanceNumberOfDays);
public function weed($pickOutPercentage);
...
}
class GardenFlower implements GardenInterface
{
public function grow($advanceNumberOfDays)
{
}
public function weed($pickOutPercentage)
{
}
}
class GardenAquaticFlowers implements GardenInterface
{
public function grow($advanceNumberOfDays)
{
}
public function weed($pickOutPercentage)
{
// không có logic vì hoa thủy sinh trồng trên nước nên không có cỏ dại
}
}
Trong ví dụ trên việc GardenFlower
sử dụng GardenInterface
tương đối hợp lý tuy nhiên GardenAquaticFlowers
sử dụng GardenInterface
thì thấy không còn ổn nữa. Việc một class bị phụ thuộc với method
mà chúng không sử dụng (weed
) thì khá tệ. Để giải quyết vấn đề này chúng ta lên tách nhỏ GardenInterface
thành những interface
nhỏ hơn.
app/GardenInterface.php
namespace App;
class GardenFlower implements GrowableInterface, WeedableInterface
{
public function grow($advanceNumberOfDays)
{
}
public function weed($pickOutPercentage)
{
}
}
class GardenAquaticFlowers implements GrowableInterface
{
public function grow($advanceNumberOfDays)
{
}
}
Dependency Inversion Principle (DIP).
Nguyên lý này được tác giả Martin, Robert C. (2000)
trong quyển Design Principles and Design Patterns
như sau:
One should depend upon abstractions. Do not depend upon concretions.
Ở đây chúng ta có thể hiểu một cách đơn giản các class
chỉ nên phụ thuộc vào các class
trừu tượng (abstract class
, interface
) mà không nên phụ thuộc vào các class
chứa logic.
Ví dụ:
class DailyReportRepository
{
public function findById($id)
{
}
}
class DailyReportService
{
protected $dailyReportRepository;
public function __construct(DailyReportRepository $DailyReportRepository)
{
$this->dailyReportRepository = $dailyReportRepository;
}
}
Ở trên đã vi phạm nguyên tắc D
trong solid
việc class DailyReportService
phụ thuộc trực tiếp lớp logic DailyReportRepository
sẽ khiến phần mềm của chúng ta khó mở rộng hay thay đổi. Cách để khắc phục điều này:
class DailyReportRepository implements DailyReportInterface
{
public function findById($id)
{
//my logic
}
}
interface DailyReportInterface
{
public function findById($id);
}
class DailyReportService
{
protected $dailyReportRepository;
public function __construct(DailyReportInterface $dailyReportInterface)
{
$this->dailyReportInterface = $dailyReportInterface;
}
}
Kết luận:
Trên đây là một số kiến thức cơ bản về solid
trong lập trình hướng đối tượng. Kiến thức mình có gì sai sót xin mọi người thoải mái góp ý để mình hoàn thiện bài viết. Cảm ơn đã đọc bài viết của mình !!!
Tài liệu tham khảo:
Martin, Robert C. (2000). "Design Principles and Design Patterns
Robert Martin, paper “The Interface Segregation Principle”
Design Patternsin PHP and Laravel — Kelt Dockins