Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Lap trinh java hieu qua

888 views

Published on

Effective Java

Published in: Engineering
  • Be the first to comment

Lap trinh java hieu qua

  1. 1. VN- L P TRÌNH JAVA HI UẬ Ệ QUẢ Tác gi : Joshua Blochả Trình bày: Lê Qu c Anhố 30-05-2015 VN-
  2. 2. Có nh n xét gì v đo n code này ?ậ ề ạ … List<Integer> lst = new ArrayList<Integer>(); Iterator<Integer> iter = lst.iterator(); while (iter.hasNext()) { // ... iter.remove(); } … Lst.Size() 2 Running timeNgu n: Murex Testồ
  3. 3. 3 Có gì khác nhau? … List<Integer> lst = new ArrayList<Integer>(); Iterator<Integer> iter = lst.iterator(); while (iter.hasNext()) { // ... iter.remove(); } … … List<Integer> lst = new LinkedList<Integer>(); Iterator<Integer> iter = lst.iterator(); while (iter.hasNext()) { // ... iter.remove(); } …
  4. 4. So sánh th i gian th c hi n removeờ ự ệ size=1000: time =166 ms size=1000: time =57 ms size=10000: time =8167 ms size=10000: time =60 ms Lst.Size() 4 Running time Lst.Size() Running time ArrayList LinkedList
  5. 5. 5 Nguyên nhân ArrayList LinkedList
  6. 6. 6 Nguyên nhân LinkedList<E> ArrayList<E> Get (idx) O(n) O(1) Add(e) O(1) O(1) Add(idx, e) O(n) O(n-idx) Remove(idx) O(n) O(n-idx) Iterator.remove() O(1) O(n-idx) ListIterator.add(e) O(1) O(n-idx)
  7. 7. L p trình hi u quậ ệ ả 7 Yêu c u chungầ -dễ đọc -dễ bảo trì -dễ mở rộng Yêu c u riêng:ầ -V n d ng ngôn ngậ ụ ữ -K thu tỹ ậ l p trìnhậ
  8. 8. 8
  9. 9. PH N 1: T O VÀ H Y Đ IẦ Ạ Ủ Ố T NGƯỢ 9
  10. 10. Quy t c 1: Dùng hàm g i đ i t ngắ ọ ố ượ • Đ nh nghĩa: Là hàm tr l i m t đ i t ng c a l p.ị ả ạ ộ ố ượ ủ ớ public static Boolean valueOf(boolean b) {return b ? Boolean.TRUE : Boolean.FALSE;} • L i ích:ợ – Không c n ph i kh i t o l p m i l n g iầ ả ở ạ ớ ỗ ầ ọ – G i đ n cùng m t đ i t ng (ví d Singleton ph n sau)ọ ế ộ ố ượ ụ ở ầ – D đ c (hàm có tên g i, rút g n tham s , etc..). Ví d :ễ ọ ọ ọ ố ụ •Cách bình th ng: Map<String, List<String>> m=new HashMap<String, List<String>>();ườ •V i hàm kh i t o: Map<String, List<String>> m=HashMap.newInstance();ớ ở ạ • Quy c:ướ – l p ch a hàm ki u này không nên đ c kh i t o tr c ti p n a, vì đã có hàm kh i t o và trớ ứ ể ượ ở ạ ự ế ữ ở ạ ả l i đ i t ng c a l p r i. Do v y l p ho c constructor c a l p đ c khai báo private.ạ ố ượ ủ ớ ồ ậ ớ ặ ủ ớ ượ – N u đ i t ng tr v có tên g i là Type thì l p ch a hàm factory s có tên là Types. Ví dế ố ượ ả ề ọ ớ ứ ẽ ụ public interface book { public void cover(); } public abstract class Books() { public static Book createBook(){ return new MyBook(); } private class MyBook implements Book{ public void cover(){} } } 10
  11. 11. Quy t c 1: Dùng hàm g i đ i t ngắ ọ ố ượ • Đi m h n ch :ể ạ ế – L p ch a các static factory methods không cho phépớ ứ k th a. Ví d không th k th a l pế ừ ụ ể ế ừ ớ java.util.Collections (theo quy c l p này có giaoướ ớ di n tên là java.util.Collection không có s). Nguyênệ nhân là đ các l p trình viên nên dùng compositionể ậ thay vì inheritance mà ta s xem trong Quy t c 16.ẽ ắ – Không có s khác bi t rõ ràng gi a các hàm staticự ệ ữ factory methods và các static factory khác. 11
  12. 12. Quy t c 2: Dùng builder cho l p cóắ ớ nhi u tham sề ố • Xem xét l p:ớ public class NutritionFacts { private final int servingSize; // (mL) required private final int servings; // (per container) required private final int calories; // optional private final int fat; // (g) optional private final int sodium; // (mg) optional private final int carbohydrate; // (g) optional … } NutritionFacts cocaCola = new NutritionFacts(size, serving, calos, fat, sodium, carbo); • H n ch : Nhi u tham s tùy ch n nh ng v n ph i khai báo h t khi kh i t oạ ế ề ố ọ ư ẫ ả ế ở ạ • Gi i pháp 1: Kh i t o đ i t ng và dùng hàm setter.ả ở ạ ố ượ – Ví dụ public void setFat(int val) { fat = val; } – Không kh thi cho l p b t bi nả ớ ấ ế • Gi i pháp 2: Dùng l p trung gian builder đ tùy ch n khai báo tham sả ớ ể ọ ố public class NutritionFacts { public static class Builder { } } 12
  13. 13. Quy t c 2: Dùng builder cho l p cóắ ớ nhi u tham sề ố public class NutritionFacts { … public static class Builder { private final int servingSize; // b t bu cắ ộ private int calories = 0; // tùy ch n, kh i t o v i giá tr m c đ nhọ ở ạ ớ ị ặ ị private int fat = 0; // tùy ch n, kh i t o v i giá tr m c đ nhọ ở ạ ớ ị ặ ị public Builder(int servingSize) {this.servingSize = servingSize; } public Builder calories(int val) { calories = val; return this; } public Builder fat(int val) { fat = val; return this; } public NutritionFacts build() {return new NutritionFacts(this); } } private NutritionFacts(Builder builder) { servingSize = builder.servingSize; calories = builder.calories; … } NutritionFacts cocaCola = new NutritionFacts.Builder(240). calories(100).fat(35).build(); 13
  14. 14. Quy t c 3:Xây d ng l p Singleton v iắ ự ớ ớ ki u Enumể • Câu h i: Singleton khác v i l p b t bi n???ỏ ớ ớ ấ ế • Đ nh nghĩa: L p ch đ c kh i t o 1 l n duy nh t. Ví d :ị ớ ỉ ượ ở ạ ầ ấ ụ // Singleton with static factory public class Elvis { private static final Elvis INSTANCE = new Elvis(); private Elvis() { ... } public static Elvis getInstance() { return INSTANCE; } public void leaveTheBuilding() { ... } } • Câu h i: Khi l p Singleton th c thi Serializable?ỏ ớ ự 14
  15. 15. Quy t c 3:Xây d ng l p Singleton v iắ ự ớ ớ ki u Enumể // Singleton with static factory public class Elvis implements Serializable { private transient String[] songs= {« a», « b »}; private static final Elvis INSTANCE = new Elvis(); private Elvis() { ... } public static Elvis getInstance() { return INSTANCE; } public void leaveTheBuilding() { ... } // readResolve method to preserve singleton property private Object readResolve() { // Return the one true Elvis and let the garbage collector // take care of the Elvis impersonator. return INSTANCE; } } •Deserialization s g i hàm constructor đ t o ra đ i t ng m i ngay c khi nó đ c khai báo privateẽ ọ ể ạ ố ượ ớ ả ượ •readResolve() bình th ng s tr l i đ i t ng m i đ c t o m i sau khi deserialized => vi t l iườ ẽ ả ạ ố ượ ớ ượ ạ ớ ế ạ • Các thu c tính (eg., version) nên đ c khai báo v i t khóa transient n u giá tr c a chúng không đ iộ ượ ớ ừ ế ị ủ ổ tr c và sau khi serialization ho c chúng có ki u khác primitives.ướ ặ ể 15
  16. 16. Quy t c 3:Xây d ng l p Singleton v iắ ự ớ ớ ki u Enumể • Gi i pháp ng n g n và an toàn h n là dùng Enumả ắ ọ ơ public enum Elvis { INSTANCE; private transient String[] songs= {« a », « b »}; public void leaveTheBuilding() { ... } } • Enum m c đ nh đã th c thi serializableặ ị ự 16
  17. 17. Quy t c 4: C m kh i t o l p v iắ ấ ở ạ ớ ớ private constructor • Đôi khi ta mu n xây d ng l p ch ch a cácố ự ớ ỉ ứ static methods hay static fields • Gi i pháp khai báo l p ki u tr u t ngả ớ ể ừ ượ Abstract không hi u qu vì l p con c a nóệ ả ớ ủ v n có th đ c kh i t oẫ ể ượ ở ạ • Gi i pháp tri t đ là khai báo l p v iả ệ ể ớ ớ private constructor 17
  18. 18. Quy t c 5: Tránh t o đ i t ng th aắ ạ ố ượ ừ • Ví d :ụ String s = new String("stringette"); – Có đ n 2 đ i t ng đ c t o raế ố ượ ượ ạ – T ng đ ng: String s = "stringette";ươ ươ • Gi i pháp chung:ả – S d ngử ụ static factory methods (Quy t c 1)ắ – S d ng ph ng phápử ụ ươ lazy initialization – S d ng ki u bi n primitives (eg., long, int,ử ụ ể ế double) thay vì boxed primitives (eg., Long, Integer, Double) 18
  19. 19. Quy t c 6: Lo i b các tham chi uắ ạ ỏ ế đ n đ i t ng không dùng n aế ố ượ ữ • Xét ví d sau:ụ public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public Object pop() { if (size == 0) throw new EmptyStackException(); Object result = elements[--size]; return result; } 19
  20. 20. Quy t c 6: Lo i b các tham chi uắ ạ ỏ ế đ n đ i t ng không dùng n aế ố ượ ữ • Xét ví d sau:ụ public Object pop() { if (size == 0) throw new EmptyStackException(); Object result = elements[--size]; elements[size] = null; // Eliminate obsolete reference return result; } • Gi i pháp: chú ý gi i pháp b nh khi xâyả ả ộ ớ d ng caches, listeners ho c callbacksự ặ 20
  21. 21. Quy t c 7: Tránh s d ngắ ử ụ finalizers • Đ nh nghĩa: Garbage collector (GC) trong Java ph tráchị ụ gi i phóng các đ i t ng không còn có th đ c s d ngả ố ượ ể ượ ử ụ (unreacheable). Tr c khi gi i phóng đ i t ng thì hàmướ ả ố ượ finalize() c a đ i t ng đó s đ c g i.ủ ố ượ ẽ ượ ọ • S d ng finalizers nguy hi m? Vì sao?ử ụ ể – Không d đoán đ c k t qu : th i gian t lúc m t đ i t ngự ượ ế ả ờ ừ ộ ố ượ thành unreachable cho t i lúc đ c GC x lý là không xác đ nh.ớ ượ ử ị – Ngay c ép ch y GC b ng l nh System.gc vì nó cũng khôngả ạ ằ ệ đ m b o đ finalize() c a đ i t ng đ c th c thi t c th i.ả ả ể ủ ố ượ ượ ự ứ ờ – S d ng finalize() làm tăng th i gian th c hi n lên 430 l n (c nử ụ ờ ự ệ ầ ầ ki m ch ng l i)ể ứ ạ 21
  22. 22. Quy t c 7: Tránh s d ngắ ử ụ finalizers • Gi i phápả – Thay th b ng try..finallyế ằ – Ho c g i l nh System.runFinalizersOnexit ho cặ ọ ệ ặ Runtime.runFinalizersOnExit. Tuy nhiên c 2 hàmả này không còn đ c s d ng (deprecated) b i lýượ ử ụ ở do nó có th đ c g i ngay c v i đ i t ngể ượ ọ ả ớ ố ượ reacheable => gây ra các hành vi b t th ngấ ườ không ki m soát đ cể ượ 22
  23. 23. Quy t c 7: Tránh s d ngắ ử ụ finalizers • Gi i phápả – N u bu c ph i s d ng, ph i đ m b o finalize() luôn đ c g iế ộ ả ử ụ ả ả ả ượ ọ c l p cha (superclass) và l p con (subclass). Ví dả ở ớ ớ ụ @Override protected void finalize() throws Throwable { try { ... // Finalize subclass state } finally { super.finalize(); } } – Ho c s d ng ph ng pháp finalizer guardian đ đ m b oặ ử ụ ươ ể ả ả finalize() luôn đ c g i. Ví d :ượ ọ ụ public class Foo { Foo object private final Object finalizerGuardian = new Object() { @Override protected void finalize() throws Throwable { } }; } 23
  24. 24. PH N 2: PH NG TH CẦ ƯƠ Ứ CHUNG CHO CÁC Đ I T NGỐ ƯỢ 24
  25. 25. Quy t c 8: Đi u ki n khi vi t l i hàmắ ề ệ ế ạ equals() • Tr c h t tr l i câu h i li u vi c vi t l i hàm equals cóướ ế ả ờ ỏ ệ ệ ế ạ c n thi t không???ầ ế – Co hai loai lop (value classes vs activity classes). Doi voi mot activity class nhu lop Thread thi khong can phai viet lai – Khong can quan tam lieu ham equals hien co co hop ly khong. Vi du nhu viet lai ham equals cho lop Random de bat buoc 2 the hien cua lop Random duoc cho la bang nhau neu va chi neu chung san xuat mot chuoi cac gia tri giong nhau. Cai nay phai xem lai nhu cau co can thiet ko. – Cac lop cua Set: HashSet, TreeSet,.. hay cac lop cua List: ArrayList, LinkedList, ... da viet de ham equals thich hop cho chung roi thi cung ko nen viet lai. – Cac lop private hay package-private thi tuyet doi ko can viet lai ham equals vi chung ko the duoc truy cap toi :). 25
  26. 26. Quy t c 8: Đi u ki n khi vi t l i hàmắ ề ệ ế ạ equals() • N u c n vi t l i hàm equals thì ph i tuân th 5 quy đ nh sau:ế ầ ế ạ ả ủ ị 1. Phan chieu: No phai bang no, x.equals(x) luon dung 2. Doi xung: x.equals(y) dung khi va chi khi y.equals(x) cung dung 3. Bac cau: Neu x.equals(y) va y.equals(z) dung thi x.equals(z) cung dung 4. Vung chac: Neu x va y la cac gia tri khong null thi x.equals(y) se phai luon tra lai gia tri nhu nhau moi khi duoc goi den cho du cac gia tri khong thuoc equals cua lop x va y co the bi thay doi. Loi khuyen la khong neu dung cac resources khong tin cay de xay dung ham equals. 5. Loi goi x.equals(null) luon tra lai false. – 26
  27. 27. Quy t c 8: Đi u ki n khi vi t l i hàmắ ề ệ ế ạ equals() • Cách xây d ng hàm equals hi u qu :ự ệ ả – Dau tien kiem tra bang toan tu == xem lieu chung co reference den cung doi tuong khong (vd: if (o == this) return true;) – Kiem tra xem chung co cung kieu khong bang toan tu instanceof (vd: if (!(o instanceof PhoneNumber)) return false;) – Ep kieu de chung ve cung kieu (vd: PhoneNumber pn = (PhoneNumber)o;) – So sanh tung doi so (argument) xem chung co tuong ung voi nhau khong (vd: return pn.lineNumber == lineNumber && pn.prefix == prefix && pn.areaCode == areaCode;) – Sau khi viet xong ham equals, kiem tra lai xem no co tuan thu 5 quy dinh khong. – Luon viet lai ham hashCode mot khi da viet lai ham equals (quy tac 9) 27
  28. 28. Quy t c 9: Luôn vi t l i hashCode()ắ ế ạ sau khi thay đ i hàm equals()ổ 1. Trong m t phiên làm vi c n u hàm hashCode đ c g iộ ệ ế ượ ọ l i nhi u l n thì k t qu tr l i đ u ph i nh nhau. Tuyạ ề ầ ế ả ả ạ ề ả ư nhiên, n u đó là 2 phiên làm vi c khác nhau thì có thế ệ ể cho k t qu hashCode khác nhau.ế ả 2. N u hai đ i t ng x, y đ c tính là b ng nhau theo hàmế ố ượ ượ ằ x.equals(y)==true, thì x.hashCode() == y.hashCode(). 3. Ng c l i, n u x.equals(y) == false, thì hàm hashCode()ượ ạ ế c a x và y không nh t thi t ph i khác nhau.ủ ấ ế ả 4. Nên bi t r ng khi hàm hashCode khác nhau trên m i đ iế ằ ỗ ố t ng khác nhau thì m i tăng hi u su t c a h th ng.ượ ớ ệ ấ ủ ệ ố 28
  29. 29. Quy t c 9: Luôn vi t l i hashCode()ắ ế ạ sau khi thay đ i hàm equals()ổ • Đi u 2 « đ i t ng b ng nhau theo equals thì hashCode ph iề ố ượ ằ ả b ng nhau» hay b vi ph m khi ta vi t l i hàm equals. Ví d :ằ ị ạ ế ạ ụ @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof PhoneNumber)) return false; PhoneNumber pn = (PhoneNumber)o; return pn.lineNumber == lineNumber && pn.prefix == prefix && pn.areaCode == areaCode; } Map<PhoneNumber, String> m = new HashMap<PhoneNumber, String>(); m.put(new PhoneNumber(707, 867, 5309), "Jenny"); • Chúng ta hi v ng l i g i m.get(new PhoneNumber(707 , 867 ,ọ ờ ọ 5309)) s tr l i giá tr "Jenny", nh ng nó tr l i null => Lý do là vìẽ ả ạ ị ư ả ạ hàm hashCode cho 2 đ i t ng không b ng nhau.ố ượ ằ 29
  30. 30. Quy t c 9: Luôn vi t l i hashCode()ắ ế ạ sau khi thay đ i hàm equals()ổ • Cach giai quyet don gian nhat la viet lai ham hashCode nhu sau: @Override public int hashCode() { return 42; } • Cach lam nhu tren co on thoa khong? 30
  31. 31. Quy t c 9: Luôn vi t l i hashCode()ắ ế ạ sau khi thay đ i hàm equals()ổ • Cach giai quyet don gian nhat la viet lai ham hashCode nhu sau: @Override public int hashCode() { return 42; } • Cach lam nhu tren co on thoa khong? • Khong, vi nhu vay tat ca cac doi tuong se co cung gia tri hashCode. Khi do bang bam se phai su dung danh sach lien ket (linkedList) de tim kiem doi tuong va do do lam giam hieu suat tim kiem. • Giai phap hay nhat la xay dung hashCode sao cho hai doi tuong khong bang nhau se ko co chung gia tri hashCode => Dieu nay kho, phai lam vai cai luan van TS 31
  32. 32. Quy t c 9: Luôn vi t l i hashCode()ắ ế ạ sau khi thay đ i hàm equals()ổ • Nguyen tac xay dung an toan ham hashCode: – la chi su dung cac gia tri dung trong ham equals – Can doi giua running time tong the he thong so voi running time cua ham hashCode. Loi khuyen la khong nen ngai su dung tinh toan phuc tap hashCode. – Neu viec tinh toan hashCode phuc tap, khong nen tinh lai no nhieu lan cho mot doi tuong, cung nhu chi tinh toan no khi doi tuong duoc tao ra. Vi du: private volatile int hashCode; // (Xem quy tac 71) @Override public int hashCode() { int result = hashCode; if (result == 0) { result = 17; result = 31 * result + areaCode; result = 31 * result + prefix; result = 31 * result + lineNumber; } return result; } 32
  33. 33. Quy t c 10: Nên vi t l i toString()ắ ế ạ • ham toString nen tra lai toan bo thong tin ve doi tuong • viet tai lieu ro rang ve dinh dang du lieu tra ve cua toString- cung cap ham truy cap den tat ca cac thong tin tra ve boi toString – LTV khong can phai xu ly chuoi String ket xuat thong tin nao do – Kho kiem soat khi dinh dang du lieu tra ve cua toString thay doi – Vi du, binh thuong lop PhoneNumber.toString se tra lai "PhoneNumber@14845" tuong ung "ten lop@gia tri hashCode viet duoi dang unsigned hexadecimal". Chung ta co the viet lai ham toString ro rang hon de tra lai gia tri vi du "(0084) 043 - 8738242" 33
  34. 34. Quy t c 11: C n th n khi vi t l iắ ẩ ậ ế ạ clone • Đ nh nghĩa: tao ra mot doi tuong moi voi tat ca thuoc tinh giong y changị mot doi tuong khac ma khong can goi den ham khoi tao • Nguyen tac viet ham clone: – x.clone() != x: Day phai hoan toan la 2 doi tuong doc lap nhau. Chu y: cac doi tuong mutables co cau truc "deep structure" can duoc sao chep theo phuong phap "deep copy". – x.clone().getClass() == x.getClass(): chu y super.clone phai duoc khai bao trong ham clone. – x.clone().equals(x) == true: Dam bao gia tri giong nhau Override public Stack clone() { try { Stack result = (Stack) super.clone(); result.elements = elements.clone(); return result; } catch (CloneNotSupportedException e) { throw new AssertionError(); } } 34
  35. 35. Quy t c 12: Th c thiắ ự Comparable • Đ nh nghĩa: Lop a thuc thi Comparable va viet lai hamị compareTo(). Khi do Array.sort(dsa) se sap xep danh sach cac doi tuong cua lop a theo tieu chi cua ham compareTo(). • Nguyen tac xay dung ham compareTo() – Doi xung: sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) dung cho moi x, y – Bac cau: (x.compareTo(y)>0 && y.compareTo(z)>0) keo theo x.compareTo(z)>0 – Vung chac: Neu (x.compareTo(y)==0) thi (x.compareTo(z) == y.compareTo(z)) – (x.compareTo(y) == 0) == (x.equals(y)): Thong tin 2 doi tuong duoc so sanh se gan lien voi thong tin duoc xay dung trong ham equals 35
  36. 36. PH N 3: L P VÀ GIAO DI NẦ Ớ Ệ 36
  37. 37. Quy t c 13: H n ch truy c p l p vàắ ạ ế ậ ớ các thành viên bên trong l pớ • Mot modul duoc cho la thiet ke tot neu no n duoc cac du lieu vaẩ cac ham xu ly du lieu cua no khoi su truy cap boi cac module khac (ie., tinh dong goi) => de phat trien song song, cai tien doc lap, de phat hien loi, de bao tri, ... • Uu tien neu co the khai bao lop hoac giao dien la package-private class/interface. Boi vi neu khai bao public, ban bat buoc phai bao tri tinh tuong thich cua no mai mai do no co the duoc su dung o dau do ben ngoai package. • ngay ca cach viet hang so cho du lieu mang (ie. public static final array) cung khong dam bao noi dung khong bi sua doi: Nen dung ham tra ve doi tuong. Vi du đúng: private static final Thing[] PRIVATE_VALUES = { ... }; public static final List<Thing> VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES)); 37
  38. 38. Quy t c 14: Dùngắ accessor methods đ truy c p các bi n bên trong l pể ậ ế ớ • Tat ca cac truong (fields) cua public classes phai duoc truy cap thong qua ham tuong ung • Nhu giai thich trong quy tac 13, de no dam bao tinh bao dong • Tuy nhien co the ngoai le voi cac truong bat bien immutable. Vi du: public final int hour; 38
  39. 39. Quy t c 15: immutable vs. mutableắ • Đ nh nghĩa?ị • B t đ u qua ví d sauắ ầ ụ 39
  40. 40. Quy t c 15: Nh n xét gì v đo n codeắ ậ ề ạ này? String string = ""; for (int i = 0; i < times; i++) { string = string.concat("sfsd"); } 40 times 40 Running time
  41. 41. 41 Quy t c 15: Có gì khác nhau?ắ String string; for (int i: 0 -> input) { string = string.concat("sfsd"); } StringBuilder string; for (int i: 0 -> input) { string.append("sfsd"); }
  42. 42. Quy t c 15: So sánh th i gian th cắ ờ ự hi n appendệ input=10000: time =566 ms input=10000: time =24 ms input 42 Running time input Running time String StringBuilder input=5000: time =157 ms input=5000: time =29 ms
  43. 43. 43 String StringBuilder string = string.concat("sfsd"); Tương đương với tạo biến mới: string = new String("sfsdsfsd") stringBuilder.append("sfsd"); Tương đương thay thế giá trị: stringBuilder = "sfsdsfsd"; Quy t c 15: immutable vs mutableắ
  44. 44. 44 String StringBuilder 2016 public String concat(String str) { 2017 int otherLen = str.length(); 2018 if (otherLen == 0) { 2019 return this; 2020 } 2021 char buf[] = new char[count + otherLen]; 2022 getChars(0, count, buf, 0); 2023 str.getChars(0, otherLen, buf, count); 2024 return new String(0, count + otherLen, buf); 2025 } 412 public AbstractStringBuilder append(String str) 413 if (str == null) str = "null"; 414 int len = str.length(); 415 ensureCapacityInternal(count + len); 416 str.getChars(0, len, value, count); 417 count += len; 418 return this; 419 } Quy t c 15: immutable vs mutableắ
  45. 45. 45 • Lý do s d ng l p b t bi n:ử ụ ớ ấ ế – An toàn: không th truy c p vào l p b t bi n đ thay đ i giá tr trong nó, ví d nh dùngể ậ ớ ấ ế ể ổ ị ụ ư làm khóa trong b ng băm, multithreadả – Ki m soát l i t t h n: vì m i đ i t ng c a l p ch có duy nh t m t tr ng tháiể ỗ ố ơ ỗ ố ượ ủ ớ ỉ ấ ộ ạ • H n ch :ạ ế – C n t o các đ i t ng riêng bi t cho m i giá tr khác nhau (ví d append c a String)ầ ạ ố ượ ệ ỗ ị ụ ủ • 5 quy t c xây d ng l p b t bi nắ ự ớ ấ ế – Không cung c p hàm thay đ i tr ng thái c a đ i t ngấ ổ ạ ủ ố ượ – L p không th đ c k th aớ ể ượ ế ừ – T khóa final cho t t c bi nừ ấ ả ế – T khóa private cho t t c bi nừ ấ ả ế – Gi u m i tham chi u (reference) đ n các thành ph n có th b thay đ iấ ọ ế ế ầ ể ị ổ Quy t c 15: u tiên s d ng l p b t bi nắ ư ử ụ ớ ấ ế và h n ch s d ng l p không b t bi nạ ế ử ụ ớ ấ ế
  46. 46. Quy t c 15: Đ i sang l p b t bi nắ ổ ớ ấ ế 46 Refactoring for Immutability, Fredrik Berg Kjolstad , Illinois 2010
  47. 47. Quy t c 16: u tiên dùngắ Ư composition thay vì inheritance • Lý do: th a k phá v tính bao đóng [Snyder86]ừ ế ỡ – Con ph thu c vào l p cha (không bi t rõ l p cha ho c l p cha thayụ ộ ớ ế ớ ặ ớ đ i)ổ – L y ví d xây d ng m t l p k th a t HashSet đ đ m s ph n tấ ụ ự ộ ớ ế ừ ừ ể ế ố ầ ử đ c thêm vào:ượ 47 public class InstrumentedHashSet<E> extends HashSet<E> { private int addCount = 0; @Override public boolean add(E e) { addCount++; return super.add(e); } @Override public boolean addAll(Collection<? extends E> c) { addCount += c.size(); return super.addAll(c); } public int getAddCount() {return addCount; } } Test: InstrumentedHashSet<String> s = new InstrumentedHashSet<String>(); s.addAll(Arrays.asList("Snap", "Crackle", "Pop")); Output: s.getAddCount() = 6 => T i sao??ạ
  48. 48. Quy t c 16: u tiên dùngắ Ư composition thay vì inheritance • Khi nào nên s d ng inheritance???ử ụ – L p B là l p con c a A hay B k th a c a A khi vàớ ớ ủ ế ừ ủ ch khi B th c s là A (ví d chó là m t con v t).ỉ ự ự ụ ộ ậ – N u B không th c s là A thì t t nh t dùngế ự ự ố ấ composition. • Trong API có r t nhi u vi ph m đi u nàyấ ề ạ ề – Stack không ph i là Vector, vì v y Stack không nênả ậ là l p con k th a t Vectorớ ế ừ ừ – Properties không nên là l p con c a HashTableớ ủ 48
  49. 49. Quy t c 16: u tiên dùngắ Ư composition thay vì inheritance • S d ng composition s không b ph thu c vào l p chaử ụ ẽ ị ụ ộ ớ • Dùng ph ng pháp chuy n ti p (forwarding) đ thay thươ ể ế ể ế inheritance b ng composition (ằ decoration pattern) 49 public class InstrumentedHashSet<E> implements Set<E> { private Set<E> s; private int addCount = 0; public InstrumentedHashSet(Set<E> s) {this.s = s;} public boolean add(E e) { addCount++; return s.add(e); } public boolean addAll(Collection<? extends E> c) { addCount += c.size(); return s.addAll(c); } public int getAddCount() {return addCount; } }
  50. 50. Quy t c 16: u tiên dùngắ Ư composition thay vì inheritance • Khi nào nên s d ng composition???ử ụ – N u B không th c s là A thì t t nh t dùng composition.ế ự ự ố ấ – N u B có nhi u h n 1 cha (vì Java không cho k th a t nhi u cha)ế ề ơ ế ừ ừ ề • Ví d :ụ – H p đ ng bán l , h p đ ng bán buôn, h p đ ng cty A, h p đ ng cty Bợ ồ ẻ ợ ồ ợ ồ ợ ồ đ u là h p đ ngề ợ ồ – H p đ ng bán l c a cty A và h p đ ng bán buôn c a cty A đ u là h pợ ồ ẻ ủ ợ ồ ủ ề ợ đ ng c a công ty A nh ng chúng không th k th a c 2ồ ủ ư ể ế ừ ả H p đ ngợ ồ H p đ ng bán lợ ồ ẻ H p đ ng bán buônợ ồ H p đ ng bán l cty Aợ ồ ẻ H p đ ng bán buôn cty Aợ ồ H p đ ng cty Aợ ồ
  51. 51. Quy t c 17: Vi t tài li u chi ti t choắ ế ệ ế vi c k th a ho c c m k th aệ ế ừ ặ ấ ế ừ • Tài li u h ng d n đ c vi t ngay tr c cácệ ướ ẫ ượ ế ướ methods có th đ c vi t đèể ượ ế • Cách t t nh t đ ki m tra tính an toàn cho cácố ấ ể ể l p đ c thi t k đ có th k th a là vi t thớ ượ ế ế ể ể ế ừ ế ử các l p conớ • Hàm kh i t o constructor không nên ch a cácở ạ ứ l p có th b vi t đè vì chúng s đ c g i tru cớ ể ị ế ẽ ượ ọ ớ khi l p con sinh raớ • …. 51
  52. 52. Quy t c 18: u tiên s d ngắ Ư ử ụ interface h n là các l pơ ớ abstract • Java chi cho phep ke thua tu 1 lop va thi hanh nhieu interfaces cung luc. • Interfaces do do duoc cho la ly tuong de dinh nghia cac mixins. Mixin duoc hieu la mot tuy chon de them cac chuc nang phu vao chuc nang chinh trong mot lop. Vi du nhu Comparable la mot mixin vi no trang bi them cho lop mot cach thuc so sanh giua cac doi tuong. Abstract classes khong lam duoc mixins vi khong the them duoc lop cha vao lop dang ton tai. • Interfaces cho phep xay dung cau truc khong co thu bac. • Interfaces cho phep cai tien tinh nang manh me hon ma khong bi le thuoc vao lop ca nhu da noi o quy tac 16. 52
  53. 53. Quy t c 18: u tiên s d ngắ Ư ử ụ interface h n là các l pơ ớ abstract • Han che: Phai thiet ke Interfaces can than truoc khi thuc thi. – Khi thay doi hay them vao mot ham, tat ca cac lop thuc thi interface se bi thay doi. – Voi abstracts thi de dang hon khi them ham cu the, cac lop dan xuat khong bi anh huong. – Chu y: Java 8 cho phep viet ham mac dinh trong Interfaces 53
  54. 54. Quy t c 19: Ch dùngắ ỉ interface để đ nh nghĩa ki u đ i t ngị ể ố ượ • Khong su dung Interfaces ma chi chua cac static final fields: Goi la constant interfaces. • Vi mac dinh cac truong hoac ham trong Interfaces la public, nen neu mot lop thuc thi constant interfaces, tat ca cac lop con cua no se bi o nhiem boi constant interfaces vi chung co the khong duoc dung den. • Giai phap: Su dung kieu Enum de khai bao hang so (Quy tac 30). 54
  55. 55. C++ h tr con tr hàm (function pointers) qua ví d sau:ỗ ợ ỏ ụ •float Cong (float a, float b) { return a+b; } •float Tru (float a, float b) { return a-b; } •float Nhan (float a, float b) { return a*b; } •float Chia (float a, float b) { return a/b; } Tùy đi u ki n mà m t hàm s đ c dùng:ề ệ ộ ẽ ượ void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float)) { float ketqua = pt2Func(a, b); // g i con tr đ n hàm t ng ngọ ỏ ế ươ ứ } 55 Java thì sao ??? Quy t c 21: Con tr hàm trong javaắ ỏ
  56. 56. // S d ng interface v i ki u genericử ụ ớ ể public interface Toantu<T> { public T toantu(T t1, T t2); } 56 public class Test { private static class Cong implements Toantu<Double> { @Override public Double toantu(Double a, Double b) {return a + b; } } public static final Toantu<Double> CONG = new Cong(); public static Double TinhToan(Double a, Double b, Toantu<Double> O) { return O.toantu(a, b); } // DEMO public static void main(String[] args) { System.out.println(Test.TinhToan(1.0, 2.0, Test.CONG)); } } Quy t c 21: Con tr hàm trong javaắ ỏ
  57. 57. H I ĐÁP?Ỏ 57 Email: ing.dev.java@gmail.com Tél: 06 64 74 78 13 Fb: VN-INFO
  58. 58. TÀI LI U THAMỆ KH OẢ 58 Joshua Bloch

×