दिलचस्प पोस्ट
मेवेन जावा 8 में काम नहीं कर रहा है जब Javadoc टैग अपूर्ण हैं उपयोग स्कीमा के उपयोग से एक सूची स्वत: तारों को NoSuchBeanDefinitionException प्रदान करता है पासवर्ड को हैशिंग और एन्क्रिप्ट करने में अंतर MVC में $ _POST डेटा को संभालने का सही तरीका क्या है? अंतराल स्क्रॉल रीसाइक्लर में आइटम को जोड़ना प्रगति के साथ नीचे तल मैं कस्टम अपवाद कैसे लिख सकता हूँ? बहुत अधिक फ़ील्ड संदर्भ: 70613; मैक्स 65536 है प्रथम और आखिरी चलनेवाली लुक में एक foreach लूप कैसे निर्धारित करें? MySQL को संग्रहीत दिनचर्या को पास करें पायथन लॉगर को लॉग करने के अलावा सभी संदेशों को stdout में आउटपुट करना मैं वर्तमान स्क्रीन अभिविन्यास कैसे प्राप्त करूं? मैं सीएसएस विरासत को कैसे रोकूं? सूची पर एंड्रॉइड स्वाइप करें विधि में हस्ताक्षर होना चाहिए "स्ट्रिंग विधि () … …" लेकिन हस्ताक्षर "शून्य विधि ()" है आप स्ट्रिंगस्ट्रीम चर कैसे साफ़ करते हैं?

VBA में कन्स्ट्रक्टर को तर्क दें

आप अपनी कक्षाओं में सीधे तर्कों को पारित करने के लिए किस तरह का निर्माण कर सकते हैं?

कुछ इस तरह:

Dim this_employee as Employee Set this_employee = new Employee(name:="Johnny", age:=69) 

ऐसा करने में सक्षम नहीं है, बहुत परेशान है, और आप इस के आसपास काम करने के लिए गंदा समाधानों के साथ समाप्त होते हैं।

वेब के समाधान से एकत्रित समाधान "VBA में कन्स्ट्रक्टर को तर्क दें"

यहाँ थोड़ी चाल है जो मैं हाल ही में उपयोग कर रहा हूं और अच्छे परिणाम लाता हूं। मैं उन लोगों के साथ साझा करना चाहूंगा, जिन्हें अक्सर वीबीए के साथ लड़ना पड़ता है।

1.- अपने प्रत्येक कस्टम क्लास में एक सार्वजनिक दीक्षा उपनेमका लागू करें मैं इसे अपने सभी वर्गों में शुरूआत करते हुए कॉल करता हूं। इस पद्धति को उन तर्कों को स्वीकार करना होगा जो आप कन्स्ट्रक्टर को भेजना चाहते हैं।

2.- एक कारखाना नामक एक मॉड्यूल बनाएं, और "बनाएं" प्लस शब्द के समान एक समान नाम के साथ एक सार्वजनिक फ़ंक्शन बनाएं और कन्स्ट्रक्टर की आवश्यकता के रूप में एक ही आवक तर्क। इस फ़ंक्शन को अपने वर्ग को इन्स्तांत करना है, और प्राप्त तर्कों को पारित करने के लिए बिंदु (1) में दी गई दीक्षा उपनेमका को बुलाओ। अंत में तत्काल और शुरू की गई विधि को वापस लौटाया।

उदाहरण:

मान लें कि हमारे पास कस्टम क्लास कर्मचारी हैं पिछले उदाहरण के रूप में, नाम और उम्र के साथ तत्काल होना चाहिए।

यह आरंभ नीतियों का तरीका है m_name और m_age हमारी निजी संपत्तियों को निर्धारित किया जा सकता है।

 Public Sub InitiateProperties(name as String, age as Integer) m_name = name m_age = age End Sub 

