轻松学习Java设计模式之责任链模式

我们的态度是:每天进步一点点,理想终会被实现。

前言


设计模式,可能很多人都是看到代码知道怎么回事,但是离开代码再让其说出来,估计就有点含糊其词了,包括我自己在内。Android中其实用到的设计模式也是很多,只是大家平时不怎么关注、在意,但是我个人认为这些设计模式我们还是应该学习、了解的,因此有了此文,和大家一起学习,如有错误还望指正。

设计模式之责任链模式


责任链模式定义

什么叫责任链模式?

责任链模式( Chain of
Responsibility):使多个对象都有机会处理同一个请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

我们来看一张图:

这里写图片描述

实际场景:

汽车、房产销售就是属于责任链模式中的一种。
我们的汽车4S店、房产的售楼部,都是这种模式。比如说:假如我去买一辆车,到了4s店,销售人员接到我,选择过程略过;假如我看上了这款车想要一定的打折扣才能买,在销售的阶层中能够给的折扣是一定的,假设4s店有三个阶层:销售人员、销售组长、经理。

例如:销售人员能给出的折扣是<=5%意思是在这个范围内的价格,销售人员就可以直接处理,假如超过这个折扣范围就只能向上报,比如小组长的给出的折扣<=10%都可以,超过这个值就得经理处理,经理能够处理的折扣<=15%。现在我的需求是让这个销售给我12%的折扣,那么销售人员不能处理,他就给你说我上报下我们组长,结果组长也不能处理那就只能经理处理,到经理了可以处理,那么经理就要思考下是否把车卖给我了

其实上面销售去一级一级往上报的过程我是不关心的,我只关心最终的结果,是否给我打折12%。这就是一个责任链模式
这个场景和我们的责任链的定义相符,销售→组长→经理属于一个链,我要求折扣12%的请求,依次传递请求,直到有人处理。

代码实现责任链模式

1.创建打折申请类,让我们的销售、组长、经理都继承这个折扣申请类:

public abstract class DiscountRatify {

   DiscountRatify discountRatify;
   public Context mContext;

   public DiscountRatify(Context mContext) {
       this.mContext = mContext;
   }
   public void setDiscountRatify(DiscountRatify discountRatify) {
       this.discountRatify = discountRatify;
   }

   //处理价格申请
   public abstract void handleDiscount(float discount);

   /**
    * 创建工厂方法
    *
    * @return
    */
   public static DiscountRatify createDiscountRatify(Context mContext) {
       DiscountRatify sales = new Sales(mContext);
       DiscountRatify leader = new Leader(mContext);
       DiscountRatify manager = new Manager(mContext);
       sales.setDiscountRatify(leader);
       leader.setDiscountRatify(manager);
       return sales;
   }
}
  • 这里的Sales、Leader、Manager类就是我们的折扣申请DiscountRatify的实现类,具体就指我们上述场景中的销售、组长、经理;

  • 属性mContext方便后面显示处理折扣的结果

  • 属性discountRatify是我们要向上传递申请

2.创建我们的销售类Sales:

public class Sales extends DiscountRatify {
   private static final String TAG = "Sales";

   public Sales(Context mContext) {
       super(mContext);
   }

   @Override
   public void handleDiscount(float discount) {
       //当打折小于5%的时候,销售人员可以直接处理
       //当大于5%的时候,需要向销售组长申请
       if (discount <= 0.05) {
           ((MainActivity) mContext).setResult(TAG + "处理了打折:" + discount);
       } else {
           //向组长申请
           discountRatify.handleDiscount(discount);
       }
   }
}

我们的销售的处理折扣是小于5%,超过5%就只能想组长申请了。

3.创建Leader类:

public class Leader extends DiscountRatify {
   private static final String TAG = "Leader";

   public Leader(Context mContext) {
       super(mContext);
   }

   @Override
   public void handleDiscount(float discount) {
       //打折10以内,组长处理,超过10%向上申报经理处理
       if (discount <= 0.1) {
           ((MainActivity) mContext).setResult(TAG + "处理了打折:" + discount);
       } else {
           //向上申请
           discountRatify.handleDiscount(discount);
       }
   }
}

和销售一样,组长的权限是能够处理折扣10%之内,超过10%就只能想经理申请了;

4.创建经理类Manager:

public class Manager extends DiscountRatify {
   private static final String TAG = "Manager";

   public Manager(Context mContext) {
       super(mContext);
   }

   @Override
   public void handleDiscount(float discount) {
       if (discount <= 0.15) {
           ((MainActivity) mContext).setResult(TAG + "处理了打折:" + discount);
       } else {
           ((MainActivity) mContext).setResult(TAG + "不能打折: " + discount);
       }
   }
}

经理能处理的就是15%折扣,大于这部分的就不能打折了。

