admin管理员组文章数量:1594754
Strategy模式定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
类图:
案例: 不同的员工薪资计算不同。
没有实现Strategy模式的例子:
public class Employee {
public static final int ENGINEER = 0;
public static final int SALESMAN = 1;
public static final int MANAGER = 2;
private int type = 0;
private int monthlySalary;
private int commission;
private int bonus;
public Employee(int type, int monthlySalary) {
this.type = type;
this.monthlySalary = monthlySalary;
}
public int getType() {
return type;
}
public int getMonthlySalary() {
return monthlySalary;
}
public int getCommission() {
return commission;
}
public void setCommission(int commission) {
thismission = commission;
}
public int getBonus() {
return bonus;
}
public void setBonus(int bonus) {
this.bonus = bonus;
}
public int payAmount() {
int result = 0;
switch(type) {
case ENGINEER:
result = monthlySalary;
break;
case SALESMAN:
result = monthlySalary + commission;
break;
case MANAGER:
result = monthlySalary + bonus;
break;
}
return result;
}
}
测试代码
public class EmployeeTest {
@Test
public void testEngineer() {
Employee engineer = new Employee(Employee.ENGINEER, 8000);
assertEquals(8000, engineer.payAmount());
engineer.setCommission(1000);
engineer.setBonus(2000);
assertEquals(8000, engineer.payAmount());
}
@Test
public void testSalesman() {
Employee salesman = new Employee(Employee.SALESMAN, 8000);
assertEquals(8000, salesman.payAmount());
salesman.setCommission(1000);
salesman.setBonus(2000);
assertEquals(9000, salesman.payAmount());
}
@Test
public void testManager() {
Employee manager = new Employee(Employee.MANAGER, 8000);
assertEquals(8000, manager.payAmount());
manager.setCommission(1000);
manager.setBonus(2000);
assertEquals(10000, manager.payAmount());
}
}
可以看到payAmount()方法有条件语句,不同类型的员工,薪资计算的算法不同,可以使用strategy模式重构:
每个类型码对应一个具体的strategy类, 每个strategy类定义一个payAmount(Employee employee)方法,Employee持有一个strategy类型的引用,它的payAmount委托给这个strategy引用对象,为了多态实现strategy, 提炼strategy接口。
public interface EmployeeType {//strategy interface
public int payAmount(Employee employee);
}
public class Engineer implements EmployeeType {
public int payAmount(Employee employee) {
return employee.getMonthlySalary();
}
}
public class Salesman implements EmployeeType {
public int payAmount(Employee employee) {
return employee.getMonthlySalary() + employee.getCommission();
}
}
public class Manager implements EmployeeType {
public int payAmount(Employee employee) {
return employee.getMonthlySalary() + employee.getBonus();
}
}
修改Employee类,将类型码替换成strategy类型引用,payAmount()委托给strategy类型的引用对象的payAmount(Employee employee)方法:
public class Employee {
private EmployeeType employeeType;
private int monthlySalary;
private int commission;
private int bonus;
public Employee(EmployeeType employeeType, int monthlySalary) {
this.employeeType = employeeType;
this.monthlySalary = monthlySalary;
}
public EmployeeType getType() {
return employeeType;
}
public int getMonthlySalary() {
return monthlySalary;
}
public int getCommission() {
return commission;
}
public void setCommission(int commission) {
thismission = commission;
}
public int getBonus() {
return bonus;
}
public void setBonus(int bonus) {
this.bonus = bonus;
}
public int payAmount() {
return employeeType.payAmount(this);
}
}
总结:
-
Strategy 模式是通过对象组合方式去除复杂的条件逻辑,为什么不选择通过Context的类继承方式?
a) 运行时动态替换算法。
b) 独立于客户端,无需修改客户端代码。 -
Strategy类如何访问Context类的数据?
a) 将Context引用传递给Strategy类的计算方法(回调机制)。
b) 将所需的数据传递给Strategy类的计算方法。
c) 将所需的数据封装成类,通过参数对象传递给Strategy类的计算方法。
d) 将特殊数据传递给Strategy类的构造函数或初始化方法。 -
Context类中用于计算的辅助方法 是 放在Context类中还是Strategy类中? 如果只是与计算相关,将这些辅助方法移动到Strategy类中。
返回 设计模式
版权声明:本文标题:设计模式 - 策略模式(Strategy) 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1725701203a1037493.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论