Reputation: 479
I'm building an API that post a given message to different platforms (Twitter, FaceBook...).
The problem is that for each platform I may change the wrapper that allow me to post the message. For example, in C# I can post a message on twitter using the yedda API or the CsharpTwitt API, for FaceBook I'll use others APIs...
Hence, I have to be able to use different wrappers to post a message for each platform.
For now, this is the design I use, but it's clear that it will be too complicated if I add more APIs with more wrappers.
I think it's a common design issue and I'm wondering
Upvotes: 4
Views: 189
Reputation: 5092
I'm not familiar with C#, but I can offer you some python code in the hope that the ideas inside may be useful.
I'll start with the client code, to show how the API is used :
# 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
Now the implementation :
# 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)
Changing your code internally (implementation code) won't break client code as long as you keep the same interface.
Upvotes: 0
Reputation: 7361
you may use abstract factory if your create different message wrappers.
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);
}
Upvotes: 1
Reputation: 12252
I like this approach because this way you can dependency inject whatever wrapper you wish and change it with a single line of code.
For example
Bind<Yedda>().To<ITwitter>();
Bind<FBWrapper>().To<IFacebook>();
And now throughout the code ITwitter
actually maps to the Yedda
wrapper.
Dependency injection could be something worthwhile to look at.
Upvotes: 3