Người truy cập nhiều hơn các lĩnh vực. Những người khác đã chỉ ra một số khác biệt quan trọng và tôi sẽ thêm một điểm nữa.
Các thuộc tính tham gia vào các lớp giao diện. Ví dụ:
interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
Giao diện này có thể được thỏa mãn theo nhiều cách. Ví dụ:
class Person: IPerson
{
private string _name;
public string FirstName
{
get
{
return _name ?? string.Empty;
}
set
{
if (value == null)
throw new System.ArgumentNullException("value");
_name = value;
}
}
...
}
Trong triển khai này, chúng tôi đang bảo vệ cả Person
lớp khỏi trạng thái không hợp lệ, cũng như người gọi không nhận được null từ thuộc tính chưa gán.
Nhưng chúng tôi có thể đẩy thiết kế hơn nữa. Ví dụ, giao diện có thể không đối phó với setter. Hoàn toàn hợp pháp khi nói rằng người tiêu dùng IPerson
giao diện chỉ quan tâm đến việc có được tài sản, không phải trong việc thiết lập nó:
interface IPerson
{
string FirstName { get; }
string LastName { get; }
}
Việc thực hiện trước đó của Person
lớp thỏa mãn giao diện này. Việc nó cho phép người gọi cũng thiết lập các thuộc tính là vô nghĩa theo quan điểm của người tiêu dùng (người tiêu dùng IPerson
). Chức năng bổ sung của việc triển khai cụ thể được xem xét bởi, ví dụ, người xây dựng:
class PersonBuilder: IPersonBuilder
{
IPerson BuildPerson(IContext context)
{
Person person = new Person();
person.FirstName = context.GetFirstName();
person.LastName = context.GetLastName();
return person;
}
}
...
void Consumer(IPersonBuilder builder, IContext context)
{
IPerson person = builder.BuildPerson(context);
Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}
Trong mã này, người tiêu dùng không biết về setters tài sản - không phải là việc của anh ta để biết về nó. Người tiêu dùng chỉ cần getters, và anh ta nhận được getters từ giao diện, tức là từ hợp đồng.
Một triển khai hoàn toàn hợp lệ khác IPerson
sẽ là một lớp người bất biến và một nhà máy người tương ứng:
class Person: IPerson
{
public Person(string firstName, string lastName)
{
if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName))
throw new System.ArgumentException();
this.FirstName = firstName;
this.LastName = lastName;
}
public string FirstName { get; private set; }
public string LastName { get; private set; }
}
...
class PersonFactory: IPersonFactory
{
public IPerson CreatePerson(string firstName, string lastName)
{
return new Person(firstName, lastName);
}
}
...
void Consumer(IPersonFactory factory)
{
IPerson person = factory.CreatePerson("John", "Doe");
Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}
Trong mã này, người tiêu dùng mẫu một lần nữa không có kiến thức về việc điền các thuộc tính. Người tiêu dùng chỉ giao dịch với getters và triển khai cụ thể (và logic kinh doanh đằng sau nó, như thử nghiệm nếu tên trống) được để lại cho các lớp chuyên biệt - nhà xây dựng và nhà máy. Tất cả các hoạt động này là hoàn toàn không thể với các lĩnh vực.