如何评价软件写的好还是坏?

软件自身是一种固化的思维,因此从本质上来看,软件是不可度量的。

但这并不意味着软件不需要度量,而只是说软件中的度量大多都有一定限度。

应用各种度量数据的时候一旦跨过这种限度,结果就会适得其反。


在这篇文章里,我们将考查一下现有的,对软件进行度量的方法(注意:这篇里主要考察别人的方法,不是我自己的)。

可能不全面,不足的地方欢迎大家进行补充。

对软件“直观可见的质量属性”的度量比较简单,比如:Bug率,性能等,这里就不提了。

这里主要关注的是软件的内在的,不直观可见的质量属性。


  • 圈复杂度

圈复杂度主要用于度量函数或方法,从《代码大全》中可以找到圈复杂度的描述。

关于圈复杂度:Tom McCabe曾经建议使用下面的方法来度量复杂度。在这一方法中为了计算复杂度首先要计算子程序中的决策点(decision points),规则如下:

  1. 从函数第一行一致往下通过程序
  2.  一旦遇到以下关键字或者同类的词就加1if,while,repeat,for,and,or
  3.  给case语句中的每一种情况加1                           --Steve McConell 《代码大全》

很多静态分析工具都直接提供对圈复杂度的度量,而圈复杂度本身歧义性很小,是非常难得的指标,高于15的代码基本很难看懂。

但圈复杂度更适合用于度量编码的结果,对高层设计则不太适用。

  • 响应集

响应集是指类的各个方法直接调用的函数数目。响应集无疑的应该尽可能的小,根据得墨忒耳法则:某个对象的任何方法都应该只调用属于以下情形的方法。

         
class Demeter
{
private:
A* a;
int func();
public:
//... 
void example(B& b);
void Demeter::example(B& b)
{
C c;
int f = func(); //<---- 类自己的方法
b.invert(); //<----传入参数的方法,当然参数本身也可能是函数
a = new A();
a->setActive();// <---创建的对象所拥有的方法
c.print(); // <---创建的,并归自己所有的对象的方法
}
};

         --- 摘自《程序员修炼之道》

  • 关系内聚性(H)

在度量包时可以用包内部类的数目除以包内类的总数,其比值用来表示包得内聚性。如果用R表示包内部得类关系数目,用N表示包内类总数。那么:

H = (R+1)/N

  • 不稳定性(I)

不稳定性由输入耦合度(Ca)与输出耦合度(Ce)计算而来。

包得输入耦合度是指处于包外部,但依赖于包内类的数目。

包得输出耦合度是指包内部的依赖于包外部类的类数目。

这样I = Ce / Ca+ Ce)

  • 抽象性(A)

包的抽象性用抽象类的数目和包中所有类的数目进行计算。

假如说包中类的总数是Nc, 抽象类的数目是Na ,那么抽象度A = Na/Nc


关系内聚性(H),不稳定性(H),抽象性(H)的进一步说明,请参见《敏捷软件开发:原则,模式与实践》一书。


这些度量指标无疑是有意义的,都可以用来评价软件写的好还是坏,但却不解决这样一个问题:
如果一个方案在关系内聚性 (H) ,不稳定性 (H) ,抽象性 (H) 上都有好的表现,复杂度有没有提高?如果说复杂度因此而提高了,那么这种额外支出的复杂度值不值得?

如果我们认为复杂度是软件的根本问题,那么在满足需求的前提下,使软件简单化就是最关键的使命(比灵活性等重要)。既如此,究竟应该如何度量软件的复杂度呢?

这是一个需要进一步展开的话题,我完善后会进一步和大家分享。


关联文章:

程序员每天到底可以写几行代码?

软件开发究竟是简单的还是复杂的

软件本质论

------------------------------------------------------------------------------------------------------------------------------------

