一、可修改性概念理解
概念:
指系统或软件的能够快速地以较高的性价比对系统进行变更的能力
这个最关注的问题是:可以修改什么?何时以谁进行修改?
比如:对于一个网站,我们要修改它某一板块的UI界面,当我们对界面进行修改时是否引起对另一个UI模块的影响,是否会引起后台控制,业务逻辑代码的并更,是否会引起整个网站的崩溃,这就体现了一个网站的整个架构的是否具备可修改性。
简单实用举例: 淘宝网站首页可以适应活动、节日等做出相应改变。 对一件商品的信息进行修改时,不会影响其他的商品和功能 商品信息可以随时更新 为了适应某些节日活动等,可以推出相应的优惠活动方式,比较方便,例如增加跨店满减、本店满减相对应得活动等。
二、引起软件可修改性因素
1、用户需求:
这里就要看“需求、成本、修改”三者之间的关系了;需求无处不在,时时刻刻产生。判别一个需求的重要性来自于它对系统的成本产生的影响,如果严重影响了系统带来的的收益,那必须对系统进行修改,如果一部分相对于系统来说微不足道,则可以选择性不改。
举例:一些网站的图标有人觉得不好,有人觉得不错
场景:使用该系统的人对此系统已经有了明确的认知,或者是已经习惯了这个图标代表的意义,如果修改了,然而对原有的使用者(老顾客)有了错误的判断——此系统停止运维了?则这些客户就会选择其他新的系统。
结果:系统的可修改性是必备的,但是最终修不修改是靠利益和人为因素决定的。
2、系统内在需求:
我这里以淘宝为说明对象,相关资料显示,初期的淘宝数据库是MySQL,众所周知MySQL是一个适用于小型企业的数据库,对于起初的淘宝也是适用的,因为没有产生MySQL无法处理的大量数据及相应的实时处理业务。但是近几年来淘宝的数据爆炸产生,在2012年11月30号到达全天访问用户总人数:2亿1千3百万,占中国网民40%;高峰期:每分钟成交订单89678笔。这就要求淘宝网对自身的数据库体系架构进行不断地更新和修改。
三、可修改性战术分类
四、可修改性战术分析
1、局部变更应用
(1)局部化意味着实现“模块化”思想,也就是设计模式中的“单一职责原则”的设计原则。通俗的来讲就是一个模块只完成一个部分,使每一个模块责任单一,防止职责过多引起整体变更时的繁琐,复杂,主要表现在类、函数、方法和接口的时候,实现“高内聚,低耦合”。
(这是之前看的一个python代码,这里边的变量、路径放在了一个.py文件中,都可以直接修改,不影响其他地方的代码)
# -----------------------路径相关参数--------------------------------------- train_ct_path = 'D:\\BaiduNetdiskDownload\\Training_Batch1\\media\\nas\\01_Datasets\\CT\\LITS\\ct' # 原始训练集CT数据路径 train_seg_path = 'D:\\BaiduNetdiskDownload\\Training_Batch1\\media\\nas\\01_Datasets\\CT\\LITS\\seg' # 原始训练集标注数据路径 test_ct_path = 'D:\\BaiduNetdiskDownload\\LITS-Challenge-Test-Data-20180512T073105Z-010\\CT' # 原始测试集CT数据路径 test_seg_path = 'D:\\BaiduNetdiskDownload\\LITS-Challenge-Test-Data-20180512T073105Z-010\\seg' # 原始测试集标注数据路径 training_set_path = 'D:\\train' # 用来训练网络的数据保存地址 pred_path = 'D:\\test\\liver_pred' # 网络预测结果保存路径 crf_path = 'D:\\test\\crf' # CRF优化结果保存路径 module_path = 'D:\\model\\net550-0.028-0.022.pth' # 测试模型地址 # -----------------------路径相关参数--------------- ------------------------ # ---------------------训练数据获取相关参数----------------------------------- size = 48 # 使用48张连续切片作为网络的输入 down_scale = 0.5 # 横断面降采样因子 expand_slice = 20 # 仅使用包含肝脏以及肝脏上下20张切片作为训练样本 slice_thickness = 1 # 将所有数据在z轴的spacing归一化到1mm upper, lower = 200, -200 # CT数据灰度截断窗口 # -----------------------网络结构相关参数------------------------------------ drop_rate = 0.3 # dropout随机丢弃概率 # -----------------------网络结构相关参数------------------------------------ # ---------------------网络训练相关参数-------------------------------------- gpu = '0' # 使用的显卡序号 Epoch = 1000 learning_rate = 1e-4 learning_rate_decay = [500, 750] alpha = 0.33 # 深度监督衰减系数 batch_size = 1 num_workers = 0 pin_memory = True cudnn_benchmark = True # ---------------------网络训练相关参数-------------------------------------- # ----------------------模型测试相关参数------------------------------------- threshold = 0.5 # 阈值度阈值 stride = 12 # 滑动取样步长 maximum_hole = 5e4 # 最大的空洞面积 # ----------------------模型测试相关参数------------------------------------- # ---------------------CRF后处理优化相关参数---------------------------------- z_expand, x_expand, y_expand = 10, 30, 30 # 根据预测结果在三个方向上的扩展数量 max_iter = 10 # CRF迭代次数 s1, s2, s3 = 1, 10, 10 # CRF高斯核参数 # ---------------------CRF后处理优化相关参数----------------------------------
维持语义一致性:模块中的责任能够协调一致的工作,不需要过多的依赖其它模块
预期期望的变更:淘宝网,用户变多,成交量变大,需要修改原有的mysql数据库。
泛化模块:模块设计的越通用,发生变更对模块影响就越小
限制可能的选择:在设计的时候对模块功能和它的可变范围进行限制,会降低这些修改所造成的影响
局部变更应用:
1.数据库更换,修改DBUtill.java文件即可。
2.数据表更换,修改持久层中表名即可。
3.添加功能,在service或者servlet中定义新的函数。
4.前端信息增加使用当框选择那个控制可限制性选择。
2、防止连锁反应
连锁反应定义:我们平时编程,无论是写函数还是写类,都需要被其他类还是函数调用,修改此函数或类就会影响到调用他的函数,这就是连锁反应。
防止连锁反应的方法:
(1)信息隐藏。信息隐藏就是把某个实体的责任分解为更小的部分,并选择使哪些信息成为公有的,哪些信息成为私有的。
(2)维持现有的接口。该战术的模式包括添加接口、添加适配器、提供一个占位程序。
(3)限制通信路径。限制与一个给定的模块共享的模块,减少联系,一旦变更影响会小很多。
(4)使用仲裁者。插入仲裁者来管理依赖之间的关系,就比如数据库的使用,通过数据库来管理不同的数据信息。
3、推迟绑定时间
推迟绑定时间。将有可能的修改,尽量用配置文件,或者其他后期让非开发人员可调整的方式实现。
(1)将数据库可能发生的修改放在c3p0-config.xml配置文件中,可以减少部署时间,甚至没有变更基础的人员也可以实现对数据库配置的修改。
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="user">root</property> <property name="password"></property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/reci?useUnicode=true&characterEncoding=utf-8</property> </default-config> </c3p0-config>
(2)框架级可修改性:平台代码、应用代码、后台模块代码分离。
(3)根据场景、调用后台模块出参入参可配原性修改,服务变更无需通过编码即可修改。