인스턴스 재구성 1: 중복 코드 제거

13447 단어 코드
먼저 장면을 묘사해 봅시다.
 
우리의 웹 프로젝트는 HTTP 프로토콜을 바탕으로 하는POST 인터페이스를 제공하여 제3자의 사용자에게 데이터를 쓰는 데 사용한다. 데이터를 쓰는 사람의 신분을 검증하기 위해 이런 인터페이스는 상대방에게 신분 표지를 전달하도록 요구할 것이다. 인터페이스가 표지를 받은 후에 쓴 사람의 표지를 검증하고 요청을 정확하게 집행하며 오류는 실패 정보를 되돌려준다. 같은 신분 검출 메커니즘을 바탕으로 모든 인터페이스가 똑같은 일을 했기 때문이다.코드에 나타나면 대량의 불필요한 코드가 있다. 만약에 불필요한 코드를 없애려면 나는 불필요한 코드를 하나의 함수로 써서 모든 인터페이스에서 호출할 수 있다. 그러면 대량의 반복적인 호출 문구도 있을 것이다. 느낌이 완벽하지 않다. 그래서 생각한 후에 OO를 빌려 이 일을 할 수 있다. 설명해야 할 것은 우리의 언어는python이고 웹 프로젝트가 사용하는 프레임워크는 웹py이다.
 
이전 코드 재구성
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의 코드는 실행되지 않는다.

좋은 웹페이지 즐겨찾기