2008-10-31 10 views
32

डेल्फी (और शायद कई अन्य भाषाओं) में कक्षा सहायक हैं। ये मौजूदा वर्ग में अतिरिक्त विधियों को जोड़ने का एक तरीका प्रदान करते हैं। सबक्लास बनाने के बिना।कक्षा सहायकों के लिए अच्छे उपयोग क्या हैं?

तो, वर्ग सहायकों के लिए अच्छा उपयोग करता है क्या हैं?

उत्तर

32

मैं उन्हें उपयोग कर रहा हूँ:

  • VCL वर्गों है कि उन्हें लागू नहीं करते में insert enumerators करने के लिए।
  • enhance VCL वर्गों के लिए
  • TStrings वर्ग के लिए तरीकों को जोड़ने के लिए तो मैं my derived lists में और TStringList में एक ही तरीके का उपयोग कर सकते हैं।

    TGpStringListHelper = class helper for TStringList 
    public 
        function Last: string; 
        function Contains(const s: string): boolean; 
        function FetchObject(const s: string): TObject; 
        procedure Sort; 
        procedure Remove(const s: string); 
    end; { TGpStringListHelper } 
    
  • रिकॉर्ड खेतों और remove casting के लिए उपयोग आसान बनाने के लिए।

12

पहले तो मुझे संदेहवादी तरह का वर्ग सहायकों के बारे में था। लेकिन फिर मैंने एक दिलचस्प blog entry पढ़ा और अब मुझे आश्वस्त है कि वे वास्तव में उपयोगी हैं।

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

उदाहरण:

type 
    TStringsHelper = class helper for TStrings 
    public 
    function IsEmpty: Boolean; 
    end; 

function TStringsHelper.IsEmpty: Boolean; 
begin 
    Result := Count = 0; 
end; 

हर बार, अब हम (के एक उपवर्ग) का एक उदाहरण TStrings उपयोग करें, और TStringsHelper दायरे के भीतर है। हमारे पास IsEmpty विधि तक पहुंच है।

उदाहरण:

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    if Memo1.Lines.IsEmpty then 
    Button1.Caption := 'Empty' 
    else 
    Button1.Caption := 'Filled'; 
end; 

नोट्स:

  • कक्षा सहायकों, एक अलग इकाई में संग्रहित किया जा सकता है ताकि आप अपनी खुद की गंधा वर्ग सहायकों जोड़ सकते हैं। कक्षा इकाइयों के लिए मददगारों के लिए कक्षाओं हेल्पर जैसे नाम याद रखने के लिए इन इकाइयों को आसान बनाना सुनिश्चित करें।
  • रिकॉर्ड सहायक भी हैं।
  • अगर वहाँ दायरे के भीतर कई वर्ग सहायकों कर रहे हैं, उम्मीद है कुछ समस्या है, केवल एक सहायक के लिए इस्तेमाल किया जा सकता है।
+3

आप टिप्पणी पढ़ा है:"। वर्ग सहायकों के साथ सबसे बड़ी समस्या यह की पीओवी से अपने स्वयं के अनुप्रयोगों में उनका उपयोग करके, यह तथ्य है कि किसी दिए गए वर्ग के लिए केवल एक वर्ग सहायक किसी भी समय गुंजाइश हो सकता है। "..." यही है, यदि आपके पास दायरे में दो सहायक हैं, तो केवल एक ही पहचाना जाएगा संकलक। आपको किसी भी अन्य मददगार के बारे में कोई चेतावनी या संकेत नहीं मिलेगा जो छिपी हो सकती है। " – mjn

6

यह सी # 3 (और वीबी 9) में विस्तार विधियों की तरह लगता है।

var query = someOriginalSequence.Where(person => person.Age > 18) 
           .OrderBy(person => person.Name) 
           .Select(person => person.Job); 

(या जो कुछ भी, निश्चित रूप से): सबसे अच्छा उपयोग मैं उनके लिए देखा है IEnumerable<T> (और IQueryable<T>) करने के लिए एक्सटेंशन जो LINQ काम की सुविधा देता है मनमाने ढंग से दृश्यों के खिलाफ है। यह सब करने योग्य है क्योंकि विस्तार विधियां आपको स्थिर तरीकों से कॉल को प्रभावी ढंग से कॉल करने की अनुमति देती हैं जो वही प्रकार लेती हैं जैसे वे लौटते हैं।

+4

एक साइड नोट के रूप में, डेल्फी के पास 2000 से कक्षा सहायक हैं, और हम धारणा पर पेटेंट रखते हैं। निक होजेस डेल्फी उत्पाद प्रबंधक एम्बरकैडेरो टेक्नोलॉजीज –

+0

@ निक: डेल्फी का कौन सा संस्करण आप बात कर रहे हैं, जिसमें 2000 से कक्षा सहायक थे? मुझे केवल उनके बारे में पढ़ना याद है जब उन्हें डेल्फी 2007 में गैर-ब्रेकिंग रिलीज करने के लिए उपयोग किया जाता था। यह 6 साल बाद था जिस साल आप दावा करते हैं कि डेल्फी उन्हें था। – dummzeuch

