在这种情况下,此API的最佳设计是什么?

时间:2010-08-31 01:03:52

标签: design-patterns api oop

我正在构建一个API,将给定的消息发布到不同的平台(Twitter,FaceBook ...)。

问题是,对于每个平台,我可能会更改允许我发布消息的包装器。例如,在C#中,我可以使用yedda API或CsharpTwitt API在Twitter上发布消息,对于FaceBook,我将使用其他API ...

因此,我必须能够使用不同的包装器为每个平台发布消息。 alt text

目前,这是我使用的设计,但很明显,如果我添加更多包含更多包装的API,它将会过于复杂。

我认为这是一个常见的设计问题,我想知道

  1. 我使用最好的方法吗? 精心设计的API?
  2. 否则,这种情况的最佳设计是什么?
  3. 这里适用的设计模式是什么?

3 个答案:

答案 0 :(得分:3)

我喜欢这种方法,因为这样你可以依赖注入你想要的任何包装器并用一行代码改变它。

例如

Bind<Yedda>().To<ITwitter>();
Bind<FBWrapper>().To<IFacebook>();

现在整个代码ITwitter实际上映射到Yedda包装器。

依赖注入可能值得一看。

答案 1 :(得分:1)

如果你创建不同的消息包装器,你可以使用抽象工厂。

abstrcat class Abstractfactory{
       IBridge Create(int type);
}
class Platrofrm1facroty:Abstractfactory
{  
  //type m.b. for Wrapper1 to wrapperN 
  IBridge Create(int type);
}
class Twitterfacroty:Abstractfactory
{  
  //type m.b. for Yedda or CshartTwitt
  IBridge Create(int type);
}

答案 2 :(得分:0)

我不熟悉C#,但我可以提供一些python代码,希望内部的想法可能有用。

我将从客户端代码开始,以显示如何使用API​​:

# Client code
myapi = MyAPI()
# then call different methods :
message = "Some status"
# send to all platforms
myapi.broadcast(message)
# or
myapi.send_facebook(message) # send to fb only
myapi.send_twitter(message) # send to twitter only
# or
myapi.send("facebook",message) # another way of doing the same thing

现在实施:

# actual APIs
import FacebookAPI1 
import FacebookAPI2
...
import TwitterAPI1
import TwitterAPI2
...
# your individual wrappers, one for each API you want to use
# they all expose a send method
class FacebookAPI1Wrapper:
    def send(self,message):
        #use FacebookAPI1 functions

class FacebookAPI2Wrapper:
    def send(self,message):
        #use FacebookAPI2 functions

class TwitterAPI1Wrapper:
    def send(self,message):
        #use TwitterAPI1 functions

class TwitterAPI2Wrapper:
    def send(self,message):
        #use TwitterAPI2 functions

# Your API, this is the only class the client code needs.
class MyAPI:
      def __init__(self):
            # you decide internally what wrappers to use
            self.fb_api = FacebookAPI1Wrapper()                
            self.twitter_api = TwitterAPI2Wrapper()
            # No need for an intermediate level here I guess (Twitter and Platform_1 in your examples)
            # like : self.fb_api = Facebook() where Facebook chooses what wrapper to use internally (FacebookAPIWrapper)
            # it would just add unnecessary level of inderection.
            ... # other plateforms
            # hash-table-like structure, keys are plateform names, values are objects
            # this attribute is useful for the exposed send method where the first argument is a string
            # representing the name of the plateform the client wants to send a message to 
            self.plateforms = {"facebook" : self.fb_api,
                               "twitter"  : self.twitter_api
                               ...        : ...
                               }

      def broadcast(self,message):
            for plateform in self.plateforms.values() : #.values() will return the objects stored in the hash-table
                  plateform.send_message(message)

      def send_facebook(self,message):
            self.fb_api.send(message)

      def send_twitter(self,message):
            self.twitter_api.send(message)

      #...

      def send(self,plateform_name,message):
            # a simple hash table lookup
            platform = self.platforms.get(plateform_name)
            plateform.send(message)

只要保持相同的界面,内部更改代码(实现代码)就不会破坏客户端代码。