मेरे लिए, जब शुरू करते हैं, तो इन पर बात तभी स्पष्ट हो जाती है जब आप उन्हें देखना बंद कर देते हैं क्योंकि आपका कोड लिखने के लिए आसान / तेज़ हो जाता है - यह उनका उद्देश्य नहीं है। उनके पास कई उपयोग हैं:
(यह पिज्जा सादृश्य खोने जा रहा है, क्योंकि इसके उपयोग की कल्पना करना बहुत आसान नहीं है)
कहें कि आप स्क्रीन पर एक सरल गेम बना रहे हैं और इसमें ऐसे जीव होंगे जिनके साथ आप बातचीत करते हैं।
ए: वे आपके सामने के अंत और आपके बैक एंड कार्यान्वयन के बीच एक ढीली युग्मन शुरू करके भविष्य में बनाए रखने के लिए आपके कोड को आसान बना सकते हैं।
आप इसे शुरू करने के लिए लिख सकते हैं, क्योंकि केवल ट्रोल होने वाले हैं:
// This is our back-end implementation of a troll
class Troll
{
void Walk(int distance)
{
//Implementation here
}
}
फ़्रंट एंड:
function SpawnCreature()
{
Troll aTroll = new Troll();
aTroll.Walk(1);
}
लाइन से दो हफ्ते नीचे, मार्केटिंग तय करती है कि आपको ऑर्क की भी ज़रूरत है, क्योंकि वे ट्विटर पर उनके बारे में पढ़ते हैं, इसलिए आपको कुछ ऐसा करना होगा:
class Orc
{
void Walk(int distance)
{
//Implementation (orcs are faster than trolls)
}
}
फ़्रंट एंड:
void SpawnCreature(creatureType)
{
switch(creatureType)
{
case Orc:
Orc anOrc = new Orc();
anORc.Walk();
case Troll:
Troll aTroll = new Troll();
aTroll.Walk();
}
}
और आप देख सकते हैं कि यह कैसे गन्दा होने लगता है। आप यहां एक इंटरफ़ेस का उपयोग कर सकते हैं ताकि आपके सामने के छोर को एक बार लिखा जाए और (यहां महत्वपूर्ण बिट) का परीक्षण किया जा सके, और फिर आप आवश्यक रूप से आगे के अंतिम आइटम में प्लग कर सकते हैं:
interface ICreature
{
void Walk(int distance)
}
public class Troll : ICreature
public class Orc : ICreature
//etc
मोर्चा अंत तब है:
void SpawnCreature(creatureType)
{
ICreature creature;
switch(creatureType)
{
case Orc:
creature = new Orc();
case Troll:
creature = new Troll();
}
creature.Walk();
}
फ्रंट एंड अब केवल इंटरफ़ेस ICreature की परवाह करता है - यह ट्रोल या orc के आंतरिक कार्यान्वयन के बारे में परेशान नहीं है, लेकिन केवल इस तथ्य पर कि वे ICreature को लागू करते हैं।
इस दृष्टि से देखने पर ध्यान देने योग्य एक महत्वपूर्ण बात यह है कि आप आसानी से एक अमूर्त प्राणी वर्ग का उपयोग कर सकते हैं, और इस दृष्टिकोण से, यह एक ही है प्रभाव है।
और आप निर्माण को एक कारखाने में निकाल सकते हैं:
public class CreatureFactory {
public ICreature GetCreature(creatureType)
{
ICreature creature;
switch(creatureType)
{
case Orc:
creature = new Orc();
case Troll:
creature = new Troll();
}
return creature;
}
}
और हमारा अगला छोर तब बन जाएगा:
CreatureFactory _factory;
void SpawnCreature(creatureType)
{
ICreature creature = _factory.GetCreature(creatureType);
creature.Walk();
}
सामने के छोर के पास अब उस लाइब्रेरी का संदर्भ भी नहीं है जहां ट्रोल और ओआरसी लागू किया जाता है (बशर्ते फैक्ट्री एक अलग लाइब्रेरी में हो) - इसके बारे में उन्हें कुछ भी नहीं पता होना चाहिए।
बी: कहते हैं कि आपके पास कार्यक्षमता है कि केवल कुछ जीव आपके अन्यथा समरूप डेटा संरचना में होंगे , जैसे
interface ICanTurnToStone
{
void TurnToStone();
}
public class Troll: ICreature, ICanTurnToStone
मोर्चा अंत तब हो सकता है:
void SpawnCreatureInSunlight(creatureType)
{
ICreature creature;
switch(creatureType)
{
case Orc:
creature = new Orc();
case Troll:
creature = new Troll();
}
creature.Walk();
if (creature is ICanTurnToStone)
{
(ICanTurnToStone)creature.TurnToStone();
}
}
सी: निर्भरता इंजेक्शन के लिए उपयोग
अधिकांश निर्भरता इंजेक्शन फ्रेमवर्क के साथ काम करना आसान होता है जब फ्रंट एंड कोड और बैक एंड कार्यान्वयन के बीच बहुत ढीली युग्मन होता है। यदि हम अपने कारखाने का उदाहरण ऊपर लेते हैं और हमारे कारखाने में एक इंटरफ़ेस लागू होता है:
public interface ICreatureFactory {
ICreature GetCreature(string creatureType);
}
हमारा अगला सिरा कंस्ट्रक्टर (आमतौर पर) के माध्यम से इस इंजेक्शन (जैसे एक एमवीसी एपीआई नियंत्रक) हो सकता है:
public class CreatureController : Controller {
private readonly ICreatureFactory _factory;
public CreatureController(ICreatureFactory factory) {
_factory = factory;
}
public HttpResponseMessage TurnToStone(string creatureType) {
ICreature creature = _factory.GetCreature(creatureType);
creature.TurnToStone();
return Request.CreateResponse(HttpStatusCode.OK);
}
}
हमारे DI ढांचे (उदाहरण के लिए Ninject या Autofac) के साथ, हम उन्हें सेट कर सकते हैं ताकि रनटाइम पर CreatureFactory का एक उदाहरण बन जाए जब भी एक निर्माण में एक ICreatureFactory की आवश्यकता हो - यह हमारे कोड को अच्छा और सरल बनाता है।
इसका अर्थ यह भी है कि जब हम अपने नियंत्रक के लिए एक इकाई परीक्षण लिखते हैं, तो हम एक नकली ICreatureFactory प्रदान कर सकते हैं (जैसे कि यदि ठोस कार्यान्वयन के लिए DB पहुँच की आवश्यकता है, हम नहीं चाहते कि हमारी इकाई परीक्षण उस पर निर्भर हो) और आसानी से हमारे नियंत्रक में कोड का परीक्षण करें ।
डी: अन्य उपयोग हैं जैसे कि आपके पास दो प्रोजेक्ट्स ए और बी हैं जो 'विरासत' के कारणों से अच्छी तरह से संरचित नहीं हैं, और ए में बी का संदर्भ है।
आप तब बी में कार्यक्षमता पाते हैं जो ए में पहले से ही एक विधि को कॉल करने की आवश्यकता है। आप इसे एक ठोस संदर्भ का उपयोग करके नहीं कर सकते क्योंकि आपको एक परिपत्र संदर्भ मिलता है।
आपके पास बी में घोषित एक इंटरफ़ेस हो सकता है जो ए में तब लागू होता है। बी में आपका तरीका एक ऐसे वर्ग का उदाहरण दिया जा सकता है जो इंटरफ़ेस को बिना किसी समस्या के लागू करता है, भले ही ठोस वस्तु ए में एक प्रकार की हो।