我想问一个关于如何处理简单的面向对象设计问题的问题。我有一些关于解决这种情况的最佳方法,但我希望听到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