代码重构实例:消除冗余代码

开发 架构
这里我们会给出一个WEB开发项目的代码实例,采用的框架是webpy,语言是Python。后面会给大家看到重构之后的代码样例。

我们的Web项目提供了若干个基于HTTP协议的POST接口,用于给第三方的用户写入数据,为了验证写入数据者的身份,这样的接口肯定会要求对方传递身份标识,接口得到标识以后会验证写入者的标识,正确就执行请求,错误就返回失败信息,由于是基于同样的检测身份的机制,每个接口都做了同样的事情,体现在代码里就有大量的冗余代码,如果要消除冗余代码,我可以把冗余代码写成一个函数,在每一个接口里调用,这样的话,也会有大量重复的调用语句,感觉还是不完美,于是思考之后还是借助OO来做这个事情,需要说明的是,我们的语言是python,web项目采用的框架是webpy。

 
重构之前的代码
 
class Apply:
    def POST(self):
        try:
            wi = web.input()
            token = wi.token
            projectId = wi.projectId
            serverToken = getServerToken(db,token)
            if serverToken == None:
                return '{"result":"error","message":"token is error"}'
            
            if checkExpires(serverToken):
                return '{"result":"error","message":"token is expires"}'
            
            userId = serverToken.userId
            result = create.joinProject(userId,int(projectId))
            if result[0] == True:
                return '{"result":"ok","message":"ok"}'
            else:
                return '{"result":"error","message":"%s"}' %(result[1])
        except:
            if DEBUG:
                raise
            return '{"result":"error","message":""}'
    
class AddFolder:
    def POST(self):
        try:
            wi = web.input()
            token = wi.token
            serverToken = getServerToken(db,token)
            if serverToken == None:
                return '{"result":"error","message":"token is error"}'
            if checkExpires(serverToken):
                return '{"result":"error","message":"token is expires"}'
            
            userId = serverToken.userId
            folderName = wi.folderName
            pFolderId = int(wi.pFolderId) if hasattr(wi,"pFolderId") else 0
            projectId = util.unhash17(int(wi.projectId)) if hasattr(wi,"projectId") else 0
            
            folderId,deep,msg = tn.newFolder(db,folderName,userId,pFolderId,0,projectId)
            if folderId > 0:
                return '{"result":"ok","message":"%s","folderId":"%s","deep":"%s"}' %(msg,folderId,deep)
            else:
                return '{"result":"error","message":"%s","folderId":"%s","deep":"%s"}' %(msg,folderId,deep) 
        except:
            if DEBUG:
                raise
            return '{"result":"error","message":""}'    
 
我从代码里挑了两个API来展现代码冗余的情况,这两个API里做了很多一样的事情,例如使用用户传过来的token(身份标识)去系统查询(getServerToken调用)一旦不匹配告诉用户token is error,然后继续检查token是否超时,最后,整个代码是包含在try-catch块中,一旦有意外的事情(例如BUG)发生,需要返回错误信息给用户,只有每个API中间一块的处理代码是不一样的,这还是两个API,实际上整个功能模块至少有十几个API,而且还会继续增加,那么这种情况下,API越多则冗余代码越多,并且一旦需要修改就很痛苦,例如,每个catch块原来就是return出错误信息,结果后来要求给模块增加调试状态,在打开调试的时候返回异常信息用于调试,上线时异常时则只能返回规矩的JSON字符串给用户
 
重构以后
 
class OpenApiBase:
    def __init__(self):
        self.funPOST = self.POST
        self.POST = self.post
    
    def post(self):
        try:
            wi =  web.input()
            token = wi.token
            self.serverToken = getServerToken(db,token)
            
            web.debug(str(self.serverToken))
            
            if self.serverToken == False:
                return '{"result":"error","message":"token is error"}'
 
            if checkExpires(self.serverToken):
                return '{"result":"error","message":"token is expires"}'
 
            #执行每个子类具体的代码
            return self.funPOST()
        except:
            if DEBUG:
                raise
            return '{"result":"error","message":""}'
 
class Apply(OpenApiBase):#继承OpenApiBase
    def POST(self):
        wi = web.input()
        projectId = wi.projectId
        
        userId = self.serverToken.userId
        result = create.joinProject(userId,int(projectId))
        if result[0] == True:
            return '{"result":"ok","message":"ok"}'
        else:
            return '{"result":"error","message":"%s"}' %(result[1])
    
class AddFolder(OpenApiBase):#继承OpenApiBase
    def POST(self):
        wi = web.input()
        
        userId = self.serverToken.userId
        folderName = wi.folderName
        pFolderId = int(wi.pFolderId) if hasattr(wi,"pFolderId") else 0
        projectId = util.unhash17(int(wi.projectId)) if hasattr(wi,"projectId") else 0
        
        folderId,deep,msg = tn.newFolder(db,folderName,userId,pFolderId,0,projectId)
        if folderId > 0:
            return '{"result":"ok","message":"%s","folderId":"%s","deep":"%s"}' %(msg,folderId,deep)
        else:
            return '{"result":"error","message":"%s","folderId":"%s","deep":"%s"}' %(msg,folderId,deep) 
 
重构以后,每个子类的POST函数只做自己应该处理的事情,对于身份的检测全部交给父类完成,一旦没通过身份检测,子类POST里的代码根本就不会被执行
责任编辑:彭凡 来源: 博客园
相关推荐

2013-09-05 09:50:11

C++代码优化

2020-11-10 08:54:55

Lombok

2018-08-24 21:25:02

编程语言代码重构GitHub

2011-09-05 10:30:51

重构代码库业务模型

2021-08-03 08:13:48

重构API代码

2019-04-03 08:10:17

代码架构信息

2022-12-26 00:02:24

重构代码软件

2010-04-13 08:49:08

JavaLombokJavabean

2022-08-01 23:45:23

代码识别项目

2022-07-04 07:37:51

模板模式重构

2022-08-02 08:07:24

单元测试代码重构

2013-10-21 17:54:00

代码重构修改

2024-02-22 10:27:00

Python开发

2015-08-11 09:39:25

重构提高代码质量

2019-02-18 16:21:47

华为代码重构

2021-09-03 23:01:58

CSS 技巧代码重构

2011-08-16 09:47:58

编程

2021-05-26 08:50:37

JavaScript代码重构函数

2009-09-23 10:28:49

使用Hibernate

2015-08-17 10:42:13

点赞
收藏

51CTO技术栈公众号