定义
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端,从而提高代码的可维护性和可扩展性。
核心概念
策略接口(Strategy):定义所有具体策略必须实现的公共方法。
具体策略(Concrete Strategies):实现策略接口的具体算法。
上下文(Context):持有一个策略接口的引用,负责根据需要选择或切换策略。
JS实现(表单验证示例)
// 策略对象(验证器集合)
const Validators = {
required: (value) => !value && value !== 0 ? '不能为空' : null,
minLength: (value, min) => value.length < min ? `长度不能少于${min}位` : null,
email: (value) => !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) ? '格式不正确' : null,
};
// 上下文(验证器)
class Validator {
constructor() {
this.rules = {};
}
// 添加验证规则
addRule(field, validatorName, ...params) {
if (!this.rules[field]) this.rules[field] = [];
this.rules[field].push({ validatorName, params });
return this; // 链式调用
}
// 执行验证
validate(formData) {
const errors = {};
for (const field in this.rules) {
for (const rule of this.rules[field]) {
const { validatorName, params } = rule;
const value = formData[field];
const errorMessage = Validators[validatorName](value, ...params);
if (errorMessage) {
errors[field] = errorMessage;
break; // 只记录第一个错误
}
}
}
return errors;
}
}
// 使用示例
const validator = new Validator()
.addRule('username', 'required')
.addRule('password', 'required')
.addRule('password', 'minLength', 6)
.addRule('email', 'required')
.addRule('email', 'email');
const formData = {
username: '',
password: '123',
email: 'invalid-email'
};
// 输出: { username: '不能为空', password: '长度不能少于6位', email: '格式不正确'}
console.log(validator.validate(formData));
Java实现
// 策略模式:用多态替代 if else
// 1. 策略接口
interface DiscountStrategy { double calculate(double price); }
// 2. 具体策略(每个分支对应一个类)
class NormalDiscount implements DiscountStrategy {
@Override public double calculate(double price) { return price; }
}
class MemberDiscount implements DiscountStrategy {
@Override public double calculate(double price) { return price * 0.9; }
}
class HolidayDiscount implements DiscountStrategy {
@Override public double calculate(double price) { return price * 0.8; }
}
// 3. 上下文(通过策略实例动态选择行为,无 if else)
class DiscountContext {
private DiscountStrategy strategy;
public DiscountContext(DiscountStrategy strategy) {
this.strategy = strategy;
}
public double calculateTotal(double price) {
return strategy.calculate(price);
}
}
// 使用时直接选择策略,无需判断
public class Main {
public static void main(String[] args) {
DiscountContext context = new DiscountContext(new MemberDiscount());
System.out.println(context.calculateTotal(100)); // 90.0(无 if else)
}
}