设计模式之责任链模式与装饰模式

一、责任链模式简介:
在这里插入图片描述
责任链模式的核心就是“链”,使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。责任链模式的缺点是性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候, 性能是一个非常大的问题。

二、责任链模式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版)》

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值