बेशक, टपका हुआ अमूर्त के कानून को लागू कर सकता है, लेकिन यह विशेष रूप से दिलचस्प नहीं है क्योंकि यह मानता है कि सभी अमूर्त टपका हुआ है। कोई भी उस अनुमान के खिलाफ और उसके खिलाफ बहस कर सकता है, लेकिन यह मदद नहीं करता है अगर हम इस बात की समझ साझा नहीं करते हैं कि हमें अमूर्तता से क्या मतलब है , और हम लीक से क्या मतलब है । इसलिए, मैं सबसे पहले यह बताने की कोशिश करूँगा कि मैं इनमें से प्रत्येक को कैसे देखता हूँ:
कपोल-कल्पना
सार की मेरी पसंदीदा परिभाषा रॉबर्ट सी। मार्टिन के एपीपीपी से ली गई है :
"एक अमूर्त आवश्यक और अप्रासंगिक के उन्मूलन का प्रवर्धन है।"
इस प्रकार, इंटरफेस, अपने आप में, सार नहीं हैं । वे केवल सार हैं यदि वे सतह पर लाते हैं जो मायने रखता है, और बाकी को छुपाता है।
टपका हुआ
पुस्तक निर्भरता इंजेक्शन सिद्धांत, पैटर्न, और अभ्यास निर्भरता इंजेक्शन (DI) के संदर्भ में टपका हुआ अमूर्त शब्द को परिभाषित करता है । इस संदर्भ में बहुरूपता और ठोस सिद्धांत एक बड़ी भूमिका निभाते हैं।
से निर्भरता उलट सिद्धांत (DIP) यह मानता है, इस प्रकार फिर से APPP के हवाले से, कि:
"क्लाइंट [...] अमूर्त इंटरफेस के मालिक हैं"
इसका मतलब यह है कि ग्राहक (कॉलिंग कोड) उन अमूर्तताओं को परिभाषित करते हैं जिनकी उन्हें आवश्यकता होती है, और फिर आप उस अमूर्त को लागू करते हैं।
मेरे विचार में एक टपका हुआ अमूर्त , एक अमूर्तता है जो डीआईपी का उल्लंघन किसी तरह से कुछ कार्यक्षमता सहित करता है जिसकी क्लाइंट को आवश्यकता नहीं है ।
तुल्यकालिक निर्भरताएँ
एक ग्राहक जो व्यावसायिक तर्क का एक टुकड़ा लागू करता है, आमतौर पर DI को कुछ कार्यान्वयन विवरणों, जैसे कि, आमतौर पर, डेटाबेस से स्वयं को हटाने के लिए उपयोग करेगा।
एक डोमेन ऑब्जेक्ट पर विचार करें जो एक रेस्तरां आरक्षण के लिए अनुरोध को संभालता है:
public class MaîtreD : IMaîtreD
{
public MaîtreD(int capacity, IReservationsRepository repository)
{
Capacity = capacity;
Repository = repository;
}
public int Capacity { get; }
public IReservationsRepository Repository { get; }
public int? TryAccept(Reservation reservation)
{
var reservations = Repository.ReadReservations(reservation.Date);
int reservedSeats = reservations.Sum(r => r.Quantity);
if (Capacity < reservedSeats + reservation.Quantity)
return null;
reservation.IsAccepted = true;
return Repository.Create(reservation);
}
}
यहाँ, ग्राहक, वर्ग द्वारा IReservationsRepository
निर्भरता का निर्धारण विशेष रूप से किया जाता है MaîtreD
:
public interface IReservationsRepository
{
Reservation[] ReadReservations(DateTimeOffset date);
int Create(Reservation reservation);
}
यह इंटरफ़ेस पूरी तरह से सिंक्रोनस है क्योंकि MaîtreD
क्लास को एसिंक्रोनस होने की आवश्यकता नहीं है ।
अतुल्यकालिक निर्भरताएँ
आप आसानी से अतुल्यकालिक होने के लिए इंटरफ़ेस बदल सकते हैं:
public interface IReservationsRepository
{
Task<Reservation[]> ReadReservations(DateTimeOffset date);
Task<int> Create(Reservation reservation);
}
MaîtreD
वर्ग, हालांकि, यह नहीं है की जरूरत है उन तरीकों अतुल्यकालिक होने की, तो अब DIP का उल्लंघन किया है। मैं इसे एक टपका हुआ अमूर्त मानता हूं, क्योंकि एक कार्यान्वयन विवरण क्लाइंट को बदलने के लिए मजबूर करता है। TryAccept
विधि अब भी अतुल्यकालिक बनना पड़ता है:
public async Task<int?> TryAccept(Reservation reservation)
{
var reservations =
await Repository.ReadReservations(reservation.Date);
int reservedSeats = reservations.Sum(r => r.Quantity);
if (Capacity < reservedSeats + reservation.Quantity)
return null;
reservation.IsAccepted = true;
return await Repository.Create(reservation);
}
डोमेन तर्क के लिए अतुल्यकालिक होने के लिए कोई अंतर्निहित तर्क नहीं है, लेकिन कार्यान्वयन की अतुल्यकालिकता का समर्थन करने के लिए, अब यह आवश्यक है।
बेहतर विकल्प
एनडीसी सिडनी 2018 में मैंने इस विषय पर बात की । इसमें, मैं एक विकल्प को भी रेखांकित करता हूं जो लीक नहीं करता है। मैं 2019 में भी कई सम्मेलनों में यह बात दे रहा हूं, लेकिन अब Async इंजेक्शन के नए शीर्षक के साथ फिर से लिखा गया है ।
मैं भी बात करने के लिए ब्लॉग पोस्ट की एक श्रृंखला प्रकाशित करने की योजना बना रहा हूं। ये लेख पहले से ही मेरे लेख कतार में बैठे हैं, प्रकाशित होने की प्रतीक्षा में हैं, इसलिए बने रहें।