Python实战之ATM取款机的实现

作者:C_小米同学 时间:2023-04-23 08:40:25 

一、项目视图分析

Python实战之ATM取款机的实现

通过上图,我们可以看到,一个完整的项目,基本包括三个部分:用户视图层、接口层、数据处理层,其中,用户视图层是用来接收用户的数据输入的,比如:有户名,密码;接口层是要接收用户视图层传来的数据,然后做判断:名字是否存在、密码是否正确,这就要求接口层调用数据处理层的方法;数据处理层就需要接收接口层的参数,把接口层需要的增、删、改、查的数据结果返回给接口层,接口层再把判断的结果返回给用户层。

二、文件结构分析

Python实战之ATM取款机的实现

文件主要有以下几个部分:conf(setting.py-参数配置,比如:日志文件的配置、路径等)、core(src.py\admin.py-用户视图层,分为图通用户和管理员)、interface(接口层,里面有很多接口:用户接口,购物接口,银行接口,管理员接口,分这么细是为了“解耦合”)、db(用户数据存放;数据处理层:主要负责数据的增、删、改、查)、lib(公共方法:比如登录功能的装饰器)、log(日志文件)、readme(文档说明)、strat启动

三、完整代码

1.start.py

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/02 14:59
@Author  : Rice
@CSDN : C_小米同学
@FileName: start.py
'''
'''
程序的入口
'''
import sys
import os

#添加解释器的环境变量
sys.path.append(
   os.path.dirname(__file__)
)

#导入用户视图层
from core import src
# 开始执行项目函数

if __name__ == '__main__':
   # 1.先执行用户视图层
   src.run()

2.conf

-settings.py

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/02 14:49
@Author  : Rice
@CSDN : C_小米同学
@FileName: settings.py
'''
'''
存放配置信息
'''
import os

#获取项目根目录路劲
BASE_PATH = os.path.dirname(
   os.path.dirname(__file__)
)

# 获取user_data文件夹目录路径
USER_DATA_PATH = os.path.abspath(os.path.join(BASE_PATH, 'db','user_data'))
#USER_DATA_PATH2 = os.path.join(BASE_PATH, 'db','user_data').replace('\\','/')
username = 'rice'
user_path = os.path.abspath(os.path.join(USER_DATA_PATH, f'{username}.json')).replace('\\','/')

"""
logging配置
"""
BASE_PATH2 = os.path.dirname(os.path.dirname(__file__))
logfile_dir = os.path.abspath(os.path.join(BASE_PATH2,'log')).replace('\\','/')
logfile_name = 'atm.log'

#如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
   os.mkdir(logfile_dir)

#log文件的全路径
logfile_path = os.path.join(logfile_dir, logfile_name).replace('\\','/')

standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                 '[%(levelname)s][%(message)s]'

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

test_format = '%(asctime)s] %(message)s'

# 3、日志配置字典
LOGGING_DIC = {
   'version': 1,
   'disable_existing_loggers': False,
   'formatters': {
       'standard': {
           'format': standard_format
       },
       'simple': {
           'format': simple_format
       },
   },
   'filters': {},
   'handlers': {
       # 打印到终端的日志
       'console': {
           'level': 'DEBUG',
           'class': 'logging.StreamHandler',  # 打印到屏幕
           'formatter': 'simple'
       },
       # 打印到文件的日志,收集info及以上的日志
       'default': {
           'level': 'DEBUG',
           'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,日志轮转
           'formatter': 'simple',
           # 可以定制日志文件路径
           # BASE_DIR = os.path.dirname(os.path.abspath(__file__))  # log文件的目录
           # LOG_PATH = os.path.join(BASE_DIR,'a1.log')
           'filename': logfile_path,  # 日志文件
           'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
           'backupCount': 5,
           'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
       },
   },
   'loggers': {
       # logging.getLogger(__name__)拿到的logger配置
       '': {
           'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
           'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
           'propagate': True,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
       },
   },
}

