Monday, December 14, 2015

Simple Java Code Refactoring

Beberapa minggu lalu saya mengikuti semacam training atau workshop tentang android di India. Tentang how to android (pengenalan tentang coding android). Tapi ada satu hal yang membuat saya tertarik, yakni code refactoring, kebetulan yang dipakai adalah Java language. Membuat saya ingin mereview kembali code saya yang sepertinya saya rasa sering salah
Code refaktoring disini dimaksudkan untuk memperbaiki struktur code kita sehingga lebih mudah dipahami, mengurangi kompleksitas dan mungkin bisa lebih reusable (jika bahasanya berbasis Object Oriented). Istilahnya mencegah code kita menjadi sebuah benang kusut yang susah dibaca dan dimengerti orang lain yang mungkin melanjutkannya di kemudian hari. Kadang kadang kalau kita membaca code kita sendiri yang sudah lama, perlu waktu juga untuk memahaminya lagi.
Disini akan saya mencoba sharing beberapa hal yang sifatnya basic saja yang kemaren sempat dibahas. karena refactoring itu luas dan panjang konsepnya.

1.  Naming variable

Untuk membuat nama variable terkadang kita asal saja memberi nama variable dalam suatu class sering asal saja. Seharusnya naming variable itu harus mudah dibaca, dimengerti dan mencerminkan apa isi class tersebut. dan ikutilah naming convention dari bahasa yang bersangkutan.

 public class Employee {  
   public int _id;  
   public String fname;  
   public String lname;  
   public String addr;  
   public String dept;  
 }  

Dari contoh di atas tentu kita mesti menebak-nebak fname, lname, addr, dept itu atribut apa maksudnya. Code di atas bisa diperbaiki jadi seperti ini.

 public class Employee {  
   public int id;  
   public String firstName;  
   public String lastName;  
   public String address;  
   public String department;  
 }  

Jika sudah seperti diatas orang lain yang membaca sekilas pun pasti mudah tau kalau class employee itu atributnya id, firstname, lastname, address dan department.

3. Comment

Comment di sebuah code itu kalo di java istilahnya JavaDoc. Ada baiknya kalo seorang programmer itu memberikan comment atau doc diatas method yang dibuat. Untuk menandakan method itu di dalamnya melakukan apa. Kalau methodnya cuma sekedar logic sederhana atau setter-getter its ok lah, masih gampang dipahami. Kita bisa ambil contoh style code dari library atau framework yang sudah terkenal itu biasanya Doc nya malah lebih panjang dari isi methodnya sendiri. Contohnya seperti di bawah ini (diambil dari :  org.apache.http.impl.client.CloseableHttpClient).

 /**  
    * Executes a request using the default context and processes the  
    * response using the given response handler. The content entity associated  
    * with the response is fully consumed and the underlying connection is  
    * released back to the connection manager automatically in all cases  
    * relieving individual {@link ResponseHandler}s from having to manage  
    * resource deallocation internally.  
    *  
    * @param target  the target host for the request.  
    *         Implementations may accept <code>null</code>  
    *         if they can still determine a route, for example  
    *         to a default target or by inspecting the request.  
    * @param request  the request to execute  
    * @param responseHandler the response handler  
    * @param context  the context to use for the execution, or  
    *         <code>null</code> to use the default context  
    *  
    * @return the response object as generated by the response handler.  
    * @throws IOException in case of a problem or the connection was aborted  
    * @throws ClientProtocolException in case of an http protocol error  
    */  
   public <T> T execute(final HttpHost target, final HttpRequest request,  
       final ResponseHandler<? extends T> responseHandler, final HttpContext context)  
       throws IOException, ClientProtocolException {  
     Args.notNull(responseHandler, "Response handler");  
     final HttpResponse response = execute(target, request, context);  
     final T result;  
     try {  
       result = responseHandler.handleResponse(response);  
     } catch (final Exception t) {  
       final HttpEntity entity = response.getEntity();  
       try {  
         EntityUtils.consume(entity);  
       } catch (final Exception t2) {  
         // Log this exception. The original exception is more  
         // important and will be thrown to the caller.  
         this.log.warn("Error consuming content after an exception.", t2);  
       }  
       if (t instanceof RuntimeException) {  
         throw (RuntimeException) t;  
       }  
       if (t instanceof IOException) {  
         throw (IOException) t;  
       }  
       throw new UndeclaredThrowableException(t);  
     }  
     // Handling the response was successful. Ensure that the content has  
     // been fully consumed.  
     final HttpEntity entity = response.getEntity();  
     EntityUtils.consume(entity);  
     return result;  
   }  

