代码层次上的软件质量属性
软件质量的属性---可修改性
可修改性:软件质量属性中的可修改性是指容易修改的能力,其包括修正,改进和用户需求的变化。
可修改性战术:其目标是控制实现、测试和部署变更的时间和成本。即为根据相关战术在时间和成本允许的范围内完成系统的相关变更。
可修改性战术分类:
1.局部化变更:目标是减少有某个变更直接影响的模块的数量,在设计时为模块分配责任,以把预期的变更限制在一定的范围内
1.1预期期望的变更:根据语义一致性原则,预测期望变更的战术并不关心模块责任的一致性,而是关心将变更的影响最小化。
1.2维持语义一致性:确保所有责任都能够协同工作,必须过分依赖其他模块,其子战术为:“抽象通用服务”通过专门的模块提供通用服务,比如sin(x)通用函数
1.3泛化模块:使一个模块更通用能够使他根据输入计算更广泛的功能;
1.4限制选择参数:限制可能的选择将会降低这些修改所造成的影响,比如可将选择的操作系统限定在一定范围内。
2.防止连锁反应:目标是限制对局部化的模块的修改,以防止对某个模块的修改间接的影响到其他模块
2.1信息隐藏:目的将变更隔离在一个模块内,防止变更扩散
2.2维持现有接口:添加接口,添加适配器
2.3限制通信路径:限制与一个给定的模块共享数据的模块
2.4使用仲裁者:在A与B之间插入一个仲裁者,以管理A与B之间依赖的相关活动,仲裁者可以是:数据(如存储库)、服务
3.延迟绑定时间:目标是控制部署时间,并允许非开发人员进行修改
3.1运行时注册:即插即用的操作
3.2配置文件:启动时设置参数
3.3多态:允许方法调用的后期绑定
3.4组件更换:允许载入时间绑定
3.5遵守已定义的协议:允许独立进程的运行时绑定
参考:https://wenku.baidu.com/view/8c475679590216fc700abb68a98271fe900eaf5b.html
1.1预期的变更
预期的变更就是在编码前想到后期用户的使用环境、电脑配置等方面来对代码进行健壮性,可修改性的改进。如果没有预期到,那么等到用户实际使用的时候,前端界面可能出现不兼容的情况,影响软件、系统等的功能使用。预期变更不关心模块责任的一致性,而是关心将变更的影响最小化。
/* CSS选择符级Hack */
*html #demo { color:red;} /* 仅IE6 识别 */
*+html #demo { color:red;} /* 仅IE7 识别 */
body:nth-of-type(1) #demo { color:red;} /* IE9+、FF3.5+、Chrome、Safari、Opera 可以识别
head:first-child+body #demo { color:red; } /* IE7+、FF、Chrome、Safari、Opera 可以识别 */
:root #demo { color:red\9; } : /* 仅IE9识别 */
根据用户的浏览器可能不兼容的问题,提前预期到并在代码层次上对浏览器兼容进行修正。
1.3泛化模块
泛化模块普通来说就是让一个模块的功能放大,可以接受不同样的多种参数,并能正常来执行函数体。其次还可以为代码的修改带来方便,例如将这种很常见的if else语句抽象通用服务,提供一个统一的接口,例如X x = factory.getBean(var); x.doX();这样在进行增加E,F,G等功能的时候不需要逐行的增加if else语句,为开发人员带来很大的方便。
if(var.equals("A")){ doA(); } else if(var.equals("B")){ doB(); } else if(var.equals("C")){ doC(); } else{ doD(); }
1.4限制选择范围
限制选择范围是平常实际开发中的一条很好用的可修改性战术,通过限制用户可选择的范围,来避免发生错误。通过范围的限制,用户只能够选择系统、软件已有的功能。在web开发中,表单提交中有很多的输入框,有时候这些输入框必须输入整数,或者其他类型,通过函数来限制用户的选择,来避免用户随便输入改造的而产生的影响。在通常的函数方法之间的调用也要进行参数的校验,以免某个方法返回的参数不符合其调用方法所能接受的参数。
例:input输入类型设置,只能输入数字、小数点和减号:
function typeText(a) { var m = ""; if(a.value.substring(0, 1) == "-") m = "-"; var str = (a.value.replace(/[^0-9.]/g,'')).replace(/[.][0-9]*[.]/, '.'); if(str.substring(0, 1) == ".") str = "0" + str; value = m + str; //οnkeyup="value=value.replace(/[^\d{1,}\.\d{1,}|\d{1,}]/g,'')" } <input οnkeyup="typeText(this)"/>
2.2添加接口,在操作数据库的时候定义了一些功能模块,而这些功能模块指责单一,各功能模块相对独立。
public static void close (ResultSet rs, Statement state, Connection conn) { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (state != null) { try { state.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
3.2配置文件:
配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp" version="3.1"> <display-name>ServerletDemo</display-name> <servlet> <servlet-name>servlet</servlet-name> <servlet-class>com.serverlet.test.servlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>servlet</servlet-name> <url-pattern>/ServletDemo</url-pattern> </servlet-mapping> </web-app>
3.3多态
多态,多态不仅提高了代码的维护性(继承保证),也提高了代码的可修改性(由多态保证)
多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。
Animal an = new Cat(); an . cry(); an = new Dog(); an.cry();