理想流 + 软件 = 《完美软件开发:方法与逻辑》
理想流 + 人生 = ??
理想流 + 管理 = ??
理想流 = 以概念和逻辑推演本质,追求真理。




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 以下是一个简单的打车软件的shell脚本示例,包括基本的车型选择、距离、时间计算以及支付方式和评价选项。请注意,这只是一个简单的示例,可能需要根据实际需求进行修改和扩展。 ```shell #!/bin/bash # 定义车型和价格 echo "请选择车型:" echo "1. 小轿车(每公里1元)" echo "2. 商务车(每公里2元)" echo "3. 豪华车(每公里5元)" read -p "请输入车型编号:" car_type case $car_type in 1) car_name="小轿车" car_price=1 ;; 2) car_name="商务车" car_price=2 ;; 3) car_name="豪华车" car_price=5 ;; *) echo "无效的车型编号" exit 1 ;; esac # 输入距离和时间 read -p "请输入起点距目的地的公里数:" distance read -p "请输入预计运行时间(分钟):" time # 计算价格 price=$(echo "scale=2; $car_price * $distance" | bc) # 根据时间计算额外费用 if [ $time -gt 30 ]; then extra_time=$(expr $time - 30) extra_price=$(echo "scale=2; $extra_time / 10 * $car_price" | bc) price=$(echo "scale=2; $price + $extra_price" | bc) fi # 输出价格和支付方式 echo "预计费用为:$price 元" echo "请选择支付方式:" echo "1. 现金" echo "2. 支付宝" echo "3. 微信支付" read -p "请输入支付方式编号:" pay_type case $pay_type in 1) pay_name="现金" ;; 2) pay_name="支付宝" ;; 3) pay_name="微信支付" ;; *) echo "无效的支付方式" exit 1 ;; esac # 评价选项 echo "请对本次服务进行评价:" echo "1. 非常满意" echo "2. 满意" echo "3. 一般" echo "4. 不满意" read -p "请输入评价编号:" rating case $rating in 1) rating_name="非常满意" ;; 2) rating_name="满意" ;; 3) rating_name="一般" ;; 4) rating_name="不满意" ;; *) echo "无效的评价编号" exit 1 ;; esac # 输出结果 echo "您选择的车型是:$car_name" echo "起点距目的地的公里数是:$distance 公里" echo "预计运行时间是:$time 分钟" echo "预计费用是:$price 元" echo "您选择的支付方式是:$pay_name" echo "您对本次服务的评价是:$rating_name" ``` 注意:在Linux系统中,需要使用`bc`命令进行浮点数计算。如果您的系统中没有安装`bc`命令,可以使用以下命令进行安装: ```shell sudo apt-get install bc ``` ### 回答2: 打车软件程序是一种利用Shell编程语言编的应用程序,它具有多个功能,包括不同车型选择、计算起点距目的地公里数、计算运行时间、计算金额、选择支付方式和评价等等。 首先,我们可以创建一个车型选择的功能。用户可以通过输入不同的数字来选择不同的车型,比如“1”表示经济型车辆,“2”表示舒适型车辆等等。 接下来,程序可以要求用户输入起点和目的地的公里数,然后通过简单的数学计算来计算出运行距离。例如,假设每1公里收费2元,则可以通过将起点与目的地的公里数相乘来计算出金额。 然后,我们可以计算运行时间。我们可以假设车辆在每小时行驶30公里,通过将运行距离除以每小时行驶的公里数来计算出运行时间。 接下来,程序可以要求用户选择支付方式。用户可以通过输入不同的数字来选择不同的支付方式,比如“1”表示支付宝支付,“2”表示微信支付等等。 最后,用户可以对此次乘车服务进行评价。可以设置一个评价功能,用户可以输入不同的评价等级来评价打车服务的好,比如“1”表示非常差,“5”表示非常好。 通过这个程序,用户可以方便地选择不同的车型、计算距离和时间、选择支付方式并进行评价。这样可以提高用户体验,方便用户进行打车服务,并增加了打车软件的实用性和可扩展性。 ### 回答3: 利用shell编程一个打车软件程序可以如下实现: 1. 首先,定义不同车型的基本信息,例如车辆名称、每分钟计费金额、每公里计费金额等等,存储在一个数组中。 2. 接下来,通过读取用户输入的起点和目的地的公里数,计算出行程的距离,并根据距离调用不同车型的计费规则计算金额。 3. 在计算金额时还需考虑运行的时间,通过读取用户输入的运行时间,根据每分钟计费金额计算出运行时间费用,并添加到总金额中。 4. 完成金额计算后,用户可以选择支付方式,可以使用if语句判断用户选择的支付类型并进行相应的操作。 5. 最后,用户可以对该次乘车进行评价,可以输入评价内容,存储到文件中或打印到终端,这里可以使用echo命令进行实现。 示例代码如下: ```shell #!/bin/bash # 定义车型信息数组 car_models=("经济型" "舒适型" "豪华型") car_rates=(2.5 3.5 4.5) car_km_rates=(1 1.5 2) # 读取用户输入的起点和目的地的公里数 read -p "请输入起点距目的地公里数: " distance # 根据距离调用不同车型的计费规则计算金额 car_model_count=${#car_models[@]} for ((i=0; i<car_model_count; i++)) do rate=$(echo "${car_rates[$i]} * $distance" | bc) if [ $rate -gt 0 ]; then rate=$(echo "scale=2; $rate + ${car_km_rates[$i]} * $distance" | bc) car_model="${car_models[$i]}" break fi done # 读取用户输入的运行时间,计算运行时间费用并添加到总金额中 read -p "请输入运行时间(分钟): " runtime time_rate=$(echo "${car_rates[$i]} * $runtime / 60" | bc) rate=$(echo "scale=2; $rate + $time_rate" | bc) # 选择支付方式 echo "支付方式:" echo "1. 支付宝" echo "2. 微信" echo "3. 现金" read -p "请选择支付方式(输入编号): " payment_type case $payment_type in 1) payment="支付宝" ;; 2) payment="微信" ;; 3) payment="现金" ;; *) payment="未知" ;; esac # 输入评价内容 read -p "请对该次乘车进行评价: " comment # 输出信息 echo "车型: $car_model" echo "起点距目的地公里数: $distance 公里" echo "运行时间: $runtime 分钟" echo "金额: $rate 元" echo "支付方式: $payment" echo "评价: $comment" ``` 运行该脚本后,用户可根据提示输入相关信息,程序将根据输入输出相应的信息,如车型、起点距目的地公里数、运行时间、金额、支付方式、评价等等。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值