iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 15
2
Software Development

[Andriod] Andriod Studio 從入門到進入狀況系列 第 15

[Day 14] 我的第一個Android程式 - BMI程式設計(九) 應用程式的重構

  • 分享至 

  • xImage
  •  

今天原本是要分享Android元件觸發事件的四種方法,
不過忽然發現我應該要先講重構這個部分之後,
再去講觸發事件的方法,
那到底什麼是重構呢?

當一段程式被寫出來之後,我們要做的事,就是修改它與維護它。一旦程式越長越複雜,混亂到無法維護的境界時,就只好砍掉重練。所以,若我們能夠透過某些方式,例如重新組織或部分改寫程式碼,好讓程式再次變得容易維護,我們就可以為自己省下許多時間,接受更多挑戰。
「將程式碼做更動以增加可讀性或是簡化結構,而不影響輸出結果」的過程,有個專有名詞稱為「重構」。「重構」的方法就是在一次次檢查程式碼的過程中,透過一些小修改,讓程式的閱讀與運作都變得更順暢。
平常就習慣把平凡的「重構」做好一點點,長久累積,自然會形成好的程式。

以下是這個程式重構之後的結果,
在此只列出Java檔案的部分,

package com.example.user.mybmi;

import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.LocaleList;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.text.DecimalFormat;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //取得控制項物件
        initViews();
        //設定監聽事件
        setListensers();
    }

    private Button button_calc;
    private EditText num_height;
    private EditText num_weight;
    private TextView show_result;
    private TextView show_suggest;

    //取得控制項物件
    private void initViews()
    {
        button_calc = (Button)findViewById(R.id.button);
        num_height = (EditText)findViewById(R.id.height);
        num_weight = (EditText)findViewById(R.id.weight);
        show_result = (TextView)findViewById(R.id.result);
        show_suggest = (TextView)findViewById(R.id.suggest);
    }

    //設定監聽事件
    private void setListensers()
    {
        button_calc.setOnClickListener(calcBMI);
    }

    private OnClickListener calcBMI = new OnClickListener() {
        @Override
        public void onClick(View v) {
            DecimalFormat nf = new DecimalFormat("0.00");
            //身高
            double height = Double.parseDouble(num_height.getText().toString())/100;
            //體重
            double weight = Double.parseDouble(num_weight.getText().toString());
            //計算出BMI值
            double BMI = weight / (height*height);

            //結果
            show_result.setText(getText(R.string.bmi_result) + nf.format(BMI));

            //建議
            if(BMI > 25) //太重了
                show_suggest.setText(R.string.advice_heavy);
            else if(BMI < 20) //太輕了
                show_suggest.setText(R.string.advice_light);
            else //剛剛好
                show_suggest.setText(R.string.advice_average);
        }
    };
}

在這裡我們可以看到,
我們把元件的宣告都放在一起,

private Button button_calc;
private EditText num_height;
private EditText num_weight;
private TextView show_result;
private TextView show_suggest;

Create之後第一件事,
就是先取得控制項的物件

initViews();
private void initViews()
{
    button_calc = (Button)findViewById(R.id.button);
    num_height = (EditText)findViewById(R.id.height);
    num_weight = (EditText)findViewById(R.id.weight);
    show_result = (TextView)findViewById(R.id.result);
    show_suggest = (TextView)findViewById(R.id.suggest);
}

接下來就要定義監聽事件

setListensers();
private void setListensers()
{
    button_calc.setOnClickListener(calcBMI);
}

以下是按鈕點擊後的事件

private OnClickListener calcBMI = new OnClickListener() {
    @Override
    public void onClick(View v) {
        DecimalFormat nf = new DecimalFormat("0.00");
        //身高
        double height = Double.parseDouble(num_height.getText().toString())/100;
        //體重
        double weight = Double.parseDouble(num_weight.getText().toString());
        //計算出BMI值
        double BMI = weight / (height*height);

        //結果
        show_result.setText(getText(R.string.bmi_result) + nf.format(BMI));

        //建議
        if(BMI > 25) //太重了
            show_suggest.setText(R.string.advice_heavy);
        else if(BMI < 20) //太輕了
            show_suggest.setText(R.string.advice_light);
        else //剛剛好
            show_suggest.setText(R.string.advice_average);
    }
};

這樣子整個程式就會變得比較有架構,
將宣告跟方法分開,
未來如果要改程式,
也會比較容易修改,

-- 後記
有時候我會在 initViews(); 後面再加一個 initDatas();
用來定義元件的初始資料及我們要設定的系統值,
當然重構的方式不是只有一種,
不過一兩年前看到的文章跟這一次看到的,
好像都是建議這樣子做,
我自己覺得用起來也還蠻順的,
暫時就不打算去做其他的思考了.


上一篇
[Day 13] 我的第一個Android程式 - BMI程式設計(八) 程式碼補充說明
下一篇
[Day 15] Android程式設計番外篇 - 元件觸發事件的四種方法(一)
系列文
[Andriod] Andriod Studio 從入門到進入狀況33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
ws11017999
iT邦新手 5 級 ‧ 2019-08-16 11:08:08

小魚大大你好
DecimalFormat nf = new DecimalFormat("0.00");
這段是什麼意思@@???

小魚 iT邦大師 1 級 ‧ 2019-08-16 23:22:39 檢舉

其實, 你可以請教一下谷先生.

0
justin103
iT邦新手 5 級 ‧ 2021-09-20 21:06:15

https://ithelp.ithome.com.tw/upload/images/20210920/20142255zUra1vFKMK.png

不好意思 小弟最近剛接觸 基礎還很不夠 想問一下為啥這邊要加分號

小魚 iT邦大師 1 級 ‧ 2021-09-20 21:20:56 檢舉

一個function的結尾吧,
Java我現在比較少碰了,
有的語言是可加可不加.

我要留言

立即登入留言