一、责任链模式简介:
责任链模式的核心就是“链”,使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。责任链模式的缺点是性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候, 性能是一个非常大的问题。
二、责任链模式demo:
责任链模式作者选取的demo是古代妇女的“三从”,也就是说一个妇女在古代做什么事都需要请示家里的男性,未出嫁时,请示父亲,出嫁后请示丈夫,如果夫死,则请教儿子,下面demo来展示下这个场景。
首先是女性的接口和具体的实现类:
interface IWomen {
//获得个人状况
public int getType();
//获得个人请示, 你要干什么? 出去逛街? 约会?还是看电影?
public String getRequest();
}
/**
* 通过一个int类型的参数来描述妇女的个人状况
* 1--未出嫁
* 2--出嫁
* 3--夫死
*/
class Women implements IWomen{
private int type=0;
//妇女的请示
private String request = "";
//构造函数传递过来请求
public Women(int type,String request){
this.type = type;
switch(this.type){
case 1:
this.request = "女儿的请求是: " + request;
break;
case 2:
this.request = "妻子的请求是: " + request;
break;
case 3:
this.request = "母亲的请求是: " + request;
}
}
//获得自己的状况
public int getType(){
return this.type;
}
//获得妇女的请求
public String getRequest(){
return this.request;
}
}
对于父亲,丈夫和儿子都是处理者,所以设置一个处理者接口:
/** 处理权人员接口 */
abstract class Handler {
public final static int FATHER_LEVEL_REQUEST = 1;
public final static int HUSBAND_LEVEL_REQUEST = 2;
public final static int SON_LEVEL_REQUEST = 3;
//能处理的级别
private int level = 0;
//责任传递, 下一个人责任人是谁
private Handler nextHandler;
//每个类都要说明一下自己能处理哪些请求
public Handler(int level){
this.level = level;
}
public final void HandleMessage(IWomen women){
if(women.getType() == this.level){
this.response(women);
}else{
if(this.nextHandler != null){
}else{
System.out.println("---没地方请示了, 按不同意处理---\n");
}
}
}
/**
如果不属于你处理的请求, 你应该让她找下一个环节的人, 如女儿出嫁了,
* 还向父亲请示是否可以逛街, 那父亲就应该告诉女儿, 应该找丈夫请示
*/
public void setNext(Handler handler){
this.nextHandler = handler;
}
protected abstract void response(IWomen women);
}
接下来分别是三个实现类:
/** 父亲类 */
class Father extends Handler {
//父亲只处理女儿的请求
public Father(){
super(Handler.FATHER_LEVEL_REQUEST);
}
//父亲的答复
protected void response(IWomen women) {
System.out.println("--------女儿向父亲请示-------");
System.out.println(women.getRequest());
System.out.println("父亲的答复是:同意\n");
}
}
/** 丈夫类 */
class Husband extends Handler {
//丈夫只处理妻子的请求
public Husband(){super(Handler.HUSBAND_LEVEL_REQUEST);
}
//丈夫请示的答复
protected void response(IWomen women) {
System.out.println("--------妻子向丈夫请示-------");
System.out.println(women.getRequest());
System.out.println("丈夫的答复是: 同意\n");
}
}
/** 儿子类 */
class Son extends Handler {
//儿子只处理母亲的请求
public Son(){
super(Handler.SON_LEVEL_REQUEST);
}
//儿子的答复
protected void response(IWomen women) {
System.out.println("--------母亲向儿子请示-------");
System.out.println(women.getRequest());
System.out.println("儿子的答复是: 同意\n");
}
}
最后看下客户端是怎么调用的:
public class ResponsibilityDesign {
public static void main(String[] args) {
//随机挑选几个女性
Random rand = new Random();
ArrayList<IWomen> arrayList = new ArrayList();
for(int i=0;i<5;i++){
arrayList.add(new Women(rand.nextInt(4),"我要出去逛街"));
}
//定义三个请示对象
Handler father = new Father();
Handler husband = new Husband();
Handler son = new Son();
//设置请示顺序
father.setNext(husband);
husband.setNext(son);
for(IWomen women:arrayList){
father.HandleMessage(women);
}
}
}
三、装饰模式简介:
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。装饰模式本质上是一个代理模式。
二、装饰模式demo:
作者提供过的装饰模式的demo是以小孩子拿到期末成绩回家请家长签字,但是因为考的较差,所以,通过“润色”的方式将期末考试成绩装潢一下。
首先是成绩单的抽象类和实现类:
/** 抽象成绩单 */
abstract class SchoolReport {
//成绩单主要展示的就是你的成绩情况
public abstract void report();
//成绩单要家长签字, 这个是最要命的
public abstract void sign(String name);
}
/** 具体实现类:四年级成绩单 */
class FouthGradeSchoolReport extends SchoolReport {
//我的成绩单
public void report() {
//成绩单的格式是这个样子的
System.out.println("尊敬的XXX家长:");
System.out.println(" ......");System.out.println(" 语文 62 数学65 体育 98 自然 63");
System.out.println(" .......");
System.out.println(" 家长签名: ");
}
//家长签名
public void sign(String name) {
System.out.println("家长签名为: "+name);
}
}
接下来就是两个装饰类,分别装饰成绩和排名:
/** 装饰最高成绩 */
class HighScoreDecorator extends Decorator {
//构造函数
public HighScoreDecorator(SchoolReport sr){
super(sr);
}
//我要汇报最高成绩
private void reportHighScore(){
System.out.println("这次考试语文最高是75, 数学是78, 自然是80");
}
//我要在老爸看成绩单前告诉他最高成绩, 否则等他一看, 就抡起扫帚揍我, 我哪里还有机会说啊
@Override
public void report(){
this.reportHighScore();
super.report();
}
}
/** 装饰排名 */
class SortDecorator extends Decorator {
//构造函数
public SortDecorator(SchoolReport sr){
super(sr);
}
//告诉老爸学校的排名情况
private void reportSort(){
System.out.println("我是排名第38名...");
}
//老爸看完成绩单后再告诉他, 加强作用
@Override
public void report(){
super.report();
this.reportSort();
}
}
最后来看下客户端的调用:
public class DecoratorDesign {
public static void main(String[] args) {
//把成绩单拿过来
SchoolReport sr;
//原装的成绩单
sr = new FouthGradeSchoolReport();
//加了最高分说明的成绩单
sr = new HighScoreDecorator(sr);
//又加了成绩排名的说明
sr = new SortDecorator(sr);
//看成绩单
sr.report();
//然后老爸一看, 很开心, 就签名了
sr.sign("老三"); //我叫小三, 老爸当然叫老三
}
}
博客参考书籍:秦小波 《设计模式之禅(第2版)》