结合工厂模式与策略模式:构建一个灵活的请假功能

650 阅读2分钟

在面向对象的设计中,设计模式是解决常见设计问题的最佳实践。我们将结合工厂模式和策略模式来设计一个灵活且易于扩展的请假功能。

背景

在一个组织中,员工可能需要请不同类型的假,如病假、年假等。每种假期可能有自己的规则,例如年假可能限制为每年最多10天。如何设计一个系统来处理这些复杂的规则和类型,同时保持扩展性和可维护性呢?

涉及设计模式

  1. 策略模式:允许在运行时选择对象的行为或算法。在我们的场景中,不同的请假类型对应于不同的计算策略。
  2. 工厂模式:提供一个创建对象的接口,但允许子类决定要实例化的类。在此系统中,我们使用工厂模式来创建不同的请假策略。

UML模式结构

截屏2023-08-23 14.42.01.png

通过以上方式,可以将假单类型和请假策略分离,并且实现相互扩展。

代码实现

// 请假策略接口
function LeaveStrategy() {
    this.calculateLeaveDays = function(days) {};
}

// 病假策略
function SickLeaveStrategy() {}
SickLeaveStrategy.prototype = Object.create(LeaveStrategy.prototype);
SickLeaveStrategy.prototype.calculateLeaveDays = function(days) {
    return days;
};

// 年假策略
function AnnualLeaveStrategy() {}
AnnualLeaveStrategy.prototype = Object.create(LeaveStrategy.prototype);
AnnualLeaveStrategy.prototype.calculateLeaveDays = function(days) {
    if (days > 10) {
        return 10;
    }
    return days;
};

// 请假类型
function LeaveType(strategy) {
    this.strategy = strategy;
}

LeaveType.prototype.calculateDays = function(days) {
    return this.strategy.calculateLeaveDays(days);
};

// 请假类型工厂
function LeaveTypeFactory() {}

LeaveTypeFactory.prototype.createLeaveType = function(type) {
    switch (type) {
        case 'sick':
            return new LeaveType(new SickLeaveStrategy());
        case 'annual':
            return new LeaveType(new AnnualLeaveStrategy());
        default:
            throw new Error("Unknown leave type");
    }
};

// 使用
let factory = new LeaveTypeFactory();

let sickLeave = factory.createLeaveType('sick');
console.log(sickLeave.calculateDays(5));  // 输出:5

let annualLeave = factory.createLeaveType('annual');
console.log(annualLeave.calculateDays(12));  // 输出:10

总结

通过结合工厂模式和策略模式,我们设计了一个既灵活又易于扩展的请假系统。现在,如果需要添加新的请假类型或更改规则,只需添加新的策略并在工厂中进行相应的调整即可。

这种模式的结合不仅适用于请假系统,还可以广泛应用于任何需要处理不同类型和规则的系统中。希望这篇文章为你提供了一些设计灵感!