0.《设计模式》摘录
-
问题:
在一个GUI中实现的上下文有关的帮助机制,用户在界面的任一部分上点击都可以得到与所点击部分最接近的相关帮助信息
问题在于帮助信息并不一定是由接受点击的对象提供的。 -
优点:
降低耦合度
一个对象无需知道其它哪个对象处理其请求,接收者和发送者都没有对方的明确信息。增强了给对象指派职责的灵活性
运行时刻可以动态修改职责链改变对请求的响应功能。 -
可以把请求包含在一个类里面,根据请求的属性来处理
1. 针对的问题
小菜向经理申请加薪,经理没权利,然后向总监上报,总监也没权限,向总经理上报。怎么把这个处理过程写成代码呢?
-
一种解决方法是把管理者的逻辑用if else写在一个类里面:判断身份是经理、总监还是总经理,分别写对应的处理方式
客户端声明三个管理者,各自调用方法:
-
这样写的缺点:
- 违反开放·封闭原则:如果增加其他的管理类别,比如项目经理、部门经理、人力总监、副总经理等等。那就意味着都需要去更改这个类
- 违背了单一职责原则:这个类承担了太多的责任
-
解决:
让管理者子类之间有一定的关联,把用户的请求传递,直到可以解决这个请求为止。
2. 职责链模式
职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
-
结构图:
-
Handler类:定义一个处理请示的接口。
abstract class Handler { protected Handler successor;//设置下一个处理者 public void SetSuccessor(Handler successor) { this.successor = successor; } public abstract void HandleRequest (int request);//处理请求的抽象方法 }
-
ConcreteHandler类:具体处理者类,处理它所负责的请求,可访问它的后继者。如果可处理该请求, 就处理之,否则就将该请求转发给它的后继者。
ConcreteHandler 1,当请求数在0到10之间则有权处理,否则转到下一位。class ConcreteHandler1 extends Handler { @override public override void HandleRequest(int request) { if (request >= 0 && request < 10) { Console.WriteLine ("%s处理请求%d",this.getClass().getName(), request); } else if (successor != null)//给下一个处理 { successor. HandleRequest (request); } } }
ConcreteHandler2,当请求数在10到20之间则有权处理,否则转到下一位。(代码类似)
ConcreteHandler3,当请求数在20到30之间则有权处理,否则转到下一位。 -
客户端代码:向链上的具体处理者对象提交请求。
static void Main(string[]] args) { Handler hl = new ConcreteHandlerl(); Handler h2 = new ConcreteHandler2 (); Handler h3 - new ConcreteHandler3(); //设置职責链上家与下家 hl.SetSuccessor(h2); h2.SetSuccessor(h3); int requests = ( 2, 5, 14, 22, 18,3, 27, 20 ); for (int request : requests) { hl.HandleRequest(request); } Console.Read(); }
3. 优点
职责链的好处:
- 职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用,这也就大大降低了耦合度了。
- 可以随时地増加或修改处理一个请求的结构,增强了给対象指派职责的灵活性
注意的有两点:
- 需要事先给每个具体管理者设置后继者。
- 需要在每个具体管理者处理请求时,做出判断,是可以处理这个请求,还是必须要转移给后继者去处理