2011-04-25 82 views
4

我有興趣爲我正在使用的第三方API編寫庫,我需要一些建議。在一次請求中,圖書館的平均使用將涉及幾個API調用。例如,一次api呼叫從第三方服務中獲取用戶,然後再次呼叫以使用該用戶獲取他/她的照片。每個API調用都會得到自己的庫方法包裝器,其中包含額外的邏輯來處理錯誤/超時,但是我最大的問題是庫是應該作爲一個包含狀態的單例還是一系列的類方法來完成。在庫中包裝第三方服務的最佳實踐

例如:

user_id = ThirdParty.get_user("[email protected]") 
photos = ThirdParty.get_photos(user_id) 

OR

thirdpartyservice = ThirdPartyService.new("[email protected]") 
photos = thirdpartyservice.get_photos 

這些並不一定是該庫的確切deseign,但我只是感到困惑的每一種方法的優點/缺點。任何幫助將是驚人的!

順便說一句,我使用紅寶石!

+1

對於與將庫設置爲單例有關的問題,最好將它作爲靜態方法使用靜態方法,因爲我知道不需要維護庫類的狀態。 – 2011-04-25 15:37:01

回答

4

我會讓庫包含狀態,因爲這樣可以減少用戶端代碼的複雜性(這就是API應該做的事情,增加簡單性)。通過這種方法,用戶不必跟蹤該user_id,因爲該庫正在保持這種狀態。

如果用戶真的想要他們的user_id(或者庫存儲的任何其他數據),那麼您可以在庫中創建一個attr_reader來公開該數據。

要爲get_photos方法添加fleixiblity,你可以這樣做:

class ThirdPartyService 

    def get_photos([email protected]_stored_in_library) 
    # do work 
    end 

end 

這樣,它默認爲存儲的ID,但是這在增加了靈活性,用戶可以指定用戶ID,如果他這樣選擇。

0

而不是get_set_方法會更好地使用getter和setter。這是紅寶石標準(不確定,但get_和set_方法,我只看到一次在紅寶石代碼)。

如果您不需要在請求之間保存某些狀態,請將其設置爲靜態。但這取決於很多因素。你能告訴我們你需要包裝什麼API嗎?

2

你需要狀態(主機等)和基於該狀態的行爲,所以你應該使用對象,而不是一個單例對象。

如上所述,您不應該使用像get_photos這樣的方法,只需要photos

+0

我同意命名標準。就主機等而言,所有這些信息都是不變的。主機和oauth令牌信息對於每個呼叫都是相同的。你仍然認爲我不應該使用單身? – Danny 2011-04-25 17:27:57

+0

是的。 (一些填充) – 2011-04-25 18:55:52

1

我相信最好的做法是使用提供者和服務來實現不受限於特定服務提供者的能力。您可能不想簡單地將庫抽象化,而是默認只允許單個服務提供者。

雖然動態/鴨類型的語言(如Ruby)並不需要繼承,但這可能有助於具體說明「爲什麼」。

class MailProvider 

    def initialize(args); raise "Not Implemented"; end 

    def send_mail(args); raise "Not Implemented"; end 

end 

class SendGridService < MailProvider 

    def initialize(args) 
    # Use args here 
    end 

    def send_mail(args) 
    # Use SendGrid's API or Gem here 
    end 

end 

然後,在你的代碼,你可以有這樣的事情:

config.mail_provider = SendGridService.new({ 
    username: ENV['SENDGRID_USERNAME'], 
    password: ENV['SENDGRID_PASSWORD'] 
}) 

config.mail_provider.send_mail({ subject: 'woot', message: 'Look ma, I did it!' }) 

在六個月後,當你的用戶喜歡你的寶石/庫,但要MailChimp的支持,你可以簡單地創建第二個服務「 MailChimpService「,並允許您的客戶使用新的提供商。