可修改性战术目标:控制实现、测试、和部署变更的时间和成本。可修改性可以理解为系统或软件的能够快速地以较高的性价比对系统举行调换的能力。
好比说:对于一个网站,我们要修改它某一板块的UI界面,当我们对界面举行修改时是否会引起对另一个UI模块的影响,是否会引起后台控制,营业逻辑代码的调换,
是否会引起整个网站的溃逃,这体现了一个网站的整个架构的是否具备可修改性。
根据目标划分,为减少由某个变更直接影响的模块的数量的可修改性战术称为“局部化修改“
1、维持语义的一致性。
语义的一致性是指模块中责任之间的关系,目标是确保所有这些责任都能协同工作,不需要过多得依赖别的模块。
热词分析中亦或者任意项目中比较典型能体现这一战术的便是数据库的相关操作。
①数据库连接类
package reci; import java.sql.*; public class Main { public static void main(String [] args) { String driverName="com.microsoft.sqlserver.jdbc.SQLServerDriver"; String dbURL="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=jsp"; String userName="sa"; String userPwd="123"; try { Class.forName(driverName); System.out.println("加载驱动成功!"); }catch(Exception e){ e.printStackTrace(); System.out.println("加载驱动失败!"); } try{ Connection dbConn=DriverManager.getConnection(dbURL,userName,userPwd); System.out.println("连接数据库成功!"); }catch(Exception e) { e.printStackTrace(); System.out.print("SQL Server连接失败!"); } } }
②Service层
public class TopSearchService{ private Connection connection = null; private Statement statement = null; private ResultSet resultSet = null; @Override public List<String> list() { String sql = "select title from info order by clickCount desc"; List<String> list = new ArrayList<>(10); try { connection = DBUtil.getConn(); statement = connection.createStatement(); resultSet = statement.executeQuery(sql); while (resultSet.next()) { list.add(resultSet.getString("title")); } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(connection, statement, resultSet); } return list; }
③Servlet层
public class TopSearchServlet extends HttpServlet { private static final long serialVersionUID = 1L; TopSearchService topSearchService=new TopSearchService(); /** * @see HttpServlet#HttpServlet() */ public TopSearchServlet() { super(); // TODO Auto-generated constructor stub } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置跨域请求 response.setHeader("Access-Control-Allow-Origin","*"); //处理中文乱码 response.setContentType("text/html;charset=utf-8"); //获取热搜列表 List<String> lists=topSearchService.list(); PrintWriter out=response.getWriter(); if (lists.size() > 0) { out.println(toJson(lists)); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
通过这样一层一层,实现了数据库的访问操作。可修改的体现:
1.数据库更换,修改DBUtill.java文件即可。
2.数据表更换,修改持久层中表名即可。
3.添加功能,在service中定义新的函数。
数据库操作独立存在,修改不会影响到其他模块。
2、防止连锁反应
我们平时编程无论是写函数照样写类,都会被其它的类或方法挪用,若何实现对被挪用部门的修改不会引起对挪用它的部门的影响,这就是连锁反映。
信息隐藏:最大化实现模块分解,最大化的隐藏私有信息,限制通信路径,减少共享数据数量。
对于immutable string 来说, 能够从accessor 方法中安全返回。
@interface MYSimpleClass { NSString *_myStringValue; } - (NSString *)safeStringValue; @end @implementation MYSimpleClass - (NSString *)safeStringValue { // 安全返回 return _myStringValue; } @end
但是, 如果是mutable string,下面的accessor 方法将破坏类的封装:
@interface MYSimpleClass { NSMutableString *_myStringValue; } - (NSMutableString *)unsafeStringValue; @end @implementation MYSimpleClass - (NSMutableString *)unsafeStringValue { / / myStringValue may be changed externally return myStringValue; }
安全返回mutabel 变量的解决办法:
1. 方法要强行 type casting返回变量. mutable -> immutable
2. 返回变量的一个 mutable copy.
@interface MYSimpleClass { NSMutableString *_myStringValue; } - (NSString *)safeStringValue1; - (NSMutableString *)safeStringValue2; } @implementation MYSimpleClass - (NSString *)safeStringValue1 { // 安全返回方案1 - type casting // return myStringValue; } - (NSMutableString *)safeStringValue2 { // 安全返回方案 2 - mutable copy return [[myStringValue mutableCopy] autorelease]; }
个人理解 软件可修改性的核心思想是模块化,并在此基础上,降低模块间的耦合性,提供模块的复用性。模块通过分布式部署,
独立的模块部署在独立的服务器上集群从物理上分离模块之间的耦合关系。我们的系统有大量的统计数据。我们的项目随时都有可能进行修改,
比如发布新功能,这时就需要在服务器上关闭原有的应用,重新部署新的应用,整个过程要求不影响用户的使用。
另外,一个项目的架构是随需而变的。关于项目的扩展性架构设计,是对现有系统影响最小的情况下,系统功能可持续扩展及提升的能力。对现有系统影响最小的情况下,
系统功能可持续扩展或提升的能力。它是系统架构设计层面的开闭原则,架构设计考虑未来功能扩展,当系统增加新功能时,不需要对现有系统的结构和代码进行修改。