if __name__ == '__main__':

print(user_path)

3.core

-src.py

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/02 14:51
@Author  : Rice
@CSDN : C_小米同学
@FileName: src.py
'''
'''
用户视图层
'''

from interface import user_interface
from lib import common
from interface import bank_interface
from interface import shop_interface

#全局变量,记录用户是否已登录
login_user = None

# 1.注册功能
def register():
   while True:
       # 1)让用户输入用户名和密码校验
       username = input('请输入用户名:').strip()
       password = input('请输入密码:').strip()
       re_password = input('请确认密码:').strip()
       #可以输入自定义的金额

# 小的逻辑错误:比如两次密码是否一致
       if password == re_password:
           #2)调用接口层的注册接口,将用户名与密码交给接口层来进行处理

#一个元祖
           flag, msg = user_interface.register_interface(username, password)

# 3)根据flag判断用户注册是否成功,用于控制break
           if flag:
               print(msg)
               break
           else:
               print(msg)

# 2.登录功能
#成功登录了之后,一定会修改全局变量:login_user
def login():
   #登录视图
   while True:
       #1)让用户输入用户名和密码
       username = input('请输入用户名:').strip()
       password = input('请输入密码:').strip()

#2)调用接口层,将数据传给登录接口
       flag, msg = user_interface.login_interface(username, password)
       if flag:
           print(msg)
           global login_user
           login_user = username
           break
       else:
           print(msg)  #有一个小bug,输入错误后,我想返回主页  #d  #成功登录了#

# 3.查看余额
@common.login_auth
def check_balance():
   #1.直接调用查看余额接口,获取用户余额
   #装饰器本身是有login_user
   balance = user_interface.check_bal_interface(login_user)
   print(f'用户{login_user} 账户余额为:{balance}')

# 4.提现功能
@common.login_auth
def withdraw():
   while True:
       #1)让用户输入提现金额
       input_money = input('请输入提现金额:').strip()

#2)判断用户输入的金额是否是数字
       if not input_money.isdigit(): #isdigit()-可以判断字符串
           print('请输入')
           continue
       #3)用户提现金额,将数据提现的金额交给接口层处理
       flag, msg = bank_interface.withdraw_interface(login_user, input_money)
       if flag:
           print(msg)
           break

# 5.还款功能
@common.login_auth
def repay():
   '''
   银行卡还款,无论是信用卡或储蓄卡,是否能任意大小的金额
   :return:
   '''
   while True:
       #1) 让用户输入还款金额
       input_money = input('请输入需要还款的金额:').strip()
       #2)判断用户输入的是否是数字
       if not input_money.isdigit():
           print('请输入正确的金额')
           continue
       input_money = int(input_money)
       #3)判断用户输入的金额大于0
       if input_money > 0:
           #4)调用还款接口
           flag, msg = bank_interface.repay_interface(login_user, input_money)
           if flag:
               print(msg)
               break
       else:
           print('输入的金额不能小于0')

# 6.转账功能
@common.login_auth
def transfer():
   '''
   1.接收 用户输入的 转账金额
   2.接收用户输入的 转账目标用户
   :return:
   '''
   while True:

#1) 让用户输入转账用户与金额
       to_user = input('请输入转账目标用户').strip()
       money = input('请输入转账金额').strip()

#2)数据判断
       if not money.isdigit():
           print('请输入数字')
           continue
       money = int(money)
       if money > 0:
           #调用转账接口
           flag, msg = bank_interface.transfer_interface(
               login_user,to_user,money
           )
           if flag:
               print(msg)
               break
           else:
               print(msg)
       else:
           print('请输入正确的金额')

# 7.查看流水
@common.login_auth
def check_flow():
   #直接调用查看流水接口
   flow_list = bank_interface.check_flow_interface(login_user)
   if flow_list:
       for flow in flow_list:
           print(flow)
   else:
       print('当前用户没有流水!')

# 8.购物功能
@common.login_auth
def shop():
   #不从文件中读取商品数据,直接写
   #创建商品列表
   # shop_list = {
   #     '0': {'name': '包子', 'price': 30}
   # }
   shop_list = [
       ['包子',  3], #0
       ['可乐', 5], #1
       ['book', 200],
       ['pc', 9999],
   ]
   #初始化当前购物车
   shopping_car = {}  #{'商品名称':['单价','数量']]}
   while True:
       #枚举:enumerate(可迭代对象)--->元祖(可迭代对象的索引,索引对应的值)
       for index, shop in enumerate(shop_list):
           shop_name, shop_price = shop
           print(f'商品编号为{index}, 商品名称{shop_name}, 商品单价:{shop_price}')
           print(shop)
       choice = input('请输入商品编号:(是否结账输入y or n)').strip()
       #让用户根据商品编号进行选择

#输入的是y进行支付结算功能
       if choice == 'y':
           if not shopping_car:
               print('购物车是空的,不能支付,请重新输入')
               continue
           #调用支付接口进行支付
           flag, msg = shop_interface.shopping_interface(login_user,shopping_car)
           if flag:
               print(msg)
               break
           else:
               print(msg)
       #输入的是n添加购物车(把shopping_car添加到json中)
       elif choice == 'n':
           #调用添加购物车接口
           if not shopping_car:
               print('购物车是空的,不能添加,请重新输入')
               continue
           flag, msg = shop_interface.add_shop_car_interface(login_user, shopping_car)
           if flag:
               print(msg)
               break
           else:
               print(msg)
       if not choice.isdigit():
           print('请输入正确的编号!')
           continue

if not choice.isdigit():
           print('请输入正确的编号!')
           continue
       choice = int(choice)

if choice not in range(len(shop_list)):
           print('请输入正确的编号!')
           continue
       shop_name, shop_price = shop_list[choice]

#加入购物车
       #判断用户选择的商品是否重复,重复加1
       if shop_name in shopping_car:
           #添加商品数量
           shopping_car[shop_name][1] += 1
       else:
           #否则数量默认为1
           shopping_car[shop_name] = [shop_price, 1]

# 9.查看购物车
@common.login_auth
def check_shop_car():
   shop_car = shop_interface.check_shop_car_interface(login_user)
   print(shop_car)

# 10.管理员功能
@common.login_auth
def admin():
   '''
   管理员功能:课后作业
   :return:
   '''
   from core import admin
   admin.admin_run()

# 创建函数功能字典
func_dic = {
   '1': register,
   '2': login,
   '3': check_balance,
   '4': withdraw,
   '5': repay,
   '6': transfer,
   '7': check_flow,
   '8': shop,
   '9': check_shop_car,
   '10': admin
}

# 视图层主程序
def run():
   while True:
       print('''
       ======= ATM + 购物车 =======
           1.注册功能
           2.登录功能
           3.查看余额
           4.提现功能
           5.还款功能
           6.转账功能
           7.查看流水
           8.购物功能
           9.查看购物车
           10.管理员功能
       ========== end ============
       ''')
       choice = input('请输入功能编号:').strip()
       if choice not in func_dic:
           print('请输入正确的功能编号!')
           continue
       func_dic.get(choice)()

-admin.py

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/04 11:50
@Author  : Rice
@CSDN : C_小米同学
@FileName: admin.py
'''
from core import src
from interface import admin_interface
# 添加用户
def add_user():
   src.register()

