2011-01-08 15 views
9

बिल्डिंग मेरे पास एक ऐप है जो अनिवार्य रूप से किसी तृतीय पक्ष API के लिए एक रैपर है। ऐप डेटाबेस का उपयोग नहीं करता है और केवल एक कुकी को स्टोर करता है जो एपीआई की आवश्यकता होती है।PHP ओओपी :: एक एपीआई रैपर वर्ग

एपीआई एक शॉपिंग प्रणाली है जो करने के लिए

-login/रजिस्टर/प्रोफ़ाइल संपादित करें/लॉगआउट

खरीदें माल

एक दान बनाओ

-become एक सदस्य उपयोगकर्ताओं की अनुमति देता है

एपीआई में 50 या तो विधियां हैं जिनसे मेरे ऐप को कनेक्ट करने की आवश्यकता है। उदाहरण एपीआई कॉल addItemToBasket(), addDonation(), GetUserDetails() इत्यादि

मैं अपने आवेदन में कक्षाओं में क्या होना चाहिए, यह जानने का प्रयास कर रहा हूं। यहाँ मैं अब तक है:

क्लासेस

1) APIManager() वर्ग तरीकों कि एक-से-एक 3 पार्टी एपीआई में उजागर तरीकों के साथ मेल खाते हैं और प्रदान करता है शामिल रिमोट एपीआई सर्वर से कनेक्शन बनाने के लिए तंत्र। इसलिए, यदि उपयोगकर्ता के माध्यम से

APIManager->loginUser($sessionKey, $uid, $pwd); 

में लॉग इन किया जाएगा और दूरदराज के एपीआई उपयोगकर्ता के रूप में लॉग इन सेट चाहते हैं की जरूरत हो, मेरे ऐप की जांच कर सकते हैं किसी भी सत्र कुंजी की स्थिति में लॉग इन एपीआई फोन करके:।

APIManager->isLoggedIn($sessionKey); 

2) उपयोगकर्ता() वर्ग यह तरीकों कि व्यापार में इस तरह के रजिस्टर या लॉग इन के रूप में API कॉल संसाधित करने से पहले आवश्यक तर्क शामिल रखती है। एक उदाहरण विधि है:

function login($_POST) { 
    //perform sanity checks, apply business rules etc. 
    //if certain conditions are met, we may pass in a promo code, $pc 

    APIManager->loginUser($sessionkey, $_POST['uid'], $_POST['pwd'], $pc); 
} 

मुझे लगता है कि मैं शायद सिर्फ लॉगिन पृष्ठ के APIManager को कॉल कर सकते हैं, बल्कि एक उपयोगकर्ता वर्ग से प्रति की तुलना में, लेकिन मुझे लगा कि कुछ व्यापार तर्क से पहले चलाने की जरूरत है के बाद से हम वास्तव में एपीआई की loginUser() विधि को कॉल करते हैं, यह उपयोगकर्ता वर्ग के भीतर संभालने का अधिकार महसूस करता है। मैं जानना चाहता हूं कि लोग इसके बारे में क्या सोचते हैं।

3) टोकरी() वर्ग

टोकरी 3 पार्टी एपीआई में किया जाता है, इसलिए मेरे ऐप की भूमिका उचित API टोकरी के लिए नए आइटम जोड़ने के, आइटम निकालने कॉल करने के लिए है देखने टोकरी इत्यादि। मेरा ऐप टोकरी के बारे में कुछ भी नहीं जानता है जब तक कि एपीआई से डेटा पुनर्प्राप्त नहीं किया जाता है, न ही यह एपीआई के बिना टोकरी में कोई भी बदलाव कर सकता है। फिर, यह इस संबंधित तर्क को बास्केट क्लास में समूहित करने के लिए उपयुक्त महसूस किया। सामने के छोर वेब पेज की तरह कुछ कह सकते हैं:

Basket->addItem(23); 

और टोकरी कक्षा में इस addItem() विधि तरह दिखता होगा:

addItem($itemID) { 
    //perform checks, apply business rules e.g. if user is eligible for discount 
     APIManager->addToCart($itemID, $discount); 
} 

जहां addToCart जैसा() तृतीय पक्ष API विधि है हम आइटम को संसाधित करने के लिए कॉल करें।

4) दान() वर्ग

यह उपयोगकर्ताओं को दान देने के लिए अनुमति देता है। टोकरी में दान दिखाई देता है और टोकरी से हटाया जा सकता है। मैं सिर्फ टोकरी वर्ग के लिए एक addDonate() विधि को जोड़ने और सभी में एक दान वस्तु होने की चिंता न के बारे में सोचा है, लेकिन ... (देखें नीचे)

5) सदस्यता() वर्ग

। .. सदस्यता वास्तव में दान का एक प्रकार है! एपीआई दान को 1 साल की सदस्यता के रूप में एक निश्चित खाते में जाने का इलाज करेगा, और सादा दान नहीं। हम तृतीय पक्ष एपीआई के तर्क/व्यवहार को नहीं बदल सकते हैं।

तो, अगर मैं खाता '1' के लिए $ 50 दान करता हूं तो यह सिर्फ एक सामान्य दान है, लेकिन अगर मैं '8' खाते में $ 100 दान करता हूं तो मैं सभी सदस्य लाभ (कम कीमत, कोई डाक शुल्क इत्यादि) के साथ सदस्य बन जाता हूं।)।

यहां वह जगह है जहां मुझे इसे डिजाइन करने का सबसे अच्छा तरीका नहीं है।

क्या मुझे दान श्रेणी बनाना चाहिए और उसके बाद सदस्यता के साथ विस्तार करना चाहिए, क्योंकि सभी दान विधियों को सदस्यता द्वारा आवश्यक होगा। लेकिन सदस्यता को नवीनीकरण() या getExpiry() आदि जैसे अतिरिक्त तरीकों की आवश्यकता होगी

