Tôi 'khám phá' giao diện và tôi bắt đầu yêu thích chúng. Vẻ đẹp của giao diện là nó là một hợp đồng và bất kỳ đối tượng nào đáp ứng hợp đồng đó đều có thể được sử dụng ở bất cứ nơi nào có giao diện đó được yêu cầu.
Vấn đề với giao diện là nó không thể có cài đặt mặc định, điều này gây khó khăn cho các thuộc tính trần tục và đánh bại DRY. Điều này cũng tốt, bởi vì nó giữ cho việc thực hiện và hệ thống tách rời. Kế thừa, trên tay, duy trì một khớp nối chặt chẽ hơn, và có khả năng phá vỡ đóng gói.
Trường hợp 1 (Kế thừa với các thành viên tư nhân, đóng gói tốt, kết hợp chặt chẽ)
class Employee
{
int money_earned;
string name;
public:
void do_work(){money_earned++;};
string get_name(return name;);
};
class Nurse : public Employee:
{
public:
void do_work(/*do work. Oops, can't update money_earned. Unaware I have to call superclass' do_work()*/);
};
void HireNurse(Nurse *n)
{
nurse->do_work();
)
Trường hợp 2 (chỉ là một giao diện)
class IEmployee
{
virtual void do_work()=0;
virtual string get_name()=0;
};
//class Nurse implements IEmployee.
//But now, for each employee, must repeat the get_name() implementation,
//and add a name member string, which breaks DRY.
Trường hợp 3: (tốt nhất của cả hai thế giới?)
Tương tự như trường hợp 1 . Tuy nhiên, hãy tưởng tượng rằng (giả thiết) C ++ không cho phép ghi đè các phương thức ngoại trừ các phương thức đó là thuần ảo .
Vì vậy, trong trường hợp 1 , ghi đè do_work () sẽ gây ra lỗi thời gian biên dịch. Để khắc phục điều này, chúng tôi đặt do_work () là ảo thuần túy và thêm một phương thức riêng tăng dần_money_earned (). Ví dụ:
class Employee
{
int money_earned;
string name;
public:
virtual void do_work()=0;
void increment_money_earned(money_earned++;);
string get_name(return name;);
};
class Nurse : public Employee:
{
public:
void do_work(/*do work*/ increment_money_earned(); ); .
};
Nhưng ngay cả điều này có vấn đề. Điều gì sẽ xảy ra nếu 3 tháng kể từ bây giờ, Joe Coder tạo ra một Nhân viên Bác sĩ, nhưng anh ta quên gọi tăng_money_earned () trong do_work ()?
Câu hỏi:
Là Trường hợp 3 vượt trội so với Trường hợp 1 ? Có phải vì nó là 'đóng gói tốt hơn' hay 'kết nối lỏng lẻo hơn', hay một số lý do khác?
Là Trường hợp 3 vượt trội so với Trường hợp 2 vì nó phù hợp với DRY?