# 修改用户额度
def change_balance():
   while True:
       change_user = input('请输入需要修改额度的用户').strip()

money = input('请输入需要修改的用户额度:').strip()
       if not money.isdigit():
           print('请输入数字')
           continue

flag, msg = admin_interface.change_balance_interface(change_user, money)
       if flag:
           print(msg)
           break
       else:
           print(msg)
           break

# 输入修改额度
# 输入修改用户
# 调用修改额度接口

# 冻结账户
def lock_user():
   while True:
       change_user = input('请输入需要修改额度的用户:').strip()

flag, msg = admin_interface.lock_user_interface(change_user)
       if flag:
           print(msg)
           break
       else:
           print(msg)
           break

# 管理员功能字典
admin_dic = {
   '1': add_user,
   '2': change_balance,
   '3': lock_user
}

def admin_run():
   while True:
       print('''
          1、添加用户
          2、修改额度
          3、冻结账户
          ''')
       choice = input('请输入管理员功能编号:').strip()

# 判断功能编号是否存在
       if choice not in admin_dic:
           print('请输入正确的功能编号!')
           continue

# 调用用于选择的功能函数
       admin_dic.get(choice)()

4.interface

 -user_interface.py

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/02 14:52
@Author  : Rice
@CSDN : C_小米同学
@FileName: user_interface.py
'''
'''
逻辑接口层
   用户接口
