Pengakses lebih dari bidang. Yang lain sudah menunjukkan beberapa perbedaan penting, dan saya akan menambahkan satu lagi.
Properti ambil bagian dalam kelas antarmuka. Sebagai contoh:
interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
Antarmuka ini dapat dipenuhi dengan beberapa cara. Sebagai contoh:
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;
}
}
...
}
Dalam implementasi ini kami melindungi kedua Person
kelas agar tidak masuk ke keadaan tidak valid, serta penelepon agar tidak keluar dari properti yang belum ditetapkan.
Tapi kami bisa mendorong desain lebih jauh. Misalnya, antarmuka mungkin tidak berurusan dengan setter. Sangat sah untuk mengatakan bahwa konsumen IPerson
antarmuka hanya tertarik untuk mendapatkan properti, bukan dalam pengaturannya:
interface IPerson
{
string FirstName { get; }
string LastName { get; }
}
Implementasi Person
kelas sebelumnya memenuhi antarmuka ini. Fakta bahwa itu memungkinkan penelepon juga mengatur properti tidak ada artinya dari sudut pandang konsumen (yang mengkonsumsi IPerson
). Fungsionalitas tambahan dari implementasi konkret dipertimbangkan oleh, misalnya, pembangun:
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);
}
Dalam kode ini, konsumen tidak tahu tentang setter properti - bukan urusannya untuk mengetahuinya. Konsumen hanya membutuhkan getter, dan ia mendapatkan getter dari antarmuka, yaitu dari kontrak.
Implementasi lain yang benar-benar valid IPerson
adalah kelas orang yang tidak dapat diubah dan pabrik orang yang sesuai:
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);
}
Dalam contoh kode ini, konsumen sekali lagi tidak memiliki pengetahuan untuk mengisi properti. Konsumen hanya berurusan dengan getter dan implementasi konkret (dan logika bisnis di belakangnya, seperti pengujian jika nama kosong) diserahkan kepada kelas khusus - pembangun dan pabrik. Semua operasi ini sama sekali tidak mungkin dengan bidang.