软件开发规范

时间:2021-08-30 09:05:57

软件开发规范

为什么要有开发规范?

​ 软件开发,规范你的项目目录结构,代码规范,遵循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('\033[1;45m 欢迎来到注册页面 \033[0m')
        username = input('请输入用户名:').strip()
        if not username.isalnum():
            print('\033[1;31;0m 用户名有非法字符,请重新输入 \033[0m')
            continue
        if username in dic:
            print('\033[1;31;0m 用户名已经存在,请重新输入 \033[0m')
            continue
        password = input('请输入密码:').strip()
        if 6 <= len(password) <= 14:
            with open("register", encoding='utf-8', mode='a') as f1:
                f1.write(f'\n{username}|{password}')
            status_dic['username'] = str(username)
            status_dic['status'] = True
            print('\033[1;32;0m 恭喜您,注册成功!已帮您成功登录~ \033[0m')
            return True
        else:
            print('\033[1;31;0m 密码长度超出范围,请重新输入 \033[0m')


def auth(func):
    def inner(*args, **kwargs):
        if status_dic['status']:
            ret = func(*args, **kwargs)
            return ret
        else:
            print('\033[1;31;0m 请先进行登录 \033[0m')
            if login():
                ret = func(*args, **kwargs)
                return ret
    
    return inner


@auth
def article():
    print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问文章页面\033[0m')


@auth
def diary():
    print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问日记页面\033[0m')


@auth
def comment():
    print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问评论页面\033[0m')


@auth
def enshrine():
    print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问收藏页面\033[0m')


def login_out():
    status_dic['username'] = None
    status_dic['status'] = False
    print('\033[1;32;0m 注销成功 \033[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('\033[1;31;0m 您输入的超出范围,请重新输入 \033[0m')

        else:
            print('\033[1;31;0m 您您输入的选项有非法字符,请重新输入 \033[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('\033[1;31;0m 请先进行登录 \033[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 


这样的话,博客园项目按照规范化目录就合理的完善完成了.