'''

import json
import os
from conf import settings
from db import db_handler
from lib import common
user_logger = common.get_logger('user')
#user_logger.setLevel(10)
#注册接口
def register_interface(username, password, balance=5000):
   # 2)查看用户是否存在
   #2.1)调用 数据处理层中的select函数,会返回用户字典或None
   user_dic = db_handler.select(username)

#若用户存在,则return,告诉用户重新输入(是通过用户名来判断是否存在的,跟密码没关系)
   if user_dic:
       return False, '用户名已存在!'

#3)用户不存在,则保存用户数据
   #做密码加密
   password = common.get_pwd_md5(password)
   user_dic = {
       'username': username,
       'password': password,
       'balance': balance,
       # 用于记录用户流水的列表
       'flow': [],
       # 用于记录用户购物车
       'shop_car': {},
       # locked: 用于记录用户是否被冻结
       # False:未冻结 True:已冻结
       'locked': False
   }

#3.2)保存数据

db_handler.save(user_dic)
   msg = f'{username} 用户注册成功'
   #记录日志
   user_logger.info(msg)
   return True, msg

#登录接口
def login_interface(username, password):

#1)先查看当前用户数据是否存在

user_dic = db_handler.select(username)
   #2)判断用户是否存在

#若有冻结用户,则需要判断是否被锁定

if user_dic:
       if user_dic.get('locked'):
           return False, '当前用户已被锁定'
       #给用户输入的密码做一次加密
       password = common.get_pwd_md5(password)
       #3)校验密码是否一致
       if password == user_dic.get('password'):
           msg = f'用户{username}登录成功!'
           user_logger.info(msg)
           return True, msg
       else:
           msg = f'用户{username}密码错误!'
           user_logger.warn(msg)
           return False, msg
   msg = f'用户{username}不存在!'
   user_logger.warn(msg)
   return False, msg

#查看余额接口
def check_bal_interface(username):
   user_dic = db_handler.select(username)
   return user_dic['balance']

-shop_interface.py

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/02 14:53
@Author  : Rice
@CSDN : C_小米同学
@FileName: shop_interface.py
'''
'''
商城购物接口层
'''
from db import db_handler
#商品准备结算接口
def shopping_interface(login_user, shopping_car):
   #计算消费金额
   cost = 0
   for price_number in shopping_car.values():
       price, number = price_number
       cost += (price*number)
   #导入银行接口
   from interface import bank_interface

#逻辑校验成功后,在调用银行支付接口
   flag = bank_interface.pay_interface(login_user,cost)
   if flag:
       return True, '支付成功,准备发货'
   return False, '支付失败,金额不足'

#购物车添加接口
def add_shop_car_interface(login_user, shopping_car):

#获取当前用户的购物车
   user_dic = db_handler.select(login_user)

