程式扎記: [ 文章收集 ] Groovy hip tip: to use or not to use setters and getters

標籤

2015年7月15日 星期三

[ 文章收集 ] Groovy hip tip: to use or not to use setters and getters

Source From Here 
Preface 
In Groovy, if you define a hip object with properties, you can access them directly; that is, you don’t have to define the bogue old-style setters and getters that we were all taught to do back in the day with Java. For example, imagine a simple object defined in Groovy like so: 
  1. class Loan {  
  2. def balance  
  3. def term  
  4. def rate  
  5. }  
If you’d like to directly set the value of balance, for example, you could write: 
  1. def loan = new Loan()  
  2. loan.balance = 30000  
Groovy's automatic getter & setter 
Note how the property was accessed directly as if it were public, but in fact, it’s private as the following copacetic test demonstrates: 
  1. import java.lang.reflect.Modifier  
  2. import groovy.util.GroovyTestCase  
  3.   
  4. class LoanTest extends GroovyTestCase{  
  5. void testLoanBalanceModifier(){  
  6.   def loan = new Loan()  
  7.   loan.balance = 30000  
  8.   assertEquals(30000, loan.balance)  
  9.   
  10.   def field = Loan.class.getDeclaredField("balance")  
  11.   assertEquals(true, Modifier.isPrivate(field.modifiers))  
  12. }  
  13. }  
What’s more, even if you do define a setter, you don’t actually have to call it — Groovy will do that for you. For example, I can add the following setter method to the Loan object like so: 
  1. class Loan {  
  2.     def balance  
  3.     def term  
  4.     def rate  
  5.   
  6.     void setRate(rate){  
  7.         if(rate > 0.99){  
  8.             this.rate = rate/100  
  9.         }else{  
  10.             this.rate = rate  
  11.         }  
  12.     }  
  13. }  
And the following tests prove that under the covers, Groovy leveraged the setter properly, even though I don’t actually call the setter directly: 
  1. import groovy.util.GroovyTestCase  
  2.   
  3. class AnotherLoanTest extends GroovyTestCase{  
  4.     void testLoanRate(){  
  5.         def loan = new Loan()  
  6.         loan.rate = 3  
  7.         assertEquals(0.03, loan.rate)  
  8.     }  
  9.   
  10.     void testLoanRateAgain(){  
  11.         def loan = new Loan()  
  12.         loan.rate = 0.03  
  13.         assertEquals(0.03, loan.rate)  
  14.     }  
  15. }  
This handy no-setter (or no-getter) syntax also works with plain old Java objects; that is, if you have a Java object that has private properties and setters and getters for accessing them, you can still directly access them Groovy-style. For instance, here is the same Loan object defined in Java: 
  1. import java.math.BigDecimal;  
  2.   
  3. public class Loan {  
  4.     private BigDecimal balance;  
  5.     private int term;  
  6.     private float rate;  
  7.   
  8.     public BigDecimal getBalance() {  
  9.         return balance;  
  10.     }  
  11.   
  12.     public void setBalance(BigDecimal balance) {  
  13.         this.balance = balance;  
  14.     }  
  15.       
  16.     //...all other setters and getters left out of example  
  17. }  
As the below test shows, when using this Java object in Groovy, you can omit invoking setBalance for example: 
  1. def loan = new Loan() //java object  
  2. loan.balance = 30000  
  3. printf("loan.balance=%s", loan.balance)  
In fact, like before with the Groovy defined Loan, Groovy will invoke the getter or setter for that property defined in the Java class. 

Clearly, the ability to seemingly access properties cuts down on the amount of code one must write; plus, the perceived safety and encapsulation that these methods provide is still present. Not bad, eh baby?

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!