工厂模式
打造工厂模式,需要抽象工厂和具体工厂。怎么理解?抽象工厂就是接口的定义,但不负责具体的实现。而具体工厂则需要负责定义的接口的实现。就好比你爸爸让你上街时带一瓶酱油,而具体买什么牌子的由你决定。”你爸爸让带一瓶酱油“就是接口的定义函数,这个函数只负责定义”要求“,而不负责实现,而实现是由你来做的,那你就是具体工厂、你爸爸就是抽象工厂。简单理解抽象工厂是提要求的人(其实代码里就是类class),具体工厂就是实现”要求“的人(代码类class)。
工厂模式的实现
我们现在有个任务,需要你完成一个get、post方法,进行数据和发送和接受。另外需要覆盖http、websocket、tcp三种协议。我们首先要明白虽然同样是发送数据、接受数据,但是要知道三种协议的实现方式有很大不同。如果实现都相同,也就不会产生三种协议了,对吧?
猛一听这个要求,是不是下意识觉得很困难。需要同时为http、websocket、tcp三种协议实现get、post方法,你可能会被困难吓住。而我要告诉你,实现这个一点都不难,我们使用工厂方法,对这个任务进行分解并设计,把大的困难,分解为一个个小任务,就简单了。下面我们开始做。
根据工厂模式,我们需要在具体实现前面,先去定义要求。我们的要求一共有两个,实现get、post。知道了要求,我们还知道定义要求是在抽象工厂里实现的。那就先写抽象工厂类,再把要求写到抽象工厂类里面,就算完成了。
from abc import ABCMeta, abstractmethod
#继承了metaclass=ABCMeta的类就会被python认定为抽象类
class Protocol(metaclass=ABCMeta):
"""@abstractmethod用来定义抽象方法,如果没有装饰符,那就是一个普通方法。
为啥这么安排呢,这是因为一旦使用了@abstractmethod,在接下来的具体工厂里
这个方法就会被强制要求实现,如果你不实现就会python报错。就像你不给你爸爸
买酱油,就会挨打一样"""
@abstractmethod
def post(self, body):
'''发送请求的接口'''
#注意抽象方法不需要具体去实现,具体实现是在具体方法里完成,所以这里pass即可
pass
@abstractmethod
def get(self):
'''获取数据的接口'''
pass
有了抽象工厂后,接下来我们就来实现具体工厂。即把post、get实现,使其真正能够发送和接受数据。
import requests
import socket
#http协议
#继承了抽象工厂Protocol,我们在实现具体方法时,必须要实现post、get,否则报错!
class HttpProtocol(Protocol):
def __init__(self, ip):
self._ip = ip
def post(self,body):
http.request('POST', url, body=json.dumps(body))
def get(self):
http.get('get', url)
#websocket协议
#继承了抽象工厂Protocol,我们在实现具体方法时,必须要实现post、get,否则报错!
class WebSocketProtocol(Protocol):
def __init__(self, ip):
self._ip = ip
def post(self, body):
if 'requestUrl' not in body:
print('requestUrl is needed for WebSocket request')
return False
with self._ws_mutex:
self._requests.append(json.dumps(body))
print('已经发送: {}'.format(json.dumps(body)))
return self.get_data()
def get(self):
data = self.sock.recv(4090)
return data
#tcp协议
#继承了抽象工厂Protocol,我们在实现具体方法时,必须要实现post、get,否则报错!
class TcpProtocol(Protocol):
def __init__(self, ip):
self._ip = ip
def post(self, body):
try:
time.sleep(5)
self.sock.send(body)
print('已经发送: {}'.format(body))
finally:
pass
def get(self): '
data = self.sock.recv(4090)
return data
到此具体工厂已经实现了,我们可以使用HttpProtocol(ip).post(body)等去调用post、get方法了,调用时,根据具体的协议选择具体工厂,如果你需要用websocket协议进行收发,请用WebSocketProtocol(ip).post(body)。灵活使用。为了更加贴近实际的使用场景,我们对客户端代码,也使用工厂模式进行设计一下,看到这里我想我不用写,你也会设计了吧。不过为了照顾到大多数人,我还是写一下示例。
客户端针对不同的ip进行连接
#客户端抽象工厂
class TransportationFactory(metaclass=ABCMeta):
'''传输层连接到ip'''
#这里定义connect方法,以便符合实际场景
@abstractmethod
def connect(self,ip):
'''连接到ip'''
pass
#客户端具体工厂
class HttpTransportation(TransportationFactory):
def connect(self,ip):
return HttpProtocol(ip)
class WebSocketTransportation(TransportationFactory):
def connect(self,ip):
return WebSocketProtocol(ip)
class TcpTransportation(TransportationFactory):
def connect(self,ip):
return TcpProtocol(ip)
#具体使用方式
t_http = HttpTransportation().connect("192.168.1.10")
t_websocket = WebSocketTransportation().connect("192.168.1.10")
t_tcp = TcpTransportation.().connect("192.168.1.10")
body ={
"services" : [ {
"service_id" : "serviceId",
"properties" : {
"Height" : 124,
"Speed" : 23.24
},
"event_time" : "2021-08-13T10:10:10.555Z"
} ]
}
t_http.post(body)
t_websocket.post(body)
t_tcp.post(body)
标签:body,get,python,ip,代码,工厂,post,self
From: https://www.cnblogs.com/hengchen/p/18347502