मैं एक एपीआई डिज़ाइन पर काम कर रहा हूं, और जावा और पॉलिमॉर्फिज्म के बारे में कुछ है जो मैंने अभी तक नहीं सोचा था। अगर मैं इस तरह एक API बनाएँ:जावा, पॉलिमॉर्फिज्म, स्टेटिक टाइपिंग और "क्वेरीइंटरफेस" पैटर्न
interface FooFactory
{
public Foo getFoo();
}
interface Foo
{
public void sayFoo();
}
तो केवल एक चीज है कि मेरे FooFactory
कार्यान्वयन पर भरोसा किया जा सकता है प्रदान करने के लिए एक Foo
कार्यान्वयन है। मैं, कुछ बढ़ाया तरीकों प्रदान करने के लिए इस तरह का निर्णय लेते हैं:
interface EnhancedFoo extends Foo
{
public void patHeadAndRubBelly();
}
class EnhancedFooImpl implements EnhancedFoo
{
... implementation here ...
}
class EnhancedFooFactoryImpl implements FooFactory
{
@Override public EnhancedFoo getFoo() { return new EnhancedFooImpl(); }
}
और अगर वे एक Foo
इंटरफ़ेस प्राप्त करने और EnhancedFoo
के रूप में यह कास्ट करने के लिए कोशिश एक ही रास्ता मेरे API क्लाइंट EnhancedFoo
इंटरफ़ेस का उपयोग कर सकते हैं।
मैं जिस तरह से माइक्रोसॉफ्ट IUnknown
इंटरफ़ेस में COM संभाला याद रखें:
HRESULT QueryInterface(
[in] REFIID riid,
[out] void **ppvObject
);
विचार है कि आप इंटरफ़ेस आप चाहते हैं के लिए एक GUID में गुजरती हैं, अगर यह सफल होता है, तो आप वापस एक सूचक आप की गारंटी देता है कि मिलता है आप जिस इंटरफ़ेस को ढूंढ रहे थे उसे सुरक्षित रूप से डाला जा सकता है।
मैं जावा के साथ एक typesafe रास्ते में कुछ इसी तरह कर सकता है:
interface FooFactory
{
public <T extends Foo> T getFoo(Class<T> fooClass);
}
जहाँ मैं अनुरोध है कि या तो वांछित subinterface का एक उदाहरण देता है, या नल लौटाता है यदि कोई भी उपलब्ध है पर एक कार्यान्वयन प्रदान करते हैं।
मेरे सवाल है,:
- QueryInterface पैटर्न उचित है?
- क्या मुझे सिर्फ कास्टिंग का उपयोग करना चाहिए?
- या एपीआई में पॉलिमॉर्फिज्म को संभालने का एकमात्र सही तरीका है ताकि ग्राहकों को सवाल में सादे तरीकों का सख्ती से उपयोग करने से प्रतिबंधित किया जा सके? (उदाहरण के लिए मेरी उदाहरण में
Foo
में तरीकों और नहीं किसी भीEnhancedFoo
तरीकों)
स्पष्टीकरण: कारखाने कार्यान्वयन ग्राहक कोड से जाना जाता नहीं जा रहा है। (मान लें कि यह निर्भरता इंजेक्शन या जावा सेवा ServiceLoader
या नेटबीन Lookup
जैसे कुछ सेवा प्रदाता आर्किटेक्चर का उपयोग करता है।) इसलिए एक ग्राहक के रूप में, मुझे नहीं पता कि क्या उपलब्ध है। फैक्ट्री के पास कई Foo
डेरिवेटिव तक पहुंच हो सकती है और मैं चाहता हूं कि क्लाइंट एक फीचर सेट का अनुरोध करने में सक्षम हो, जो इसे चाहता है, और या तो इसे प्राप्त हो, या इसे आधार Foo
कार्यक्षमता पर वापस गिरना होगा।
मुझे लगता है कि मेरे लिए कठिन हिस्सा यह है कि यहां रनटाइम निर्भरता है ... शुद्ध स्थैतिक प्रकारएफ़ दृष्टिकोण जहां संकलन समय पर सब कुछ तय किया गया है इसका मतलब है कि मैं केवल उस मूल Foo
कार्यक्षमता पर निर्भर कर सकता हूं। वह दृष्टिकोण मुझसे परिचित है, लेकिन फिर मैं संभावित उन्नत सुविधाओं पर हार जाता हूं। जबकि अधिक गतिशील/अवसरवादी दृष्टिकोण ऐसा कुछ है जो इन सुविधाओं का लाभ उठा सकता है, लेकिन मुझे इसका उपयोग करने वाली प्रणाली को आर्किटेक्ट करने का सही तरीका नहीं है।
जावा 8 में टाइप अनुमान में सुधार किया गया है। – assylias
हम्म ... पाइथन के लिए अपवाद दृष्टिकोण सामान्य है लेकिन जावा के लिए अनुचित लगता है। –
मैं कहूंगा कि यह पूरी तरह उपयुक्त है - शून्य-जांच – Arkadiy