リーダブルコード実践 第二弾 ~Vol.3~

今回はロジックを書き直して読みやすくします。

//商品クラス
var CartItem = function(cart_no, goods_id, unit_price, goods_num, price, tax_rate, tax, price_with_tax) {
    this.cart_no        = cart_no;
    this.goods_id       = goods_id;
    this.unit_price     = unit_price;
    this.goods_num      = goods_num;
    this.price          = price;
    this.tax_rate       = tax_rate;
    this.tax            = tax;
    this.price_with_tax = price_with_tax;
}

//カートクラス
var Cart = function() {
    this.latest_cart_no = 0;
    this.cart_items     = [];

    this.Add = function(goods_id, unit_price, goods_num) {
        if (goods_id === "") {
            CommonFunc.ShowError("商品を指定してください。");
            return;
        }
        if (goods_num < 1) {
            CommonFunc.ShowError("数量は1以上を入力してください。");
            return;
        }

        var price    = unit_price * goods_num;
        var tax_rate = CommonFunc.TaxRate(Date.now(), goods_id);
        var tax      = price * tax_rate;

        this.cart_items[this.cart_items.length] = new CartItem(
            this.NewCartNo(),
            goods_id,
            unit_price,
            goods_num,
            price,
            tax_rate,
            tax,
            price + tax
        );
    }

    this.ChangeGoodsNum = function(cart_no, goods_num) {
        var cart_idx = this.IndexOf(cart_no);

        if (cart_idx < 0) {
            CommonFunc.ShowError("商品が存在しません。");
            return;
        }
        if (goods_num < 1) {
            CommonFunc.ShowError("数量は1以上を入力してください。");
            return;
        }

        //数量を変更したら消費税・金額を再計算する。
        var price = this.cart_items[cart_idx].unit_price * goods_num;
        var tax   = price * this.cart_items[cart_idx].tax_rate;

        this.cart_items[cart_idx].goods_num      = goods_num;
        this.cart_items[cart_idx].price          = price;
        this.cart_items[cart_idx].tax            = tax;
        this.cart_items[cart_idx].price_with_tax = price + tax;
    }

    this.Remove = function(cart_no) {
        var cart_idx = this.IndexOf(cart_no);

        if (cart_idx < 0) {
            CommonFunc.ShowError("商品が存在しません。");
            return;
        }

        this.cart_items.splice(cart_idx, 1);
    }

    this.TotalPriceWithTax = function() {
        var total_price_with_tax = 0;

        for (var i = 0; i < this.cart_items.length; i++)
            total_price_with_tax += this.cart_items[i].price_with_tax;

        return CommonFunc.ToMoney(total_price_with_tax);
    }

    this.NewCartNo = function() {
        return ++this.latest_cart_no;
    }

    this.IndexOf = function(cart_no) {
        for (var i = 0; i < this.cart_items.length; i++) {
            if (this.cart_items[i].cart_no === cart_no)
                return i;
        }
        return -1;
    }
}

//共通関数クラス
CommonFunc = {
    TaxRate: function(target_date, goods_id) {
        if (target_date >= "2019/10/01") {
            //軽減税率対象商品なら8%
            if (this.IsReducedTaxRateGoods(goods_id))
                return 0.08;
            else
                return 0.1;
        }
        else if (target_date >= "2014/04/01") {
            return 0.08;
        }
        else if (target_date >= "1997/04/01") {
            return 0.05;
        }
        else if (target_date >= "1989/04/01") {
            return 0.03;
        }
        else {
            return 0;
        }
    },

    IsReducedTaxRateGoods: function(goods_id) {
        return goods_id.substr(0, 3) === "RTR";
    },

    ToMoney: function(price) {
        return "¥" + String(price).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
    },

    ShowError: function(msg) {
        console.log("Error: " + msg);
    }
}

※変更点は省略します。

重複したコードや本題とは関係ないコードをメソッド化してかなり読みやすくなりました。でもまだ読みにくい。次回はロジックを見直してさらに読みやすくします。

この記事が気に入ったらサポートをしてみませんか?