定义
Adapter_pattern,引自wiki,可能需要特殊手段打开。
代码片段
本文使用bottle框架0.4.10版本的代码做例子
class ServerAdapter(object):
def __init__(self, host='127.0.0.1', port=8080, **kargs):
self.host = host
self.port = int(port)
self.options = kargs
def __repr__(self):
return "%s (%s:%d)" % (self.__class__.__name__, self.host, self.port)
def run(self, handler):
pass
class WSGIRefServer(ServerAdapter):
def run(self, handler):
from wsgiref.simple_server import make_server
srv = make_server(self.host, self.port, handler)
srv.serve_forever()
class CherryPyServer(ServerAdapter):
def run(self, handler):
from cherrypy import wsgiserver
server = wsgiserver.CherryPyWSGIServer((self.host, self.port), handler)
server.start()
class FlupServer(ServerAdapter):
def run(self, handler):
from flup.server.fcgi import WSGIServer
WSGIServer(handler, bindAddress=(self.host, self.port)).run()
class PasteServer(ServerAdapter):
def run(self, handler):
from paste import httpserver
from paste.translogger import TransLogger
app = TransLogger(handler)
httpserver.serve(app, host=self.host, port=str(self.port))
class FapwsServer(ServerAdapter):
""" Extreamly fast Webserver using libev (see http://william-os4y.livejournal.com/)
Experimental ... """
def run(self, handler):
import fapws._evwsgi as evwsgi
from fapws import base
import sys
evwsgi.start(self.host, self.port)
evwsgi.set_base_module(base)
def app(environ, start_response):
environ['wsgi.multiprocess'] = False
return handler(environ, start_response)
evwsgi.wsgi_cb(('',app))
evwsgi.run()
def run(server=WSGIRefServer, host='127.0.0.1', port=8080, optinmize = False, **kargs):
""" Runs bottle as a web server, using Python's built-in wsgiref implementation by default.
You may choose between WSGIRefServer, CherryPyServer, FlupServer and
PasteServer or write your own server adapter.
"""
global OPTIMIZER
OPTIMIZER = bool(optinmize)
quiet = bool('quiet' in kargs and kargs['quiet'])
# Instanciate server, if it is a class instead of an instance
if isinstance(server, type) and issubclass(server, ServerAdapter):
server = server(host=host, port=port, **kargs)
if not isinstance(server, ServerAdapter):
raise RuntimeError("Server must be a subclass of ServerAdapter")
if not quiet:
print ('Bottle server starting up (using %s)...' % repr(server))
print ('Listening on http://%s:%d/' % (server.host, server.port))
print ('Use Ctrl-C to quit.')
print()
try:
server.run(WSGIHandler)
except KeyboardInterrupt:
print ("Shuting down...")
总体的思路是:
- 实现基类
- 继承基类,并实现接口
- 将实现的类给真正的调用方
调用方的核心逻辑
def run(server=WSGIRefServer, host='127.0.0.1', port=8080, optinmize = False, **kargs):
try:
server.run(WSGIHandler)
except KeyboardInterrupt:
print ("Shuting down...")
可以看到,在bottle中,适配者模式起到了统一不同服务器的作用,虽然没有使用raise NotImplemented
或元类实现接口的的方法,但是确实是接口的玩法。