我想問一個關於如何處理簡單的面向對象設計問題的問題。我有一些關於解決這種情況的最佳方法,但我希望聽到Stack Overflow社區的一些意見。有關網上文章的鏈接也表示讚賞。我使用C#,但問題不是語言特定的。面向對象的最佳實踐 - 繼承v組合v接口
假設我寫一個視頻商店應用程序,其數據庫中有一個Person
表,與PersonId
,Name
,DateOfBirth
和Address
領域。它還有一個Staff
表,其中有一個鏈接到PersonId
,和一個Customer
表也鏈接到PersonId
。
一個簡單的面向對象的方法是說,一個Customer
「是」 Person
,因此創建類有點像這樣:
class Person {
public int PersonId { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public string Address { get; set; }
}
class Customer : Person {
public int CustomerId { get; set; }
public DateTime JoinedDate { get; set; }
}
class Staff : Person {
public int StaffId { get; set; }
public string JobTitle { get; set; }
}
現在我們可以寫一個函數說,發送電子郵件給所有客戶:
static void SendEmailToCustomers(IEnumerable<Person> everyone) {
foreach(Person p in everyone)
if(p is Customer)
SendEmail(p);
}
該系統工作正常,直到我們有一個既是客戶又是員工的成員。假設我們真的不希望我們的everyone
列表,以便在同一個人兩次,一次作爲Customer
一次作爲Staff
,我們之間做出任意選擇:
class StaffCustomer : Customer { ...
和
class StaffCustomer : Staff { ...
顯然只有這兩個中的第一個不會破壞SendEmailToCustomers
功能。
那麼你會怎麼做?
- 充分利用
Person
類有一個StaffDetails
和CustomerDetails
類可選的參考? - 創建一個新類,其中包含一個
Person
,加上可選的StaffDetails
和CustomerDetails
? - 使所有的接口(例如
IPerson
,IStaff
,ICustomer
)並創建三個類來實現適當的接口? - 採取另一種完全不同的方法?
是的,你現在可以選擇一個實現,稍後改變你的想法,而不會破壞其他代碼。 – 2008-10-19 15:33:14