+1

क्लास हेल्पर्स को डेल्फी 8 (डेल्फी के पहले संस्करण में .NET) में डेल्फी में जोड़ा गया था। –

3

पहली बार मैं का सामना कर रहा याद है कि तुम क्या "वर्ग सहायकों" कहते हैं, जबकि सीखने उद्देश्य सी कोको (एप्पल के उद्देश्य सी ढांचे) का उपयोग करता है क्या कहा जाता है "श्रेणियाँ था।"

श्रेणी जिसपर आप आप ही उपवर्गीकरण बिना तरीकों जोड़ कर किसी मौजूदा वर्ग का विस्तार करने की अनुमति देता है। में तथ्य कोको जब संभव उपवर्गीकरण से बचने के लिए आप को प्रोत्साहित करती है। अक्सर ऐसा समझ में आता है उपवर्ग के लिए, लेकिन अक्सर यह श्रेणियों का उपयोग कर बचा जा सकता है।

कोको में एक वर्ग के उपयोग का एक अच्छा उदाहरण क्या "कुंजी मान कोड (KVC)" और कहा जाता है कि "कुंजी मान अवलोकन (KVO)।"

इस प्रणाली के दो श्रेणियों (NSKeyValueCoding और NSKeyValueObserving का उपयोग कर कार्यान्वित किया जाता है)। ये श्रेणियां विधियों को परिभाषित और कार्यान्वित करती हैं जिन्हें आप चाहते हैं कि किसी भी वर्ग में जोड़ा जा सकता है। उदाहरण के लिए कोको ने विधियों को जोड़ने के लिए इन श्रेणियों का उपयोग करके केवीसी/केवीओ को "अनुरूपता" जोड़ा एनएसएआरएआरई जैसे:

- (id)valueForKey:(NSString *)key 

एनएसएआरएआरई कक्षा में कोई घोषणा नहीं है और न ही इस विधि का कार्यान्वयन है। हालांकि, श्रेणी के उपयोग के माध्यम से। आप किसी भी एनएसएआरएआरई कक्षा पर उस विधि को कॉल कर सकते हैं। केवीसी/केवीओ अनुरूपता प्राप्त करने के लिए आपको एनएसएआरएआरई को उप-वर्ग करने की आवश्यकता नहीं है।

NSArray *myArray = [NSArray array]; // Make a new empty array 
id myValue = [myArray valueForKey:@"name"]; // Call a method defined in the category 

इस तकनीक का उपयोग करना आपके स्वयं के वर्गों में केवीसी/केवीओ समर्थन को जोड़ना आसान बनाता है। जावा इंटरफेस आपको विधि घोषणाएं जोड़ने की अनुमति देता है, लेकिन श्रेणियां आपको मौजूदा कक्षाओं में वास्तविक कार्यान्वयन भी जोड़ने की अनुमति देती हैं।

type 
    TMyObject = class 
    public 
    procedure DoSomething; 
    end; 

    TMyObjectStringsHelper = class helper for TStrings 
    private 
    function GetMyObject(const Name: string): TMyObject; 
    procedure SetMyObject(const Name: string; const Value: TMyObject); 
    public 
    property MyObject[const Name: string]: TMyObject read GetMyObject write SetMyObject; default; 
    end; 

function TMyObjectStringsHelper.GetMyObject(const Name: string): TMyObject; 
var 
    idx: Integer; 
begin 
    idx := IndexOf(Name); 
    if idx < 0 then 
    result := nil 
    else 
    result := Objects[idx] as TMyObject; 
end; 

procedure TMyObjectStringsHelper.SetMyObject(const Name: string; const Value: 
    TMyObject); 
var 
    idx: Integer; 
begin 
    idx := IndexOf(Name); 
    if idx < 0 then 
    AddObject(Name, Value) 
    else 
    Objects[idx] := Value; 
end; 

var 
    lst: TStrings; 
begin 
    ... 
    lst['MyName'] := TMyObject.Create; 
    ... 
    lst['MyName'].DoSomething; 
    ... 
end; 

क्या तुमने कभी रजिस्ट्री में बहु लाइन तार का उपयोग करने की जरूरत है था:

3

GameCat पता चलता है, TStrings एक अच्छे उम्मीदवार कुछ टाइपिंग से बचने के लिए है?

type 
    TRegistryHelper = class helper for TRegistry 
    public 
    function ReadStrings(const ValueName: string): TStringDynArray; 
    end; 

function TRegistryHelper.ReadStrings(const ValueName: string): TStringDynArray; 
var 
    DataType: DWord; 
    DataSize: DWord; 
    Buf: PChar; 
    P: PChar; 
    Len: Integer; 
    I: Integer; 
