Blog

结构化分析方法

基本思想 #

自顶向下,逐层分解,把一个大问题分解成若干个小问题,每个小问题再分解成若干个更小的问题。经过逐层分解,每个最低层的问题都是足够简单、容易解决的。

模型的核心 #

数据字典

三个层次的模型 #

  1. 数据模型(E-R 图)
  2. 功能模型(DFD)
  3. 行为模型(也称为状态模型)(状态转换图)

这三个模型有着密切的关系,它们的建立不具有严格的时序性,而是一个迭代的过程。

From #

面向对象测试的三个特征

Content #

与传统的结构化系统相比,面向对象系统具有三个明显特征,即封装性、继承性与多态性。

封装性决定了面向对象系统的测试必须考虑到信息隐蔽原则对测试的影响,以及对象状态与类的测试序列,因此在测试一个类时,仅对该类的每个方法进行测试是不够的;

继承性决定了面向对象系统的测试必须考虑到继承对测试充分性的影响,以及误用引起的错误;

多态性决定了面向对象系统的测试必须考虑到动态绑定对测试充分性的影响、抽象类的测试以及误用对测试的影响。

From #

代理模式和装饰器模式的区别

Content #

代理类附加的是跟原始类无关的功能,而在装饰器模式中,装饰器类附加的是跟原始类相关的增强功能。

// 代理模式的代码结构
public interface IA {
  void f();
}
public class A impelements IA {
  public void f() { //... }
}
public class AProxy implements IA {
  private IA a;
  public AProxy(IA a) {
    this.a = a;
  }

  public void f() {
    // 新添加的代理逻辑
    a.f();
    // 新添加的代理逻辑
  }
}

// 装饰器模式的代码结构
public interface IA {
  void f();
}
public class A implements IA {
  public void f() { //... }
}
public class ADecorator implements IA {
  private IA a;
  public ADecorator(IA a) {
    this.a = a;
  }

  public void f() {
    // 功能增强代码
    a.f();
    // 功能增强代码
  }
}

Viewpoints #

From #

50 | 装饰器模式:通过剖析Java IO类库源码学习装饰器模式-设计模式之美-极客时间

...

面向对象设计中的类的三种类型

Content #

实体类 #

映射需求中的每个实体,实体类保存需要存储在永久存储体中的信息。实体类是对用户来说最有意义的类,通常采用业务领域术语命名,一般来说是一个名词,在用例模型向领域模型转化中,一个参与者一般对应于实体类。

控制类 #

用于控制用例工作的类,一般是由动宾结构的短语(“动词+名词”或“名词+动词”)转化来的名词。控制类用于对一个或几个用例所特有的控制行为进行建模,控制对象通常控制其他对象,因此它们的行为具有协调性。

边界类 #

用于封装在用例内、外流动的信息或数据流。边界类是一种用于对系统外部环境与其内部运作之间的交互进行建模的类。边界对象将系统与其外部环境的变更隔离开,使这些变更不会对系统其他部分造成影响。

From #

桥接模式(Bridge)

Content #

在 GoF 的《设计模式》一书中,桥接模式是这么定义的: Decouple an abstraction from its implementation so that the two can vary independently。将抽象和实现解耦,让它们可以独立变化。

JDBC 驱动是桥接模式的经典应用。如何利用 JDBC 驱动来查询数据库的代码如下所示:

Class.forName("com.mysql.jdbc.Driver");//加载及注册JDBC驱动程序
String url = "jdbc:mysql://localhost:3306/sample_db?user=root&password=your_password";
Connection con = DriverManager.getConnection(url);
Statement stmt = con.createStatement()
String query = "select * from test";
ResultSet rs=stmt.executeQuery(query);
while(rs.next()) {
  rs.getString(1);
  rs.getInt(2);
}

如果想要把 MySQL 数据库换成 Oracle 数据库,只需要把第一行代码中的 com.mysql.jdbc.Driver 换成 oracle.jdbc.driver.OracleDriver 就可以了。

先从 com.mysql.jdbc.Driver 这个类的代码看起。

package com.mysql.jdbc;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
  static {
    try {
      java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
      throw new RuntimeException("Can't register driver!");
    }
  }

