zoukankan      html  css  js  c++  java
  • 软件开发规范

    软件开发规范

    为什么要有开发规范?

    ​ 软件开发,规范你的项目目录结构,代码规范,遵循PEP8规范等,使开发更合理,清晰.可读性高,可维护性高.

    ​ 将代码分类后,加载速度快,可读性高,查询修改简单.

    以博客园系统为例,将在一个py文件中的所有代码,整合成规范的开发.
    
    status_dic = {
        'username': None,
        'status': False,
    }
    flag = True
    
    
    def login():
        i = 0
        with open("register", encoding='utf-8') as f1:
            dic = {i.strip().split('|')[0]: i.strip().split('|')[1] for i in f1}
        while i < 3:
            username = input('请输入用户名:').strip()
            password = input('请输入密码:').strip()
            if username in dic and dic[username] == password:
                print('登录成功')
                return True
            else:
                print('用户名密码错误,请重新登录')
                i += 1
    
    
    def register():
        with open("register", encoding='utf-8') as f1:
            dic = {i.strip().split('|')[0]: i.strip().split('|')[1] for i in f1}
        while 1:
            print('33[1;45m 欢迎来到注册页面 33[0m')
            username = input('请输入用户名:').strip()
            if not username.isalnum():
                print('33[1;31;0m 用户名有非法字符,请重新输入 33[0m')
                continue
            if username in dic:
                print('33[1;31;0m 用户名已经存在,请重新输入 33[0m')
                continue
            password = input('请输入密码:').strip()
            if 6 <= len(password) <= 14:
                with open("register", encoding='utf-8', mode='a') as f1:
                    f1.write(f'
    {username}|{password}')
                status_dic['username'] = str(username)
                status_dic['status'] = True
                print('33[1;32;0m 恭喜您,注册成功!已帮您成功登录~ 33[0m')
                return True
            else:
                print('33[1;31;0m 密码长度超出范围,请重新输入 33[0m')
    
    
    def auth(func):
        def inner(*args, **kwargs):
            if status_dic['status']:
                ret = func(*args, **kwargs)
                return ret
            else:
                print('33[1;31;0m 请先进行登录 33[0m')
                if login():
                    ret = func(*args, **kwargs)
                    return ret
        
        return inner
    
    
    @auth
    def article():
        print(f'33[1;32;0m 欢迎{status_dic["username"]}访问文章页面33[0m')
    
    
    @auth
    def diary():
        print(f'33[1;32;0m 欢迎{status_dic["username"]}访问日记页面33[0m')
    
    
    @auth
    def comment():
        print(f'33[1;32;0m 欢迎{status_dic["username"]}访问评论页面33[0m')
    
    
    @auth
    def enshrine():
        print(f'33[1;32;0m 欢迎{status_dic["username"]}访问收藏页面33[0m')
    
    
    def login_out():
        status_dic['username'] = None
        status_dic['status'] = False
        print('33[1;32;0m 注销成功 33[0m')
    
    
    def exit_program():
        global flag
        flag = False
        return flag
    
    
    choice_dict = {
        1: login,
        2: register,
        3: article,
        4: diary,
        5: comment,
        6: enshrine,
        7: login_out,
        8: exit_program,
    }
    
    def run():
        while flag:
            print('''
            欢迎来到博客园首页
            1:请登录
            2:请注册
            3:文章页面
            4:日记页面
            5:评论页面
            6:收藏页面
            7:注销
            8:退出程序''')
    
            choice = input('请输入您选择的序号:').strip()
            if choice.isdigit():
                choice = int(choice)
                if 0 < choice <= len(choice_dict):
                    choice_dict[choice]()
                else:
                    print('33[1;31;0m 您输入的超出范围,请重新输入 33[0m')
    
            else:
                print('33[1;31;0m 您您输入的选项有非法字符,请重新输入 33[0m')
    run()        
            
            
    每一个函数都是一个具体的功能,一个文件中功能越多,代码越冗余,应该将这些函数进行分类然后分文件而治.
    具体划分如下:
    1.划归固定路径
    如代码中的"register"注册表文件,使相对路径,如果路径改变,则程序中用到的地方都需要一一更改,所以应该统一相同的变量,在文件的最上面写一个变量指向register注册表的路径,代码中如果需要这个路径时,直接引用即可.
    
    REGISTER_PATH = r"C:python"register"
     with open(REGISTER_PATH, encoding='utf-8') as f1:    
       
    #将register注册表的路径赋给变量,用到这个文件时直接引用这一变量. 
    
    2.划分文件
    
    settings.py:
        #配置文件,存放一些项目中需要的静态参数,比如路径,数据库的连接,配置等,一般在代码中只是引用不改变,基本上都是常量
    比如博客园系统中的:
        REGISTER_PATH = r"C:python"register"
        
    common.py:
        #公共组件文件,放置一些常用的公共组件函数,更像是服务于整个程序中的公用的插件,程序中需要即调用.
    比如我们程序中的装饰器auth,有些函数是需要这个装饰器认证的,但是有一些是不需要的,何处需要何处调用即可,密码加密,序列化功能,日志功能等都可以存放在这里
    比如博客园系统中的:
        def auth(func):
        def inner(*args, **kwargs):
            if status_dic['status']:
                ret = func(*args, **kwargs)
                return ret
            else:
                print('33[1;31;0m 请先进行登录 33[0m')
                if login():
                    ret = func(*args, **kwargs)
                    return ret
        
        return inner
    
    src.py:
        #主要存放核心逻辑功能,即主逻辑函数,核心函数,是直接可以体现出来的,贯穿整个项目的主要功能.
    比如博客园系统中的:
    @auth
    def article():...
    @auth
    def diary():...
    @auth
    def comment():...
    @auth
    def enshrine():...
    def login_out():...
    def exit_program():...
        
    start.py:
        #项目启动文件,将开启项目的功能单独放置到一个文件中,开启项目方便,醒目.
    比如博客园系统中的:
        run()
        
    类似register文件:
        #这种文件是存储数据的文件,类似于文本数据库,一些项目中的数据有的是从数据库中获取到,有些数据就是这种文本数据库中获取的,总之,会遇到将一些数据存储在文件中,与程序交互的情况,所以要单独设置这样的文件.
        
    log文件:
        #log文件就是存储log日志的文件,日志主要是供开发人员使用,可以记录用户的一些操作(停留时间,浏览信息等),,以及项目中的一些bug问题,以便开发者浏览查询.
        
    形成以下目录:
        
    |-- blog
    |   |-- settings.py
    |  |-- start.py
    |   |-- src.py
    |   |-- common.py
    |   |-- register.txt
    |   |-- access.log
    |
    

    划分具体目录

    上面的博客园系统只是较为简单的程序,如果src主逻辑函数很多,则需要划分为src1.py,src2.py等,文本数据库register只是一个注册表,如果还有个人信息表,记录表等,则项目会比较凌乱,所以需要设计项目目录结构.
    
    为什么要设计项目目录结构?
    设计一个层次清晰的目录结构,是为了达到:
    1.可读性高:不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪,配置文件在哪等等,从而非常快速的了解这个项目.
    2.可维护性高:定义好组织规则后,维护者就能很明确的知道,新增的哪个文件和代码应该放在什么目录之下,好处是随着时间的推移,代码/配置的规模增加,项目结构不会混乱,仍然能够组织良好.
    
    博客园的目录结构可以如下
    blog
    |-- bin
    |  |-- start.py
    |-- conf
    |   |-- settings.py
    |-- core
    |   |-- src.py
    |-- db
    |   |-- register
    |-- lib
    |   |-- common.py
    |-- log
    |   |--access.log
    |-- README
    
    关于README:
    每一个项目都应该有的文件,目的是能简要描述该项目的信息,让读者快速了解这个项目.
    它需要说明以下几个事项:
    1.软件定位,软件的基本功能
    2.运行代码的方法:安装环境,启动命令等
    3.简要的使用说明
    4.代码目录结构说明,更详细点可以说明软件的基本原理
    5.常见问题说明
    
    
    

    实例演示:

    博客园的目录结构可以如下
    blog
    |-- bin
    |  |-- start.py
    |-- conf
    |   |-- settings.py
    |-- core
    |   |-- src.py
    |-- db
    |   |-- register
    |-- lib
    |   |-- common.py
    |-- log
    |   |--access.log
    |-- README
    
    
    -配置start.py文件,首先需要手动将整个项目的工作路径添加到sys.path中,即将blog项目的工作目录添加到sys.path中,这样无论项目下的任意一个文件引用项目中哪个文件,都可以找到.但是项目是共同开发的,所以文件路径还需要动态获取.即:
    
    import sys
    import os
    BASE.DIR = os.path.dirname(os.path.dirname(__file__))
    #获取到了本文件的父级的父级,也就是项目的根目录
    sys.path.append(BASE.DIR)
    from core.src import run
    run()
    if __name__ == '__main__':
        run()
    #__file__ 获取本文件的绝对路径
    #os.path.dirname() 获取父级目录
    #作为启动文件不可以被别人引用启动,所以要用到__name__
    
    
    -配置settings.py文件,需要将项目中的静态路径,数据库的连接设置等等文件放置在settings文件中,settings文件也叫做配置静态文件,所以只需要把register_path放进去即可.
    
    
    import os
    BASE_PATH = os.path.dirname(os.path.dirname(__file__))
    REGISTER_PATH = os.path.join(BASE_PATH,"db","register")
    
    
    -配置common.py文件,在本项目中,装饰器就是公共组件的工具,除了将auth装饰器代码剪切到common.py文件中,还需要引入src.py文件中需要用到的变量,装饰器中的引用其他模块中的变量也需要前缀模块名
    
    from core import src
    
    
    -配置src.py文件,需要引用settings.py文件中register的路径和auth装饰器,src中的auth要变成common.auth,regis
    ter的路径引用其他模块中的变量也需要前缀模块名
    
    from conf import settings
    from lib import common 
    
    
    这样的话,博客园项目按照规范化目录就合理的完善完成了.
    
  • 相关阅读:
    Moving Price and Standard Price
    Partner function解析
    [ABAP] ABAP中定义和呼叫宏
    ABAP
    Words Learning~~(1-3)
    Words Learning~~(1-2)
    Words Learning~~(1-1)
    SQLSERVER如何查看索引缺失
    Material Stock manage T-code
    远程重启
  • 原文地址:https://www.cnblogs.com/tutougold/p/11284718.html
Copyright © 2011-2022 走看看