Uzun metotları daha okunabilir ve kompak hale getirmek için Extract Method refactoring metodunu kullanabiliriz.
private Double calculatePrice(double price, String locale) { Double result; double taxRate = 0; if (isCountryGermany(locale)) { taxRate = TAX_RAT_GERMANY; } else if (isCountryTurkishRepublic(locale)) { taxRate = TAX_RAT_TURKISH_REPUBLIC; } Double tax = Double.valueOf( (price / 100) * taxRate); result = Double.valueOf(tax.doubleValue() + price); return result; }
calculatePrice metodu bünyesinde ülkeye bağlı olarak katma deger vergisi oranı (taxRate) tespit edilmektedir. Bu işlemi aşağıdaki şekilde başka bir metot bünyesine alarak, calculatePrice metodunu küçültebiliriz.
private Double calculatePrice(double price, String locale) { Double result; double taxRate = 0; taxRate = getTaxRateBasedOnCountry(locale); Double tax = Double.valueOf( (price / 100) * taxRate); result = Double.valueOf(tax.doubleValue() + price); return result; } private double getTaxRateBasedOnCountry(String locale) { double taxRate = 0.0; if (isCountryGermany(locale)) { taxRate = TAX_RAT_GERMANY; } else if (isCountryTurkishRepublic(locale)) { taxRate = TAX_RAT_TURKISH_REPUBLIC; } return taxRate; }
Bu refactoring metodunu kullanırken seçtiğimiz metot isimlerinin, işlemin nasıl yapıldığını değil, hangi işlemin yapıldığını yansıtmasına dikkat etmemiz gerekmektedir. Bu kodun okunmasını kolaylaştıracaktır. Uzunda olsa yapılan işlemleri tanımlayan metot isimleri kullanmaktan kaçınmamamız gerekmektedir.
Yeni oluşturulan metodun küçük tutulmasında fayda vardır. Bu, yeni metodun başka bir metot bünyesinde tekrar kullanım şansını artıracaktır.
Eğer uzun bir metodun bu şekilde parçalarına bölünmesi okunurluluğu ve kodun anlaşılma seviyesini artırıyorsa Extract Method refactoring metodu kullanılmalıdır.
Bu refactoring işleminin ardından bile calculatePrice metodunu daha da kompak hale getirme potansiyeli vardır. calculatePrice metodunu aşağıdaki şekilde tekrar refactor etmeye ne dersiniz?
private Double calculatePrice(double price, String locale) { double taxRate = getTaxRateBasedOnCountry(locale); return getCalculatedPriceWithTax(price, taxRate); } private Double getCalculatedPriceWithTax(double price, double taxRate) { Double result; Double tax = Double.valueOf( (price / 100) * taxRate); result = Double.valueOf(tax.doubleValue() + price); return result; } private double getTaxRateBasedOnCountry(String locale) { double taxRate = 0.0; if (isCountryGermany(locale)) { taxRate = TAX_RAT_GERMANY; } else if (isCountryTurkishRepublic(locale)) { taxRate = TAX_RAT_TURKISH_REPUBLIC; } return taxRate; }
Şimdi calculatePrice metodunun eski ve yeni halini bir kıyaslayalım. Hangi metot size ilk bakışta ne yaptığını daha kolay anlatıyor?
Eski hali:
private Double calculatePrice(double price, String locale) { Double result; double taxRate = 0; if (isCountryGermany(locale)) { taxRate = TAX_RAT_GERMANY; } else if (isCountryTurkishRepublic(locale)) { taxRate = TAX_RAT_TURKISH_REPUBLIC; } Double tax = Double.valueOf( (price / 100) * taxRate); result = Double.valueOf(tax.doubleValue() + price); return result; }
Yeni hali:
private Double calculatePrice(double price, String locale) { double taxRate = getTaxRateBasedOnCountry(locale); return getCalculatedPriceWithTax(price, taxRate); }
calculatePrice metodunda gördüğümüz gibi oluşturdugumuz metotlar 4-5, en fazla 6-7 satırı geçmemelidir. Bu kurala uyduğumuz taktirde aşağıda yer aldığı gibi, okunması, bakımı ve geliştirilmesi çok kolay sınıflar oluşur.
package com.kurumsaljava.refactoring.extractmethod; public class TaxCalculator { private static final String LOCALE_DE = "de_DE"; private static final String LOCALE_TR = "tr_TR"; private static final double TAX_RAT_GERMANY = 19.00; private static final double TAX_RAT_TURKISH_REPUBLIC = 18.00; private static final Double NULL_VALUE_DOUBLE_OBJECT = new Double(0); public Double calculate(String locale, double price) { return calculateBasedOnLocale(locale, price); } private Double calculateBasedOnLocale(String locale, double price) { if (isCountryGermany(locale)) { return calculatePrice(price, locale); } else if (isCountryTurkishRepublic(locale)) { return calculatePrice(price, locale); } else return NULL_VALUE_DOUBLE_OBJECT; } private Double calculatePrice(double price, String locale) { double taxRate = getTaxRateBasedOnCountry(locale); return getCalculatedPriceWithTax(price, taxRate); } private Double getCalculatedPriceWithTax(double price, double taxRate) { Double tax = Double.valueOf( (price / 100) * taxRate); return Double.valueOf(tax.doubleValue() + price); } private double getTaxRateBasedOnCountry(String locale) { if (isCountryGermany(locale)) { return TAX_RAT_GERMANY; } else if (isCountryTurkishRepublic(locale)) { return TAX_RAT_TURKISH_REPUBLIC; } else return NULL_VALUE_DOUBLE_OBJECT.doubleValue(); } private boolean isCountryGermany(String locale) { return locale != null && locale.equals(LOCALE_DE); } private boolean isCountryTurkishRepublic(String locale) { return locale != null && locale.equals(LOCALE_TR); } }
Refactoring için çıkış noktamız aşağıdaki sınıftı. Umarım Extract Method refactoring metodunun ne kadar kıymetli bir araç olduğunu gösterebilmişimdir :)
package com.kurumsaljava.refactoring.extractmethod; public class TaxCalculatorOld { public Double calculate(String locale, double price) { Double result = new Double(0); double taxRate = 0; if (locale != null && locale.equals("de_DE")) { taxRate = 19.00; Double tax = Double.valueOf( (price / 100) * taxRate); result = Double.valueOf(tax.doubleValue() + price); } else if (locale != null && locale.equals("tr_TR")) { taxRate = 18.00; Double tax = Double.valueOf( (price / 100) * taxRate); result = Double.valueOf(tax.doubleValue() + price); } return result; } }
Geri izleme: Refactoring Oturumu (Video) - Kurumsal Java Yazılımı
Geri izleme: Metodu Metot Nesnesine Dönüştürme (Replace Method with Method Object) - Kurumsal Java Yazılımı