如何解决将策略模式与依赖注入一起使用
我正在研究https://en.wikipedia.org/wiki/Strategy_pattern中列出的Strategy模式,并试图了解当您还要使用依赖注入并使其易于进行单元测试时,该模式如何工作。
所以界面是:
interface BillingStrategy {
// Use a price in cents to avoid floating point round-off error
int getActPrice(int rawPrice);
}
有两种实现方式:
@Component
NormalHours implements BillingStrategy {
public int getActPrice(int rawPrice) {
return rawPrice;
}
}
@Component
HappyHours implements BillingStrategy {
public int getActPrice(int rawPrice) {
return rawPrice/2;
}
}
现在有一个我要为其跟踪总价的客户对象:
class Customer {
private final List<Integer> drinks = new ArrayList<>();
private BillingStrategy strategy;
public Customer(BillingStrategy strategy) {
this.strategy = strategy;
}
public void add(int price,int quantity) {
this.drinks.add(this.strategy.getActPrice(price*quantity));
}
// Payment of bill
public int getBill() {
int sum = this.drinks.stream().mapToInt(v -> v).sum();
this.drinks.clear();
return sum;
}
// Set Strategy
public void setStrategy(BillingStrategy strategy) {
this.strategy = strategy;
}
}
现在说我有一个文件,其中包含一天中每个小时的购买信息,我需要为客户计算最终账单。
@Component
public class Calculator {
public int calculate(File file) {
//pseudo code here
Customer customer = new Customer();
for(line in file) {
//parse price,strategy and quantity from line
customer.setStrategy(strategy);
customer.add(price,quantity);
}
return customer.getBill();
}
}
很显然,这对于单元测试不是很好,因为在该方法中创建了一个新对象,并且仅使用常规Mockito很难模拟在Calculator类中为策略返回的值。有没有其他方法可以对Customer&Calculator类进行建模,以确保易于测试并尽可能使用DI?
我知道一种方法是让Calculator的调用者传递对象Customer,但是用Wiki解释这种特定Customer类的方式,我们不能将其作为Singleton进行处理,并且会存在相同的问题。
解决方法
给定策略与客户本身无关,将其置于客户内违反了直接投资。而是将策略作为方法参数传递
class Customer {
private final List<Integer> drinks = new ArrayList<>();
public void add(BillingStrategy strategy,int price,int quantity) {
drinks.add(strategy.getActPrice(price * quantity));
}
// Payment of bill
public int getBill() {
int sum = drinks.stream().mapToInt(v -> v).sum();
drinks.clear();
return sum;
}
}
@Component
public class Calculator {
public int calculate(Customer customer,File file) {
//pseudo code here
for(line in file) {
//parse price,strategy and quantity from line
customer.add(strategy,price,quantity);
}
return customer.getBill();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。