  /**
   * Construct a new driver and register it with DriverManager
   * @throws SQLException if a database error occurs.
   */
  public Driver() throws SQLException {
    // Required for Class.forName().newInstance()
  }
}

当执行 Class.forName(“com.mysql.jdbc.Driver”) 时,实际做了两件事情:

...

门面模式(Facade)

Content #

Provide a unified interface to a set of interfaces in a subsystem. Facade Pattern defines a higher-level interface that makes the subsystem easier to use.

门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。

假设有一个系统 A,提供了 a、b、c、d 四个接口。系统 B 完成某个业务功能,需要调用 A 系统的 a、b、d 接口。利用门面模式,提供一个包裹 a、b、d 接口调用的门面接口 x,给系统 B 直接使用。

让系统 B 直接调用 a、b、d 感觉没有太大问题呀,为什么还要提供一个包裹 a、b、d 的接口 x 呢?

假设系统 A 是一个后端服务器,系统 B 是 App 客户端。App 客户端通过后端服务器提供的接口来获取数据。App 和服务器之间是通过移动网络通信的,网络通信耗时比较多,为了提高 App 的响应速度,要尽量减少 App 与服务器之间的网络通信次数。

完成某个业务功能(比如显示某个页面信息)需要“依次”调用 a、b、d 三个接口,因自身业务的特点,不支持并发调用这三个接口。

针对这种情况,就可以利用门面模式,让后端服务器提供一个包裹 a、b、d 三个接口调用的接口 x。App 客户端调用一次接口 x,来获取到所有想要的数据,将网络通信的次数从 3 次减少到 1 次,也就提高了 App 的响应速度。

...

黑盒测试

Content #

黑盒测试也称为功能测试,主要用于集成测试,确认测试和系统测试阶段。黑盒测试根据软件需求规格说明所规定的功能来设计测试用例。

等价类划分 #

所谓等价类就是某个输入域的集合,对每一个输入条件确定若干个有效等价类和若干个无效等价类,分别设计覆盖有效等价类和无效等价类的测试用例。无效等价类是用来测试非正常的输入数据的,所以要为每个无效等价类设计一个测试用例。

边界值分析 #

通过选择等价类边界作为测试用例,不仅重视输入条件边界,而且也必须考虑输出域边界。在实际测试工作中,将等价类划分法和边界值分析结合使用,能更有效地发现软件中的错误。

因果图方法 #

从用自然语言书写的程序规格说明的描述中找出因(输入条件)和果(输出或程序状态的改变),可以通过因果图转换为判定表。

正交试验设计法 #

使用已经造好了的正交表格来安排试验并进行数据分析的一种方法,目的是用最少的测试用例达到最高的测试覆盖率。

From #

软件开发环境的集成机制

Content #

软件开发环境(SoftwareDevelopmentEnvironment,SDE)是指支持软件的工程化开发和维护而使用的一组软件,由软件工具集和环境集成机制构成。

软件开发环境应支持多种集成机制,根据功能的不同,集成机制可以划分为:

  1. 环境信息库

环境信息库是软件开发环境的核心,用以存储与系统开发有关的信息,并支持信息的交流与共享。环境信息库中主要存储两类信息,一类是开发过程中产生的有关被开发系统的信息,例如分析文档、设计文档和测试报告等;另一类是环境提供的支持信息,如文档模板、系统配置、过程模型和可复用构件等。

  1. 过程控制与消息服务器

过程控制与消息服务器是实现过程集成和控制集成的基础。过程集成时按照具体软件开发过程的要求进行工具的选择与组合,控制集成使各工具之间进行并行通信和协同工作。

  1. 环境用户界面

环境用户界面包括环境总界面和由它实行统一控制的各环境部件及工具的界面。统一的、具有一致性的用户界面是软件开发环境的重要特征,是充分发挥环境的优越性、高效地使用工具并减轻用户的学习负担的保证。

From #

sub:RelationalAlgebra

Content #

逻辑运算符: \[\neg, \vee, \wedge\]

关系运算 #

投影(Projection) #

\[\pi_A( R)=\{t[A]|t \in R\}\]

选择(Selection) #

\[\sigma_F( R)=\{t|t \in R \wedge F(t)=True\}\]

\(\sigma_{1 \geq 6}( R)\) 表示选取R关系中第1个属性值大于等于第6个属性值的元组。 \(\sigma_{1 \geq ‘6’}( R)\) 表示选取R关系中第1个属性值大于等到6的元组。

连接(Join) #

\(\theta\) 连接 #

从R和S的笛卡尔积中选取属性满足一定条件的元组: \[R \mathop{\bowtie}\limits_{X \theta Y} S=\{t|t=<t^n,t^m> \wedge t^n \in R \wedge t^m \in S \wedge t^n[X] \theta t^m [Y]\}\] \(\theta\) 为比较运算符,X和Y分别为R和S上度数相等且可比的属性组。 $<t^n,t^m>$意为元组 \(t^n\) 和 \(t^m\) 拼接成的一个元组。

\(\theta\) 连接可由笛卡尔积和选取运算导出: \(R \mathop{\bowtie}\limits_{X \theta Y} S=\sigma_{X \theta Y}(R \times S)\)

...