代码设计优化与Mock对象的使用
立即解锁
发布时间: 2025-08-19 01:48:54 阅读量: 1 订阅数: 3 

### 代码设计优化与Mock对象的使用
#### 1. 代码设计优化
在软件开发过程中,代码设计的优化至关重要。以下是一些代码设计优化的要点和示例。
##### 1.1 提取代码到新类
将代码提取到新类可以使测试更加直接和简单。例如,在测试`MatchSet`代码时,不再需要创建`Profile`对象的干扰开销。同时,当测试更容易编写时,往往可以覆盖更多的排列组合。
```java
private MatchSet createMatchSet() {
return new MatchSet(answers, criteria);
}
@Test
public void matchAnswersFalseWhenMustMatchCriteriaNotMet() {
add(answerDoesNotReimburseTuition);
criteria.add(
new Criterion(answerReimbursesTuition, Weight.MustMatch));
assertFalse(createMatchSet().matches());
}
@Test
public void matchAnswersTrueForAnyDontCareCriteria() {
add(answerDoesNotReimburseTuition);
criteria.add(
new Criterion(answerReimbursesTuition, Weight.DontCare));
assertTrue(createMatchSet().matches());
}
```
##### 1.2 避免构造函数做实际工作
`MatchSet`的构造函数原本用于计算分数,但如果计算的分数没有被客户端使用,那么计算的努力就会浪费。因此,应该在请求时计算分数。
```java
public class MatchSet {
public MatchSet(Map<String, Answer> answers, Criteria criteria) {
this.answers = answers;
this.criteria = criteria;
}
public int getScore() {
int score = 0;
for (Criterion criterion: criteria)
if (criterion.matches(answerMatching(criterion)))
score += criterion.getWeight().getValue();
return score;
}
}
```
##### 1.3 解决数据存储问题
在处理答案集合时,存在一些问题。例如,`Profile`和`MatchSet`类都对答案的存储和检索方式有深入了解,这会导致代码的耦合度增加。为了解决这个问题,可以将答案的存储隔离到一个名为`AnswerCollection`的类中。
```java
// Profile.java
public class Profile {
private AnswerCollection answers = new AnswerCollection();
private String name;
public Profile(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void add(Answer answer) {
answers.add(answer);
}
public MatchSet getMatchSet(Criteria criteria) {
return new MatchSet(answers, criteria);
}
}
// AnswerCollection.java
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
public class AnswerCollection {
private Map<String,Answer> answers = new HashMap<>();
public void add(Answer answer) {
answers.put(answer.getQuestionText(), answer);
}
public Answer answerMatching(Criterion criterion) {
return answers.get(criterion.getAnswer().getQuestionText());
}
public List<Answer> find(Predicate<Answer> pred) {
return answers.values().stream()
.filter(pred)
.collect(Collectors.toList());
}
}
// MatchSet.java
public class MatchSet {
private AnswerCollection answers;
private Criteria criteria;
public MatchSet(AnswerCollection answers, Criteria criteria) {
this.answers = answers;
this.criteria = criteria;
}
public int getScore() {
int score = 0;
for (Criterion criterion: criteria)
if (criterion.matches(answers.answerMatching(criterion)))
score += criterion.getWeight().getValue();
return score;
}
}
```
#### 2. 使用Mock对象进行单元测试
在实际开发中,我们经常会遇到难以进行单元测试的情况,例如与外部服务的交互。这时可以使用Mock对象来解决这些问题。
##### 2.1 测试挑战
在`iloveyouboss`应用程序中,添加了一个新功能,用户可以在交互式地图上选择一个点来表示`Profile`地址。应用程序将所选点的纬度和经度坐标传递给`AddressRetriever`类的`retrieve()`方法,该方法应根据坐标返回一个填充好的`Address`对象。
```java
public class AddressRetriever {
public Address retrieve(double latitude, double longitude)
throws IOException, Parse
```
0
0
复制全文
相关推荐