shop_car = user_dic.get('shop_car')
   #添加购物车
   for shop_name, price_number in shopping_car.items():
       #每个商品的数量
       number = price_number[1]
       if shop_name in shop_car:
           user_dic['shop_car'][shop_name] += number
           db_handler.save(user_dic)
           print('添加到json成功')
       else:
           user_dic['shop_car'].update({shop_name: price_number})
           db_handler.save(user_dic)
           print('添加到json成功')

return True, '添加购物车成功'

#查看购物车接口
def check_shop_car_interface(username):
   user_dic = db_handler.select(username)
   return user_dic.get('shop_car')

-bank_interface.py

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/02 14:53
@Author  : Rice
@CSDN : C_小米同学
@FileName: bank_interface.py
'''
'''
银行先关业务的接口
'''
from db import db_handler
#提现接口(手续费5%)
def withdraw_interface(username, money):
   #1)先获取用户字典
   user_dic = db_handler.select(username)
   #校验用户的钱是否足够
   balance = int(user_dic.get('balance'))

#本金+手续费
   momey2 = int(money) * 1.05  #money是str,用int类型转换

#判断用户金额是否足够
   if balance >= momey2:

#2)修改用户字典中的金额
       balance -= momey2
       user_dic['balance'] = balance

#记录流水
       flow = f'用户{username} 提现金额{money}成功,手续费是:{momey2 - float(money)}$ 剩余{balance}'
       user_dic['flow'].append(flow)
   #3)再保存数据,或更新数据
       db_handler.save(user_dic)
       # money是str,用int类型转换
       return True, flow

def repay_interface(username, money):
   '''
   1.获取用户的金额
   2.给用户加钱操作
   :param username:
   :param money:
   :return:
   '''
   #1.获取用户字典
   user_dic = db_handler.select(username)

#2.直接做加钱的操作
   user_dic['balance'] += money

#记录流水
   flow = f'用户{username} 还款{money}成功! 当前额度为{user_dic["balance"]}'
   user_dic['flow'].append(flow)
   #3.调用数据处理层,将修改后的数据进行更新
   db_handler.save(user_dic)
   return True, flow

def transfer_interface(login_user, to_user, money):
   '''
   1.获取'当前用户' 数据
   2.获取'目标用户' 数据
   3.获取转账金额
   :return:
   '''
   login_user_dic = db_handler.select(login_user)

to_user_dic = db_handler.select(to_user)

if not to_user_dic:
       return False, '目标用户不存在'

#4)若用户存在,则判断'当前用户的转账金额' 是足够的
   if login_user_dic['balance'] >= money:
        login_user_dic['balance'] -= money
        to_user_dic['balance'] += money
        #当前用户流水
        login_user_flow = f'用户{login_user} 给用户 {to_user} 转账 {money}$ 成功'
        login_user_dic['balance'].append(login_user_flow)

#目标用户流水
        to_user_flow = f'用户{to_user} 给用户 {login_user} 转账 {money}$ 成功'
        to_user_dic['flow'].append(to_user_flow)
        #调用数据处理层,保存数据
        db_handler.save(login_user_dic)
        db_handler.save(to_user_dic)

return True, login_user_flow
   return False, '当前用户转账金额不足'

def check_flow_interface(login_user):
   user_dic = db_handler.select(login_user)
   return user_dic.get('flow')

#支付接口

def pay_interface(login_user, cost):
   user_dic = db_handler.select(login_user)

#判断用户金额
   if user_dic.get('balance') >= cost:
       user_dic['balance'] -= cost
       flow = f'用户消费金额:{cost}$'
       user_dic['flow'].append(flow)

#保存数据
       db_handler.save(user_dic)
       return True
   return False

-admin_interface.py

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/04 12:39
@Author  : Rice
@CSDN : C_小米同学
@FileName: admin_interface.py
'''

from db import db_handler
from lib import common
admin_logger = common.get_logger('admin')
#修改额度接口
def change_balance_interface(username, money):
   user_dic = db_handler.select(username)