और अब फ़ैक्टरी मॉड्यूल में:

 Public Function CreateEmployee(name as String, age as Integer) as Employee Dim employee_obj As Employee Set employee_obj = new Employee employee_obj.InitiateProperties name:=name, age:=age set CreateEmployee = employee_obj End Function 

और अंत में जब आप किसी कर्मचारी को इन्स्तांत करना चाहते हैं

 Dim this_employee as Employee Set this_employee = factory.CreateEmployee(name:="Johnny", age:=89) 

विशेष रूप से उपयोगी है जब आपके पास कई कक्षाएं हैं। बस मॉड्यूल कारखाने में प्रत्येक के लिए एक फ़ंक्शन रखें और कारखाने को कॉल करके तुरंत शुरू करें। क्रेलेट क्लास ए (फलक) , कारखाना। क्रेलेट क्लास बी (अन्य_ग्राम) आदि।

संपादित करें

जैसा कि स्टेन्सी ने बताया, आप कंसट्रक्टर फ़ंक्शंस में एक स्थानीय चर बनाने से बचने के द्वारा टीर्स सिंटैक्स के साथ एक ही बात कर सकते हैं। उदाहरण के लिए CreateEmployee फ़ंक्शन इस प्रकार लिखा जा सकता है:

 Public Function CreateEmployee(name as String, age as Integer) as Employee Set CreateEmployee = new Employee CreateEmployee.InitiateProperties name:=name, age:=age End Function 

कौन सा अच्छा है

मैं एक Factory मॉड्यूल का उपयोग करता हूं जिसमें एक (या अधिक) कंस्ट्रक्टर प्रति वर्ग शामिल होता है जो प्रत्येक वर्ग के Init सदस्य को कॉल करता है।

उदाहरण के लिए एक Point क्लास:

 Class Point Private X, Y Sub Init(X, Y) Me.X = X Me.Y = Y End Sub 

एक Line क्लास

 Class Line Private P1, P2 Sub Init(Optional P1, Optional P2, Optional X1, Optional X2, Optional Y1, Optional Y2) If P1 Is Nothing Then Set Me.P1 = NewPoint(X1, Y1) Set Me.P2 = NewPoint(X2, Y2) Else Set Me.P1 = P1 Set Me.P2 = P2 End If End Sub 

और एक Factory मॉड्यूल:

 Module Factory Function NewPoint(X, Y) Set NewPoint = New Point NewPoint.Init X, Y End Function Function NewLine(Optional P1, Optional P2, Optional X1, Optional X2, Optional Y1, Optional Y2) Set NewLine = New Line NewLine.Init P1, P2, X1, Y1, X2, Y2 End Function Function NewLinePt(P1, P2) Set NewLinePt = New Line NewLinePt.Init P1:=P1, P2:=P2 End Function Function NewLineXY(X1, Y1, X2, Y2) Set NewLineXY = New Line NewLineXY.Init X1:=X1, Y1:=Y1, X2:=X2, Y2:=Y2 End Function 

