一句话总结
使多个对象都有机会处理请求,从而避免请求的发送者和接受者的耦合关系。将这些对象连成一条链,并沿着该链传递该请求,直到有一个对象处理它为止。
需求
公司的审批通常要经过组长、经理、总监、总经理层层审批,那么如何用代码实现这样一个逻辑呢?
Code V1.0
manager类的代码不符合单一职责原则和开放-封闭原则。
static func main() {
let jingli = Manager(name: "经理")
let zongjian = Manager(name: "总监")
let zongjingli = Manager(name: "总经理")
let request = Request()
request.requestType = "加薪"
request.requestContent = "小菜请求加薪"
request.number = 1000
jingli.getResult(managerLevel: "经理", request: request)
zongjian.getResult(managerLevel: "总监", request: request)
zongjingli.getResult(managerLevel: "总经理", request: request)
let request2 = Request()
request2.requestType = "请假"
request2.requestContent = "小菜请求请假"
request2.number = 3
jingli.getResult(managerLevel: "经理", request: request2)
zongjian.getResult(managerLevel: "总监", request: request2)
zongjingli.getResult(managerLevel: "总经理", request: request2)
}
class Request {
var requestType = ""
var requestContent = ""
var number = 0
}
class Manager {
let name: String
init(name: String) {
self.name = name
}
func getResult(managerLevel: String, request: Request) {
if managerLevel == "经理" {
if request.requestType == "请假", request.number <= 2 {
print("\(name): \(request.requestContent) 数量\(request.number)被批准")
} else {
print("\(name): \(request.requestContent) 数量\(request.number)我无权处理")
}
} else if managerLevel == "总监" {
if request.requestType == "请假", request.number <= 5 {
print("\(name): \(request.requestContent) 数量\(request.number)被批准")
} else {
print("\(name): \(request.requestContent) 数量\(request.number)我无权处理")
}
} else if managerLevel == "总经理" {
if request.requestType == "请假" {
print("\(name): \(request.requestContent) 数量\(request.number)被批准")
} else if request.requestType == "加薪", request.number <= 500 {
print("\(name): \(request.requestContent) 数量\(request.number)被批准")
} else if request.requestType == "加薪", request.number > 500 {
print("\(name): \(request.requestContent) 数量\(request.number)再说吧")
}
}
}
}
职责链模式示例代码
当前一个类的实例处理不了的时候可以交由下一个类的实例去处理。
static func main() {
let handler1 = ConcreteHandler1()
let handler2 = ConcreteHandler2()
let handler3 = ConcreteHandler3()
handler1.successor = handler2
handler2.successor = handler3
let requests = [2, 8, 11, 14, 21, 23, 5, 30, 40]
for item in requests {
handler1.handleRequest(request: item)
}
}
protocol Handler {
var successor: Handler? { set get }
func handleRequest(request: Int)
}
class ConcreteHandler1: Handler {
var successor: Handler?
func handleRequest(request: Int) {
if request >= 0, request < 10 {
print("\(Self.self) 处理请求 \(request)")
} else {
successor?.handleRequest(request: request)
}
}
}
class ConcreteHandler2: Handler {
var successor: Handler?
func handleRequest(request: Int) {
if request >= 10, request < 20 {
print("\(Self.self) 处理请求 \(request)")
} else {
successor?.handleRequest(request: request)
}
}
}
class ConcreteHandler3: Handler {
var successor: Handler?
func handleRequest(request: Int) {
if request >= 20, request < 30 {
print("\(Self.self) 处理请求 \(request)")
} else {
successor?.handleRequest(request: request)
}
}
}
Code V2.0
用职责链模式实现该需求。
static func main() {
let jingli = CommonManager(name: "经理")
let zongjian = Majordomo(name: "总监")
let zongjingli = GeneralManager(name: "总经理")
jingli.superior = zongjian
zongjian.superior = zongjingli
let request = Request()
request.requestType = "加薪"
request.requestContent = "小菜请求加薪"
request.number = 1000
jingli.requestApplications(request: request)
let request2 = Request()
request2.requestType = "请假"
request2.requestContent = "小菜请求请假"
request2.number = 3
jingli.requestApplications(request: request2)
}
protocol Manager {
var name: String { set get }
var superior: Manager? { set get }
func requestApplications(request: Request)
}
class Request {
var requestType = ""
var requestContent = ""
var number = 0
}
class CommonManager: Manager {
var name: String
var superior: Manager?
init(name: String) {
self.name = name
}
func requestApplications(request: Request) {
if request.requestType == "请假", request.number <= 2 {
print("\(name): \(request.requestContent) 数量\(request.number)被批准")
} else {
superior?.requestApplications(request: request)
}
}
}
class Majordomo: Manager {
var name: String
var superior: Manager?
init(name: String) {
self.name = name
}
func requestApplications(request: Request) {
if request.requestType == "请假", request.number <= 5 {
print("\(name): \(request.requestContent) 数量\(request.number)被批准")
} else {
superior?.requestApplications(request: request)
}
}
}
class GeneralManager: Manager {
var name: String
var superior: Manager?
init(name: String) {
self.name = name
}
func requestApplications(request: Request) {
if request.requestType == "请假" {
print("\(name): \(request.requestContent) 数量\(request.number)被批准")
} else if request.requestType == "加薪", request.number <= 500 {
print("\(name): \(request.requestContent) 数量\(request.number)被批准")
} else if request.requestType == "加薪", request.number > 500 {
print("\(name): \(request.requestContent) 数量\(request.number)再说吧")
}
}
}
职责链模式的优点
- 当客户提交一个请求时,请求会沿链传递,直到有一个对象去处理它。
- 接受者和发送者都没有对方的明确信息,且链中的对象都不知道链的结构。可简化对象的相互连接,每个对象只需保持一个指向其后继者的引用,而无需保持全部后续者的引用。