if user_dic:
       #修改额度
       user_dic['balance'] = int(money)

db_handler.save(user_dic)
       msg = f'管理员修改用户:{username}额度修改成功'
       admin_logger.info(msg)
       return True, '额度修改成功!'
   return False, '修改额度用户不存在'

#冻结账户接口

def lock_user_interface(username):
   user_dic = db_handler.select(username)
   if user_dic:
       user_dic['locked'] = True
       db_handler.save(user_dic)

return True, f'用户{username}冻结成功'
   return False, '冻结用户不存在'

5.db

-db_handler.py

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/02 14:57
@Author  : Rice
@CSDN : C_小米同学
@FileName: db_handler.py
'''
'''
数据处理层
   -专门用户处理数据
'''
import json
import os
from conf import settings

#查看数据
def select(username):

#1)接收接口层传过来的username用户名,拼接用户json文件路劲
   user_path = os.path.abspath(os.path.join(settings.USER_DATA_PATH, f'{username}.json')).replace('\\', '/')
   #2)校验用户json文件是否存在
   if os.path.exists(user_path):
       #3)打开数据,并返回给接口层
       with open(user_path, 'r', encoding='utf-8') as f:
           user_dic = json.load(f)  # 导出数据
           return user_dic
   #3)不return,默认返回return None

#保存数据
def save(user_dic):
   #1)拼接用户的数据字典
   username = user_dic.get('username')
   user_path = os.path.abspath(os.path.join(settings.USER_DATA_PATH, f'{username}.json')).replace('\\', '/')
   #2)保存用户数据
   with open(user_path, 'w', encoding='utf-8') as f:
       # 导入数据(ensure_ascii=False,让文件中的中文数据显示更美观)
       json.dump(user_dic, f, ensure_ascii=False)

6.lib

-common.py

# -*- coding: utf-8 -*-

'''
@Time    : 2022/09/02 14:50
@Author  : Rice
@CSDN : C_小米同学
@FileName: common.py
'''
'''
存放公共方法
'''

import hashlib
import logging.config
from conf import settings

def get_pwd_md5(password):
   md5_obj = hashlib.md5()
   md5_obj.update(password.encode('utf-8')) #传入的数据需要时"字节串"
   salt = 'rice这是一个ATM'
   md5_obj.update(salt.encode('utf-8'))
   return md5_obj.hexdigest()

#登录认证装饰器
def login_auth(func):
   from core import src

def inner(*args, **kwargs):
       if src.login_user:
           res = func(* args, ** kwargs)
           return res
       else:
           print('使用功能前,请先登录')
           src.login()
   return inner

#添加日子功能:(日志功能在接口层使用)

#获取日志功能
#获取日志对象
def get_logger(log_type):
   '''
   :param log_type: 比如是user日子,bank日子,购物商城日志
   :return:
   '''
   #1、加载日志配置信息
   logging.config.dictConfig(settings.LOGGING_DIC)
   #2、获取日志对象
   logger = logging.getLogger(log_type)
   return logger

7.readme

# 项目说明书
## 项目:ATM + 购物车

# 项目需求
   模拟实现一个ATM + 购物商城程序

1.额度 15000或自定义 ->注册功能
       2.实现购物商城,买东西加入 购物车,调用信用卡接口结账-》购物、支付
       3.可以提现,手续费5%-》提现功能
       4.支持多账户登录-》登录功能
       5.支持账户间转账  -》转账功能
       6.记录日常消费流水-》记录流水功能
       7.提供还款接口  -》还款功能
       8.ATM记录操作日志 —》记录日志功能
       9.提供管理接口,包括添加账户、用户额度,冻结账户等。。。-》管理员功能
       10.用户认证用装饰器-》登录认证装饰器

## "用户视图层"展示给用户选择的功能
   1.注册功能
   2.登录功能
   3.查看余额
   4.提现功能
   5.还款功能
   6.转账功能
   7.查看流水
   8.购物功能
   9.查看购物车
   10.管理员功能

# 一个项目如何从无到有
## 一 需求分析
   1.拿到项目,想在客户那里讨论需求
   商量项目的功能能否实现,周期,价格,得到需求文档
   2.最后在公司内部需要开一次会议,得到最终的开发文档,
   交给不同的岗位的程序员进行开发
       -Python:后端,爬虫
       -不同的岗位:
           -UI界面设计:
               -设计软件的布局,会根据软件的外观切成一张张图片
           -前端:
               -拿到UI交给他的图片,去搭建网页页面
               -设计一些页面中,哪些位置需要接收数据,需要进行数据交互
           -后端:
               -直接核心的业务逻辑,调度数据库进行数据的增删
           -测试:
               -会给代码进行全面测试,比如压力测试,界面测试
           -运维
               -部署项目
## 二 程序的架构设计
### 1、程序设计的好处
   1)思路不清晰
   2)不会出现写一半推翻重写
   3)方便自己或以后的同时更好维护
### 2、 三层架构设计的好处
   1)每个功能都分成三部分
   2)如果用户更换不同的用户界面或不同的数据储存机制,这样
   都不会影响接口层的核心逻辑代码。拓展性强
   3)可以在接口层,准确的记录接口和流水
### 3、三层架构
#### 一 用户视图层
   用于与用户交互的,可以接受用户输入,打印接口返回的数据
#### 二 逻辑接口层
   接受 用户视图层 传递过来的参数,根据逻辑判断调用数据层加以处理,
   并返回一个结果给用户视图层
#### 三 数据处理层
   接受接口层传递过来的参数,做数据的
       - 保存 save()
       - 查看数据 select()
       - 更新数据
       - 删除数据
## 三 分任务开发
## 四 测试
## 五 上线

# 统计代码

来源:https://blog.csdn.net/weixin_43507744/article/details/126692924

标签:Python,ATM,取款机
0
投稿

猜你喜欢

  • javascript操作table(insertRow,deleteRow,insertCell,deleteCell方法详解)

    2024-04-16 09:14:08
  • echarts柱状图坐标轴内容显示不全的两种解决办法

    2023-09-06 03:57:34
  • Python中的字典与成员运算符初步探究

    2023-01-28 09:59:18
  • 理理Vue细节(推荐)

    2024-05-28 15:53:07
  • CSS布局之浮动(二)三列浮动

    2008-08-19 12:47:00
  • CSS Hack 汇总快查

    2007-11-06 11:48:00
  • 《解剖PetShop》之四:PetShop之ASP.NET缓存

    2024-06-05 09:25:59
  • PyHacker实现网站后台扫描器编写指南

    2022-11-07 12:20:24
  • Python基于list的append和pop方法实现堆栈与队列功能示例

    2022-10-20 02:26:26
  • 详解python的数字类型变量与其方法

    2023-12-05 18:40:53
  • MySQL数据库在Linux下二进制日志恢复方法

    2009-07-30 08:55:00
  • 在Infopath中实现数据有效性验证的三种方法

    2023-03-06 15:25:31
  • Windows下在CMD下执行Go出现中文乱码的解决方法

    2024-04-25 15:17:27
  • Vue实现web分页组件详解

    2024-04-30 10:39:27
  • Python实现类似比特币的加密货币区块链的创建与交易实例

    2022-03-19 15:49:49
  • 详解python使用canvas实现移动并绑定键盘

    2022-08-18 01:02:52
  • Python办公自动化Word转Excel文件批量处理

    2022-06-24 21:02:23
  • google地图的路线实现代码

    2024-04-10 10:51:28
  • 详解Python学习之安装pandas

    2021-04-30 19:35:33
  • Python实现的KMeans聚类算法实例分析

    2021-06-28 04:44:49
  • asp之家 网络编程 m.aspxhome.com