- 基于接口而非基于实现编程的好处?
- 应用这条原则,可以将接口和实现相分离,封装不稳定的实现,暴露稳定的接口。上游系统面向接口而非实现编程,不依赖不稳定的实现细节,这样子,当实现发生变化的时候,上游系统的代码基本上不需要做改动,以此来降低耦合性,提高扩展性。
- 上面这样讲,可能很多人会有点懵,接下来举个例子来说:
- 假如现在你们公司有一个需求是要求你实现登录发短信功能,这时候,你想了一下,这不是很简单吗?那么就直接调用七牛云发短信的接口就好了,具体实现步骤是根据七牛云要求的参数,然后调用发短信的接口,最后根据返回的结果返回给前端失败还是成功,这时候,你创建了一个QiMsg的一个类去实现这个功能,然后定义了send的方法,方法里面是根据七牛云的文档来发短信,后面功能成功上线了,也用得很好。问题来了,后面你们老板觉得用七牛云太贵了,用阿里的平台会便宜很多,因此叫你改用对接阿里平台,你又写了一个AliMsg类和发短信send的方法,这时候你就比较头疼了,因为代码里面用到七牛云模块的导入和调用的地方都要去掉,改成导入阿里的模块和发短信的接口,这样无疑会增加系统的维护成本。其实,像这种情况,如果我们是基于接口而非基于具体实现编程,就不会有这样的问题了,话不多说,直接上代码。
class MessageTool(object):
"""发送短信类接口"""
def __init__(self, msg_way):
"""根据传入的类别调用具体的实现"""
if msg_way == 1:
self.msg = QiMsg()
elif msg_way == 2:
self.msg = AliMsg()
else:
pass
def send_msg(self):
self.msg.send()
class AliMsg(object):
"""阿里云发短信的具体实现类"""
def __init__(self):
pass
def send(self):
print('调用发短信接口')
class QiMsg(object):
"""七牛云发短信的具体实现类"""
def __init__(self):
pass
def send(self):
print('调用发短信接口')
if __name__ == '__main__':
mage = MessageTool(1) # 后面只需要改动改变这里的场景
mage.send_msg()
总结:从该例子可以看出,这样将接口类跟实现类分开的好处,就是后面如果要添加新的发送短信的对接平台的时候,我们只需要在接口类中添加新的场景,然后新的场景类只要实现自己发送短信的方法即可,这样子,改动其实是非常小的,也不会引入新的bug.