साथ ही, क्या मुझे सदस्य बनने के लिए उपयोगकर्ता को विस्तारित करना चाहिए? दोबारा, एक सदस्य के पास उपयोगकर्ता की सभी मूल विधियां होती हैं, लेकिन इसमें अतिरिक्त हैं जैसे getSpecialOffers() या getDiscountCode() जो केवल सदस्य ही पहुंचेंगे।

डिज़ाइन तक पहुंचने के तरीके में कोई मार्गदर्शन बहुत सराहना की जाएगी।

धन्यवाद, जेम्स

+3

नहीं जवाब आप के लिए देख रहे हैं, लेकिन मुझे क्या मदद करता है जब एक वस्तु केंद्रित डिजाइन में कुछ भी डिजाइनिंग एक चित्र बाहर आकर्षित करने के लिए है ऑब्जेक्ट्स, जहां सामान्यता है वहां काम कर रहे हैं आदि। यदि आप गोता लगाने और कोड करने से पहले ऐसा करते हैं तो आप पाएंगे कि आपके पास इसका एक आसान समय है। और आप लंबे समय तक कुछ और बनाए रखने के साथ खत्म हो जाएगा। – diagonalbatman

उत्तर

18

व्यक्तिगत रूप से, मैं इस 3 परतों में निर्माण होगा।

लेयर 1: एपीआई इंटरफ़ेस

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

कुछ वर्गों है कि इस स्थान से संबंधित हो सकता है:

  • XMLRPC_Client
  • SOAP_Client
  • REST_Client

परत 2: एपीआई एडाप्टर

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

याद रखने की एक महत्वपूर्ण बात यह है कि यह एडाप्टर परत एपीआई को शामिल करने के लिए है। इसलिए प्रत्येक व्यक्तिगत वर्ग का दायरा एपीआई कार्यान्वयन की संपूर्णता है। इसलिए एडेप्टर और रिमोट एपीआई के बीच 1: 1 मैपिंग होना चाहिए।

कुछ वर्गों है कि यहाँ हो सकता है:

  • RemoteAPI_v1_5
  • RemoteAPI2_v1

परत 3: आंतरिक वस्तुओं

यह परत विभिन्न वस्तुओं के अपने आंतरिक प्रतिनिधित्व होना चाहिए (आपके विशिष्ट मामले में: उपयोगकर्ता, टोकरी, कार्ट, दान, सदस्यता, आदि)। उन्हें एपीआई को सीधे कॉल नहीं करना चाहिए, लेकिन एपीआई में मूल रूप से bridge बनने के लिए संरचना (निर्भरता इंजेक्शन) का उपयोग करना चाहिए। इसे अलग रखकर, आप आंतरिक वर्गों (और vise versa) से पूरी तरह से स्वतंत्र एपीआई को अलग करने में सक्षम होना चाहिए।

तो, अपने वर्गों में से एक इस प्रकार दिखाई देंगे:

class User { 
    protected $api; 
    public function __construct(iAPIAdapter $api) { 
     $this->api = $api; 
    } 
    public function login() { 
     $this->api->loginUser($blah); 
    } 
} 

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

वह मेरी $ 0.02 है। यह overkill हो सकता है, लेकिन वह वास्तव में अपने सटीक जरूरत पर निर्भर करता है ...

+0

अच्छे सुझाव और स्पष्टीकरण। वंशानुगत इंजेक्शन विरासत पर संरचना में महत्वपूर्ण है। – crush

+0

@ircmaxwell अच्छी पोस्ट। मैं आपकी सलाह के बाद एक एपीआई रैपर बनाने जा रहा हूं। क्या आप इस मॉडल पर बनाए गए एपीआई रैपर के उदाहरण से लिंक कर सकते हैं जिसे मैं देख सकता हूं? – bernie2436

+1

इस उत्तर को स्वीकार नहीं करना एक अपराध है .. यह केवल साढ़े सालों से है .. – FloatingRock

0

मैं कहना चाहता हूँ:

  1. सब है कि यह जरूरत
  2. सदस्यता के एक सदस्य चर बनाने के साथ एक दान वर्ग बनाने (जो दान दान का होना चाहिए)।

    public function makeDonation($data) { 
        $this->donation = new Donation($data) // maybe with the data parameter; 
        $this->donation->commit() // whatever it does to set things up 
         ...... 
         whatever you need 
    } 
    

इस तरह आप आइटम के बीच अच्छा decoupling है:

  • आप सदस्यता वर्ग ऐसे में एक विधि हो सकता है। इसके अलावा दान को एक इफेरफेस को कार्यान्वित करना चाहिए ताकि अगर व्यवहार बाद में बदल दिया जाए तो इसमें अभी भी मेम्बर वर्ग द्वारा आवश्यक विधियों को शामिल करना चाहिए।

    Thsi तरीका यह विरासत से अधिक लचीला है। मैं एक ऐसी ही प्रश्न पूछा था कुछ समय पहले और एक अच्छा जवाब मिला:

    Elegant alternatives to the weird multiple inheritance

  • +1

    इसे और भी बेहतर बनाने के लिए, आप विधि के भीतर कक्षा को तुरंत चालू करने के बजाय निर्भरता इंजेक्शन का उपयोग कर सकते हैं। तो 'मेकडोनेशन (दान $ दान) {$ यह-> दान = $ दान; ... '। यह भी बेहतर है। लेकिन मैं सहमत हूं, हमेशा विरासत पर रचना का पक्ष लेते हैं ... – ircmaxell

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