Hiểu về “O” – Open closed principle

Bây giờ chúng ta sẽ tiếp tục với class Customer ở ví dụ trước. Tôi sẽ thêm một property đơn giản vào lớp này. Property này sẽ chỉ ra kiểu “customer” sẽ là “Gold” hay “Silver”.

Sau đó với một vài tính toán đơn giản với hàm “GetDiscount” chúng ta sẽ tính toán discount cho khách hàng.

Cùng xem đoạn code sau:

class Customer
{
	private int _CustType;

	public int CustType
	{
		get { return _CustType; }
		set { _CustType = value; }
	}

	public double getDiscount(double TotalSales)
	{
		if (_CustType == 1)		
			return TotalSales - 100;
		else
			return TotalSales - 50;
	}
}

Xem nào, vấn đề ở đây là khi chúng ta muốn thêm một kiểu customer mới, chúng ta sẽ phải thêm 1 câu lệnh điều kiện if vào hàm “getDiscount”. Nói cách khác chúng ta cần thay đổi lớp customer.

Nếu chúng ta thay đổi lớp customer hết lần này đến lần khác, chúng ta cần chắc chắn rằng đoạn code của chúng ta phải được kiểm tra lại (tested again) để đảm bảo rằng chương trình sẽ vẫn hoạt động bình thường. Điều này thật rắc rối và mất công!!!

Vậy bất cứ khi nào bạn gặp vấn đề về “MODIFYING” thì hãy ngay lập tức nghĩ tới “EXTENSION”. Ở trường hợp cụ thể này, chúng ta có thể thêm 1 class mới như đoạn code dưới, để mỗi lần thay đổi, chúng ta chỉ việc kiểm tra lại class mới được thêm vào

class Customer
{
	public virtual double getDiscount(double TotalSales)
	{
		return TotalSales;
	}
}

class SilverCustomer : Customer
{
	public override double getDiscount(double TotalSales)
	{
		return base.getDiscount(TotalSales) - 50;
	}
}

class goldCustomer : SilverCustomer
{
	public override double getDiscount(double TotalSales)
	{
		return base.getDiscount(TotalSales) - 100;
	}
}

nguyen-ly-solid-trong-lap-trinh-huong-doi-tuong-va-vi-du-su-dung-c-p2

Lớp “Customer” bây giờ được hiểu là “Đóng” với mọi thay đổi, nhưng nó luôn “Mở” đối với việc mở rộng các thuộc tính hay phương thức của lớp “Customer”.

Đây chính là ý nghĩa của nguyên lý Open-Close. Luôn đóng với mọi thay đổi và luôn mở đối với việc mở rộng.
Software modules should be closed for modifications but open for extensions