1. Issue
Cho đoạn code sau:
public class Charge {
private int units;
private double rate;
public Charge(int units, double rate) {
this.units = units;
this.rate = rate;
}
public int getUnits() {
return units;
}
public void setUnits(int units) {
this.units = units;
}
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
public Money getAmount() {
return Money.usd(units * rate);
}
}
Bạn có thể thấy, tất cả các fields đều được đánh dấu là private modifier với getter/setter đấy đủ, tuy nhiên ở phần dưới method getAmount()
đã phá vỡ nguyên tắc Encapsulation
trong lập trình hướng đối tượng bằng việc truy cập trực tiếp vào các fields. Hơn nữa việc hard-code như thế này làm cho method thiếu đi sự linh hoạt cần thiết trong trường hợp chúng ta muốn override method getAmount()
, lazy initialization hay validation.
2. Solution
Mình sẽ thay đổi đoạn code trên một chút ở method getAmount()
:
public Money getAmount() {
return Money.usd(this.getUnits() * this.getRate());
}
Mọi thứ đã trở nên dễ dàng hơn ngay cả với việc mở rộng class:
static class CustomCharge extends Charge {
public CustomCharge(int units, double rate) {
super(units, rate);
}
@Override
public int getUnits() {
return super.getUnits() * 2;
}
}
3. Final Thought
Không phải bao giờ việc self-encapsulation field cũng cần thiết ngoài trừ phần lớn những trường hợp sau:
- Inheritance
- Lazy initialization
- Validation
Cảm ơn mọi người đã đọc bài. Happy Coding! 😆😆