2. Magic number

Magic number (angka ajaib) di sini maksudnya suatu angka yang secara tiba tiba muncul di tengah-tengah code, tanpa tahu maksudnya itu apa. Berikut ini contohnya.

 public class Receipt {  
   private Taxi taxi;  
   public Receipt(Taxi taxi) {  
     this.taxi = taxi;  
   }  
   public double totalTaxiCost(Taxi taxi) {  
     // fixed charges  
     double totalCost = 50;  
     // taxi charges  
     int totalKms = taxi.getTotalKms();  
     double peakTimeMultiple = taxi.isPeakTime() ? 1.2 : 1.0;  
     if(taxi.isAirConditioned()) {  
       totalCost += Math.min(10, totalKms) * 20 * peakTimeMultiple;  
     } else {  
       totalCost += Math.min(10, totalKms) * 15 * peakTimeMultiple;  
     }  
     return totalCost;  
   }  
 }  

Variable 50, 1.2, 20, 10 dan lainnya itu variable apa?, maksudnya nilai apa?.
Variable diatas mungkin bisa dibuatkan constant value, seperti dibawah ini.

 public class Receipt {  
   public static final int FIXED_CHARGE = 50;  
   public static final double MULTIPLE_PERCENTAGE_PEAK_TIME = 1.2;  
   public static final double MULTIPLE_PERCENTAGE_NON_PEAK_TIME = 1.0;  
   public static final int SALES_TAX = 10;  
   public static final int PRICE_PER_KM_AC = 20;  
   public static final int PRICE_PER_KM_NON_AC = 15;  
   private Taxi taxi;  
   public Receipt(Taxi taxi) {  
     this.taxi = taxi;  
   }  
   public double totalTaxiCost(Taxi taxi) {  
     // fixed charges  
     double totalCost = FIXED_CHARGE;  
     // taxi charges  
     int totalKms = taxi.getTotalKms();  
     double peakTimeMultiple = taxi.isPeakTime() ? MULTIPLE_PERCENTAGE_PEAK_TIME : MULTIPLE_PERCENTAGE_NON_PEAK_TIME;  
     if(taxi.isAirConditioned()) {  
       totalCost += Math.min(SALES_TAX, totalKms) * PRICE_PER_KM_AC * peakTimeMultiple;  
     } else {  
       totalCost += Math.min(SALES_TAX, totalKms) * PRICE_PER_KM_NON_AC * peakTimeMultiple;  
     }  
     return totalCost;  
   }  
 }  


3. Enumeration

Enum di java digunakan sebagai untuk kumpulan contants value yang digunakan untuk mentukan pilihan.

 public class Direction {  
   public static final String NORTH = "NORTH";  
   public static final String SOUTH = "SOUTH";  
   public static final String EAST = "EAST";  
   public static final String WEST = "WEST";  
 }  

Class diatas berisi pilihan tentang arah (direction). Karena tujuan / maksudnya sama. maka bisa di jadikan sebuah Enum. seperti dibawah ini.

 public enum Direction {  
   NORTH,  
   SOUTH,  
   WEST,  
   EAST;  
 }  

4. Test Class coverage

Setiap kali membuat method biasakan juga membuat test class (di Java bisanya menggunakan jUnit).
Bisa untuk mengetest logic kita sudah benar atau belum (menghasilkan result yang diharapkan) dengan berbagai macam inputan.

Selamat mencoba dan semoga bermanfaat.
Terima kasih.

No comments:

Post a Comment