I implemented a plugable framework like below.
It works but I’m confused about the implementation of Plugin2. Seems it uses a normal method instead of a class constructor.
Can I do so? Is there any cons?
Is it a normal-used ‘pattern’? If it is, what’s the pattern name? ‘Duck typing’? Should I avoid usage like this?
UPDATE: My concern is for below method:
def addPlugin(name, plugin)
Now parameter plugin could be either a Class or a Method. Then it is kind of obscure for the plugin developer. Is this a common case in dynamic programming language world?
class MyFramework(object):
_plugins = {}
_osType = None
@staticmethod
def addPlugin(name, plugin):
MyFramework._plugins[name]= plugin
def __init__(self, osType):
self._osType = osType
for name, plugin in MyFramework._plugins.items():
setattr(self, name, plugin(self, self._osType))
class Plugin1(object):
def __init__(self, owner, osType):
self.owner= owner
self.osType = osType
def hello(self):
print 'this is plugin1'
def Plugin2(owner, osType):
if (osType == "Linux"):
return Plugin2Linux(owner)
else:
return Plugin2Common(owner)
class Plugin2Linux(object):
def __init__(self, owner):
self.owner= owner
def hello(self):
print 'this is plugin2 Linux version'
class Plugin2Common(object):
def __init__(self, owner):
self.owner= owner
def hello(self):
print 'this is plugin2 common version'
MyFramework.addPlugin("plugin1", Plugin1)
MyFramework.addPlugin("plugin2", Plugin2)
framework = MyFramework("Linux")
plugin1 = getattr(framework, "plugin1")
plugin2 = getattr(framework, "plugin2")
plugin1.hello()
plugin2.hello()
This is an often-used pattern called a factory function. It’s a good idea to have your interface open to any callable that returns an object, whether the callable is a function or a class. It keeps you flexible for whatever you want to do in the future.