小酌重构系列[20]——用条件判断代替异常

概述

异常处理的关键在于何时处理异常以及如何使用异常,有些开发者会觉得try catch的处理和使用难以把握,于是他们秉承着“您可错杀一千,不可放过一个”的想法,给所有的方法添加try catch。

这种方式会对应用程序造成什么影响吗?

从用户角度出发,用户确实难以察觉到什么,应用程序运行正常,使用的体验好像也没什么差别。

从程序角度出发,大量的try catch会降低代码的可读性,只有在异常触发时才会对程序的性能造成较大的影响。

这两种角度有对错吗?

二者都没有错,第一种角度甚至要远远高于第二种角度。

对于程序员来说,写程序开发产品的最终目的不是为了在技术上吹毛求疵,而是为了满足市场和用户的业务需求,用户并不关心产品的内部实现——用户觉得好的产品,是真正的好产品。

我们不必纠结于这两种角度的处理方式,适合自己的才是最佳的。

但是一些场景下确实不宜使用try catch

  1. 流程控制语句:流程控制有它本身的逻辑,我们应该用判断来规避try catch语句块的使用
  2. 循环控制语句:一次catch对性能的影响是较小的,但在循环中却可以积少成多,因此可能会产生较大的性能损失。

本文的主题“用条件判断代替异常”是针对场景1的,当使用try catch来控制程序流程时,如果程序中不存在“危险”代码(例如:类型转换、建立连接等),就没有必要使用try catch,我们可以直接使用条件判断来控制程序流程。

异常不发生的时候,只是给程序套了一层try{}语句块,对性能的影响微乎其微。
当异常发生的时候,进入catch语句块,CLR需要创建异常对象,保存堆栈信息,逐层查找异常表,这会较大地影响程序的性能。

异常处理是一个较大的课题,也是程序设计的一个横切关注点,本文不会对此进行深入的说明。

示例

重构前

下面这段代码表示“微波炉当前如果没有被使用,那么我们就可以用它加热食物”。

public class Microwave
{
    private IMicrowaveMotor Motor { get; set; }

    public bool Start(object food)
    {
        bool foodCooked = false;
        try
        {
            Motor.Cook(food);
            foodCooked = true;
        }
        catch (InUseException)
        {
            foodcooked = false;
        }

        return foodCooked;
    }
}

这段代码通过是否触发自定义异常InUseException,来决定方法Start()方法的返回值,这是典型的使用try catch语句块来控制流程的做法。

catch语句块捕获了InUseException,却没有处理InUseException,这不仅损失了程序的性能,也未体现自定义异常InUseException的价值。
这仅仅是一个常见的逻辑判断,我们用条件判断就可以了。

重构后

重构以后,代码的可读性增强了,还消除了捕捉异常带来的性能损失。

public class Microwave
{
    private IMicrowaveMotor Motor { get; set; }

    public bool Start(object food)
    {
        if (Motor.IsInUse)
            return false;

        Motor.Cook(food);

        return true;
    }
}
关注keepfool
要在Vue2项目中使用vue-chartjs,需要先安装以下依赖: ```bash npm install vue-chartjs chart.js ``` 然后在需要使用图表的组件中,引入vue-chartjs并注册组件: ```javascript import { Line } from 'vue-chartjs' export default { extends: Line, mounted () { this.renderChart({ labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], datasets: [ { label: 'Data One', backgroundColor: '#f87979', data: [40, 39, 10, 40, 39, 80, 40] } ] }, {responsive: true, maintainAspectRatio: false}) } } ``` 这里用Line为例,如果需要使用其他类型的图表,只需要替换掉对应的组件名即可。在mounted函数中,我们可以通过调用`this.renderChart`方法来渲染图表,传入的第一个参数是图表的数据,第二个参数是配置项。 当然,你也可以在组件中定义自己的数据和配置项,然后在mounted函数中调用`this.renderChart`方法来渲染图表,例如: ```javascript import { Line } from 'vue-chartjs' export default { extends: Line, data () { return { chartData: { labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], datasets: [ { label: 'Data One', backgroundColor: '#f87979', data: [40, 39, 10, 40, 39, 80, 40] } ] }, chartOptions: { responsive: true, maintainAspectRatio: false } } }, mounted () { this.renderChart(this.chartData, this.chartOptions) } } ``` 这里我们将图表的数据和配置项定义在了组件的data中。 最后,在需要使用该组件的地方,直接引入即可: ```html <template> <div> <my-chart></my-chart> </div> </template> <script> import MyChart from './MyChart.vue' export default { components: { MyChart } } </script> ``` 这样就可以在Vue2项目中使用vue-chartjs了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值