5.最后我们MainActivity类来请求折扣:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
   private DiscountRatify discountRatify;

   private Button button;

   private EditText inputDiscount;

   private TextView result;


   /**
    * 设置销售人员
    *
    * @param discountRatify
    */
   public void setDiscount(DiscountRatify discountRatify) {
       this.discountRatify = discountRatify;
   }

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       button = findViewById(R.id.button);
       inputDiscount = findViewById(R.id.et_discount);
       result = findViewById(R.id.textView);
       button.setOnClickListener(this);
   }

   @Override
   public void onClick(View v) {
       String str = inputDiscount.getText().toString();
       Float discount = Float.valueOf(str);
       requestDiscount(discount);
   }

   /**
    * 向销售人员请求打折
    *
    * @param discount
    */
   private void requestDiscount(float discount) {
       //1.找到一个销售人员
       this.setDiscount(DiscountRatify.createDiscountRatify(this));
       //2.处理我的打折信息
       discountRatify.handleDiscount(discount);
   }

   /**
    * 返回处理结果
    * @param resultStr
    */
   public void setResult(String resultStr) {
       if (!TextUtils.isEmpty(resultStr)) {
           result.setText(resultStr);
       }
   }
}

布局文件:
这里写图片描述
最后我们输入我们的折扣,就可以得到输入结果:
这里写图片描述
那么在我们这样就简单的把责任链模式给讲解了,可能有很多小伙伴会问你这种设计模式,还不如我使用 if else 简单,确实像这种简单的场景不如if else来的简单粗暴,而且还不易出错。但是假如像一些大公司的层级非常多,而且处理的类型很多的情况就适用了,另外像一些大公司的人员波动很大,假如像我们的当前场景有添加一个店长,处理折扣在组长和经理之间,我们只需要添加一个店长Shopowner类,处理折扣逻辑写好。在创建工厂出添加一行代码:

public abstract class DiscountRatify {

  DiscountRatify discountRatify;
  public Context mContext;

  public DiscountRatify(Context mContext) {
      this.mContext = mContext;
  }
  public void setDiscountRatify(DiscountRatify discountRatify) {
      this.discountRatify = discountRatify;
  }

  //处理价格申请
  public abstract void handleDiscount(float discount);

  /**
   * 创建工厂方法
   *
   * @return
   */
  public static DiscountRatify createDiscountRatify(Context mContext) {
      DiscountRatify sales = new Sales(mContext);
      DiscountRatify leader = new Leader(mContext);
      DiscountRatify shop = new Shopowner(mContext);
      DiscountRatify manager = new Manager(mContext);
      sales.setDiscountRatify(leader);
      leader.setDiscountRatify(shop);
      shop.setDiscountRatify(manager);
      return sales;
  }
}

这样简洁的就能处理,可扩展性很好,这就是我们的责任链模式了。

责任链模式优点:

  • 代码清晰,请求者和处理者松散耦合
  • 处理者动态组合
  • 可扩展性强

责任链模式缺点:

  • 产生了很多对象,占用了内存,这是个很大的缺点。
  • 既然我们的定义都说了,处理者是一条链,那么在处理请求的时候要去遍历这条链,直到有人处理结束;执行时间、效率肯定是相对单个处理要差。
  • 假如像上面的场景,我折扣是5%,那么只有sales对象使用到了,链上的Leader、Manager的对象都未使用到,说明浪费内存。

正是因为责任链模式的缺点,所以我们使用的很少,但是我们应该需要知道了解Android系统中哪些使用了责任链模式:

  • try catch 异常捕获,当第一个catch不匹配直接跳到第二个catch。
  • 我们的出名的网络请求okHttp中的拦截器Intercepter就是使用的责任链模式,我们可以拦截打印自定义Log、设置缓存、加密、防串改等

一句话总结


这种模式可能我们平常使用的不多,但是我们作为一个开发者,还是有必要知道了解,我们选择使用的时候多结合实际项目中来做抉择。另外,假如面试遇到了,也能吹吹逼,加分项。

温馨提示:

我创建了一个技术交流群,群里有各个行业的大佬都有,大家可以在群里畅聊技术方面内容,以及文章推荐;如果有想加入的伙伴加我微信号【luotaosc】备注一下“加群”
另外关注公众号,还有一些个人收藏的视频: 回复“Android” ,获取Android视频链接。 回复“Java” ,获取Java视频链接。
回复“C++” ,获取C++视频链接。 回复“C” ,获取C视频链接。 回复“Python” ,获取Python视频链接等等。

原创文章不易,如果觉得写得好,扫码关注一下点个赞,是我最大的动力。
关注我,一定会有意想不到的东西等你:
每天专注分享Android干货
这里写图片描述
备注:程序圈LT

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值