इस दृष्टिकोण का एक अच्छा पहलू यह है कि यह अभिव्यक्ति के भीतर फ़ैक्टरी फ़ंक्शन का उपयोग करना आसान बनाता है। उदाहरण के लिए ऐसा कुछ करना संभव है:

 D = Distance(NewPoint(10, 10), NewPoint(20, 20) 

या:

 D = NewPoint(10, 10).Distance(NewPoint(20, 20)) 

यह साफ है: फैक्ट्री बहुत कम है और यह लगातार सभी ऑब्जेक्ट्स में, प्रत्येक निर्माता पर सिर्फ सृजन और एक Init कॉल करता है

और यह काफी ऑब्जेक्ट ओरिएंटेड है: Init फ़ंक्शन ऑब्जेक्ट्स के अंदर परिभाषित किए गए हैं।

संपादित करें

मैं जोड़ना भूल गया था कि इससे मुझे स्थिर तरीकों का निर्माण करने की अनुमति मिलती है I उदाहरण के लिए मैं कुछ ऐसा कर सकता हूँ (पैरामीटर वैकल्पिक बनाने के बाद):

 NewLine.DeleteAllLinesShorterThan 10 

दुर्भाग्य से ऑब्जेक्ट का एक नया उदाहरण हर बार बनाया जाता है, इसलिए निष्पादन के बाद कोई स्थिर वैरिएबल खो जाएगा। इस छद्म-स्थिर विधि में प्रयुक्त लाइनों का संग्रह और किसी अन्य स्थिर वैरिएबल को एक मॉड्यूल में परिभाषित किया जाना चाहिए।

जब आप एक क्लास मॉड्यूल निर्यात करते हैं और नोटपैड में फ़ाइल खोलते हैं, तो आप नोटिस करेंगे, शीर्ष के पास, छुपी विशेषताओं का एक गुच्छा (वीबीई उन्हें प्रदर्शित नहीं करता है, और उनमें से ज्यादातर को ज़्यादा ज़ूम करने के लिए कार्यक्षमता का खुलासा नहीं करता है)। उनमें से एक VB_PredeclaredId :

 Attribute VB_PredeclaredId = False 

इसे True सेट करें, सहेजें, और मॉड्यूल को अपने VBA प्रोजेक्ट में पुनः आयात करें।

वैकल्पिक रूप से यदि आप रबरडॉक का उपयोग कर रहे हैं, तो आप मॉड्यूल के शीर्ष पर केवल एक विशेष एनोटेशन निर्दिष्ट कर सकते हैं:

 '@PredeclaredId Option Explicit 

Rubberduck एक निरीक्षण परिणाम बताते हुए कहते हैं कि मॉड्यूल एट्रिब्यूट मॉड्यूल एनोटेशन के साथ सिंक्रनाइज़ेशन से बाहर हैं, और एक क्लिक के साथ आप VB_PredeclaredId छोड़ने के बिना VB_PredeclaredId विशेषता सेट कर सकते हैं (ध्यान दें: इस लेखन के रूप में यह अभी भी प्रयोगात्मक सुविधा है)।

एक PredeclaredId साथ क्लासेस में एक "वैश्विक उदाहरण" है जिसे आप मुफ्त में प्राप्त करते हैं – बिल्कुल UserForm मॉड्यूल (एक उपयोगकर्ता फ़ॉर्म निर्यात करें, आप देखेंगे कि इसकी पूर्ववर्ती आईडी विशेषता सही पर सेट है)।

बहुत सारे लोगों ने राज्य को स्टोर करने के लिए पूर्ववत उदाहरण का आनंद लिया है। यह गलत है – यह एक स्थैतिक वर्ग में उदाहरण राज्य को संग्रहीत करने की तरह है!

इसके बजाय, आप अपनी फैक्टरी पद्धति को कार्यान्वित करने के लिए डिफ़ॉल्ट आवृत्ति का लाभ उठाते हैं:

[ Employee वर्ग]

 '@PredeclaredId Option Explicit Private Type TEmployee Name As String Age As Integer End Type Private this As TEmployee Public Function Create(ByVal emplName As String, ByVal emplAge As Integer) As Employee With New Employee .Name = emplName .Age = emplAge Set .Create = .Self End With End Function Public Property Get Self() As Employee Set Self = Me End Property Public Property Get Name() As String Name = this.Name End Property Public Property Let Name(ByVal value As String) this.Name = value End Property Public Property Get Age() As String Age = this.Age End Property Public Property Let Age(ByVal value As String) this.Age = value End Property 

उसके साथ, आप यह कर सकते हैं:

 Dim empl As Employee Set empl = Employee.Create("Johnny", 69) 

Employee.Create डिफ़ॉल्ट रूप से काम कर रहा है, अर्थात इसे प्रकार के सदस्य माना जाता है, और केवल डिफ़ॉल्ट आवृत्ति से लागू किया जाता है।

समस्या यह है कि यह पूरी तरह से कानूनी है:

 Dim emplFactory As New Employee Dim empl As Employee Set empl = emplFactory.Create("Johnny", 69) 

और वह बेकार है, क्योंकि अब आपके पास भ्रमित एपीआई है। आप दस्तावेज़ उपयोग के लिए VB_Description '@Description एनोटेशन / VB_Description एट्रिब्यूट्स का उपयोग कर सकते हैं, लेकिन VB_Description बिना संपादक में कुछ भी नहीं है जो आपको कॉल साइटों पर मौजूद जानकारी दिखाता है।

इसके अलावा, Property Let सदस्यों को सुलभ हैं, इसलिए आपके Employee उदाहरण अस्थिर है :

 empl.Name = "Booba" ' Johnny no more! 

यह चाल आपके वर्ग को एक इंटरफ़ेस लागू करने के लिए है, जो केवल उजागर होने की आवश्यकता होती है।

[ IEmployee वर्ग]

 Option Explicit Public Property Get Name() As String : End Property Public Property Get Age() As Integer : End Property 

और अब आप Employee को IEmployee लागू IEmployee – अंतिम कक्षा इस तरह दिखाई दे सकती है:

[ Employee वर्ग]

 '@PredeclaredId Option Explicit Implements IEmployee Private Type TEmployee Name As String Age As Integer End Type Private this As TEmployee Public Function Create(ByVal emplName As String, ByVal emplAge As Integer) As IEmployee With New Employee .Name = emplName .Age = emplAge Set .Create = .Self End With End Function Public Property Get Self() As IEmployee Set Self = Me End Property Public Property Get Name() As String Name = this.Name End Property Public Property Let Name(ByVal value As String) this.Name = value End Property Public Property Get Age() As String Age = this.Age End Property Public Property Let Age(ByVal value As String) this.Age = value End Property Private Property Get IEmployee_Name() As String IEmployee_Name = Name End Property Private Property Get IEmployee_Age() As Integer IEmployee_Age = Age End Property 

ध्यान दें कि विधि Create अब इंटरफ़ेस देता है , और इंटरफ़ेस Property Let खुलासा नहीं करता सदस्यों को Property Let ? अब कॉलिंग कोड इस तरह दिख सकता है:

 Dim empl As IEmployee Set empl = Employee.Create("Immutable", 42) 

और चूंकि क्लाइंट कोड इंटरफ़ेस के खिलाफ लिखा जाता है, केवल IEmployee के सदस्य ही IEmployee अंतरफलक द्वारा परिभाषित सदस्य होते हैं, जिसका अर्थ है कि यह विधि Create , न ही Self प्राप्तकर्ता, न ही किसी भी Property Let बदलते हैं। "कंक्रीट" Employee वर्ग के साथ काम करने के बजाय, शेष कोड "सार" IEmployee इंटरफ़ेस के साथ काम कर सकता है, और एक अपरिवर्तनीय, IEmployee वस्तु का आनंद ले सकता है।

एक अन्य दृष्टिकोण

कहते हैं कि आप एक क्लास क्लास बनाते हैं

क्लास मॉड्यूल में एक अतिरिक्त उप-रूटिन बनाते हैं, जो कार्य करता है क्योंकि आप वास्तविक निर्माता को व्यवहार करना चाहते हैं। नीचे मैंने इसे कन्स्ट्रक्टरअजिग्नेट नाम दिया है।

 Public Sub ConstructorAdjunct(ByVal ...) ... End Sub From the calling module, you use an additional statement Dim loPublicKey AS clsBitcoinPublicKey Set loPublicKey = New clsBitcoinPublicKey Call loPublicKey.ConstructorAdjunct(...) 

एकमात्र दंड अतिरिक्त कॉल है, लेकिन फायदा यह है कि आप कक्षा मॉड्यूल में सब कुछ रख सकते हैं, और डीबगिंग आसान हो जाता है