begin 
    result := nil; 
    if RegQueryValueEx(CurrentKey, PChar(ValueName), nil, @DataType, nil, @DataSize) = ERROR_SUCCESS then begin 
    if DataType = REG_MULTI_SZ then begin 
     GetMem(Buf, DataSize + 2); 
     try 
     if RegQueryValueEx(CurrentKey, PChar(ValueName), nil, @DataType, PByte(Buf), @DataSize) = ERROR_SUCCESS then begin 
      for I := 0 to 1 do begin 
      if Buf[DataSize - 2] <> #0 then begin 
       Buf[DataSize] := #0; 
       Inc(DataSize); 
      end; 
      end; 

      Len := 0; 
      for I := 0 to DataSize - 1 do 
      if Buf[I] = #0 then 
       Inc(Len); 
      Dec(Len); 
      if Len > 0 then begin 
      SetLength(result, Len); 
      P := Buf; 
      for I := 0 to Len - 1 do begin 
       result[I] := StrPas(P); 
       Inc(P, Length(P) + 1); 
      end; 
      end; 
     end; 
     finally 
     FreeMem(Buf, DataSize); 
     end; 
    end; 
    end; 
end; 
+4

वाह, 'डिफ़ॉल्ट' ओवरराइडिंग! अविश्वसनीय। और संभवतः एजी अजीब त्रुटियों का स्रोत स्रोत :) – gabr

+0

सहमत है, यह थोड़ा सा बंद है। लेकिन मैं क्लास हेल्पर्स का अधिकतर तंग दायरे में उपयोग करता हूं, इसलिए यह कोई मुद्दा नहीं रहा है - अब तक ... –

4

वे प्लग-इन के लिए बहुत उपयोगी हैं। उदाहरण के लिए, मान लें कि आपकी प्रोजेक्ट एक निश्चित डेटा संरचना को परिभाषित करती है और यह किसी निश्चित तरीके से डिस्क पर सहेजी जाती है। लेकिन फिर कुछ अन्य कार्यक्रम कुछ समान है, लेकिन डेटा फ़ाइल अलग है। लेकिन आप एक फीचर के लिए आयात कोड के गुच्छा के साथ अपने EXE को ब्लूट नहीं करना चाहते हैं कि आपके बहुत से उपयोगकर्ताओं को उपयोग करने की आवश्यकता नहीं होगी। आप एक प्लगइन ढांचे का उपयोग और एक प्लगइन में आयातकों है कि इस तरह काम करेगा रख सकते हैं:

type 
    TCompetitionToMyClass = class helper for TMyClass 
    public 
     constructor Convert(base: TCompetition); 
    end; 

और फिर कनवर्टर परिभाषित करते हैं। एक चेतावनी: एक वर्ग सहायक कक्षा मित्र नहीं है। यह तकनीक केवल तभी काम करेगी जब इसकी सार्वजनिक विधियों और गुणों के माध्यम से एक नई TMyClass ऑब्जेक्ट को पूरी तरह से सेट करना संभव हो। लेकिन अगर आप कर सकते हैं, यह वास्तव में अच्छी तरह से काम करता है।

0

मैंने उन्हें कक्षाओं में लगातार उपलब्ध वर्ग विधियों को बनाने के लिए उपयोग किया है: केवल सक्रिय और दृश्यमान गुणों के बजाय किसी दिए गए "प्रकार" के सभी वर्गों को खोलें/बंद करें और दिखाएं/छुपाएं।

2

मैं के बाद से मैं इस टिप्पणी को पढ़ते हैं, उन्हें इस्तेमाल करने की सिफारिश नहीं होगा:,

"वर्ग सहायकों के साथ सबसे बड़ी समस्या है, उन्हें अपने खुद के अनुप्रयोगों में उपयोग करने का पीओवी से तथ्य यह है कि किसी दिए गए कक्षा के लिए केवल एक वर्ग सहायक, किसी भी समय दायरे में हो सकता है। " ... "यही है, यदि आपके पास दो सहायक हैं दायरे में, केवल एक को संकलक द्वारा पहचाना जाएगा।आप किसी भी चेतावनी मिल जाएगा नहीं या यहां तक ​​कि किसी अन्य सहायकों कि छिपा हो सकता है के बारे में संकेत "

http://davidglassborow.blogspot.com/2006/05/class-helpers-good-or-bad.html

+3

मैंने उस टिप्पणी को पढ़ लिया है। लेकिन इसका उपयोग करने का कोई कारण नहीं है। बस किसी भी अन्य उपकरण की तरह सावधानीपूर्वक उनका उपयोग करें। –

+1

@GamecatisToonKrijthe संकेत भी नहीं, इसका मतलब है कि डेवलपर्स को अब "संघर्ष सहायक" का पता लगाने के लिए तीसरे पक्ष के पुस्तकालयों के सभी स्रोतों को स्कैन करना होगा (केवल एक बार नहीं बल्कि प्रत्येक अपडेट के लिए भी) ... – mjn

संबंधित मुद्दे