खेतों की तुलना में एक्सेसर्स अधिक हैं। दूसरों ने पहले ही कई महत्वपूर्ण अंतर बताए हैं, और मैं एक और जोड़ने जा रहा हूं।
गुण इंटरफ़ेस कक्षाओं में भाग लेते हैं। उदाहरण के लिए:
interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
इस इंटरफ़ेस को कई तरीकों से संतुष्ट किया जा सकता है। उदाहरण के लिए:
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;
}
}
...
}
इस कार्यान्वयन में हम दोनों Person
वर्ग को एक अमान्य स्थिति में लाने से बचा रहे हैं, साथ ही फोन करने वाले को अप्रकाशित संपत्ति से बाहर निकलने से रोक रहे हैं।
लेकिन हम डिजाइन को और भी आगे बढ़ा सकते हैं। उदाहरण के लिए, इंटरफ़ेस सेटर के साथ व्यवहार नहीं कर सकता है। यह कहना काफी वैध है कि IPerson
इंटरफ़ेस के उपभोक्ता केवल संपत्ति प्राप्त करने में रुचि रखते हैं, इसे स्थापित करने में नहीं:
interface IPerson
{
string FirstName { get; }
string LastName { get; }
}
Person
वर्ग का पिछला कार्यान्वयन इस इंटरफ़ेस को संतुष्ट करता है। तथ्य यह है कि यह फोन करने वाले को भी सेट करने देता है गुण उपभोक्ताओं (जो उपभोग करते हैं IPerson
) के दृष्टिकोण से व्यर्थ है । कंक्रीट कार्यान्वयन की अतिरिक्त कार्यक्षमता को ध्यान में रखा जाता है, उदाहरण के लिए, बिल्डर:
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);
}
इस कोड में, उपभोक्ता संपत्ति बसने वालों के बारे में नहीं जानता है - इसके बारे में जानना उसका व्यवसाय नहीं है। उपभोक्ता को केवल गेटर्स की आवश्यकता होती है, और उसे इंटरफेस से, अनुबंध से प्राप्त होता है।
एक पूरी तरह से मान्य कार्यान्वयन IPerson
एक अपरिवर्तनीय व्यक्ति वर्ग और एक संबंधित व्यक्ति कारखाना होगा:
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);
}
इस कोड के नमूने में उपभोक्ता को एक बार फिर संपत्तियों को भरने का कोई ज्ञान नहीं है। उपभोक्ता केवल गेटर्स और कंक्रीट कार्यान्वयन (और इसके पीछे व्यावसायिक तर्क, जैसे कि नाम खाली है, तो परीक्षण) को विशेष वर्गों - बिल्डरों और कारखानों को छोड़ दिया जाता है। ये सभी ऑपरेशन खेतों के साथ पूरी तरह से असंभव हैं।