Chương 4 : Phân tích – Thiết kế ứng dụng STT 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. Thuộc tính N_AREA_X N_AREA_Y TOTAL_ARC TOTAL_NODE nodeEnd nodeStart pathFound StreetName StreetNameIndex ArcInfo Arcs ArcsIndex Areas AreaIndex Boulevards fontBold fontNorm graphicBuffer ID_Path K lineWidth lineWidthBold Nodes Ý nghĩa Số phần bản đồ được chia theo chiều ngang Số phần bản đồ được chia theo chiều dọc Tổng số cung của các con đường trong thành phố Tổng số nút có trong bản đồ Nút kết thúc của lộ trình...
Chương : Phân tích – Thiết kế ứng dụng STT Thuộc tính Ý nghĩa N_AREA_X Số phần đồ chia theo chiều ngang N_AREA_Y Số phần đồ chia theo chiều dọc TOTAL_ARC Tổng số cung đường thành phố TOTAL_NODE Tổng số nút có đồ TOTAL_STREET Tổng số đường có đồ nodeEnd Nút kết thúc lộ trình cần tìm nodeStart Nút bắt đầu lộ trình cần tìm pathFound Mảng lưu ID cung thuộc lộ trình tìm StreetName Mảng lưu ký tự tên đường 10 StreetNameIndex Mảng mục hỗ trợ việc truy xuất mảng StreetName 11 ArcInfo Mảng lưu chìêu dài cung chiều cung 12 Arcs Mảng lưu tọa độ cung đồ 13 ArcsIndex Mảng mục hỗ trợ việc truy xuất mảng Arcs, ArcInfo 14 Areas Mảng lưu số cung nằm vùng nhìn thấy 15 AreaIndex Mảng mục hỗ trợ việc truy xuất mảng Areas 16 Boulevards Mảng cờ, cho biết đường có phải đại lộ hay khơng 17 fontBold Font chữ dùng để vẽ tên đại lộ 18 fontNorm Font chữ dùng để vẽ tên đường bình thường 19 graphicBuffer Đối tượng graphic dùng để vẽ đồ 20 ID_Path Mảng lưu Id đường theo id cung, cho vào id cung, tra id đường 21 K Giá trị cho biết kích thước cạnh vùng chia 22 lineWidth Giá trị cho biết độ rộng đường nhỏ 23 lineWidthBold Giá trị cho biết độ rộng đường lớn (đại lộ) 24 Nodes Mảng cho biết nút bắt đầu, nút kết thúc cung 86 Chương : Phân tích – Thiết kế ứng dụng 25 PathArcs Mảng danh sách cung đường 26 PathArcsIndex Mảng mục, cho biết vị trí bắt đầu, vị trí kết thúc đường mảng PathArcs, hỗ trợ cho việc truy xuất mảng PathArcs 27 SL Vị trí góc trái hình hiển thị đồ 28 ST Vị trí góc hình hiển thị đồ 29 SR Vị trí góc phải hình hiển thị đồ 30 SB Vị trí góc duới hình hiển thị đồ 31 Scale Tỉ lệ phóng to, thu nhỏ đồ 32 StreetIndex Mảng đánh số tên đường 33 ThreadSearchPath Tiến trình thực chức tìm đường ngắn Bảng 4-31 : Danh sách thuộc tính lớp Streets STT Phương thức Ý nghĩa Streets Phương thức khởi tạo Streets drawStreets Phương thức vẽ đường drawStreetName Phương thức vẽ tên đường drawArc Phương thức vẽ cung thuộc đường drawNodes Phương thức vẽ nút bắt đầu, nút kết thúc lộ trình cần tìm drawNodeInArc Phương thức vẽ phần cung, từ vị trí chọn cung đến đỉnh cung drawGuidingPath Phương thức vẽ lộ trình tìm findShortestPath Phương thức tìm đường ngắn checkSpecialCases Phương thức kiểm tra trường hợp đặc biệt tìm đường từ chiều sang chiều, chiều sang chiều,… 87 Chương : Phân tích – Thiết kế ứng dụng 10 findNearestArc Phương thức tìm cung gần với điểm đưa vào 11 findNearesNode Phương thức tìm nút gần với điểm đưa vào 12 abortSearchPath Phương thức ngưng việc tìm đường 13 getFoundPathString Phương thức lấy chuỗi mô tả kết tìm đường 14 getStreetPostion Phương thức lấy tọa độ điểm đường, dùng chức tìm đường theo tên 15 getGuideText Hàm tạo chuỗi mô tả đường 16 getStreetName Phương thức lấy tên đường dựa theo số nhập vào 17 leftOrRight Phương thức xác định xem phải rã trái hay rẽ phải 18 updateGraphics Phương thức cập nhật lại font chữ, độ rộng đường theo tỉ lệ 19 updateNode Tìm cập nhật nút bắt đầu hay kết thúc từ tọa độ loại nút đưa vào 20 run Phương thức tìm đường ngắn hai điểm 21 sqrt Phương thức phần nguyên bậc hai số đưa vào 22 destroy Phương thức hủy, giải phóng tài nguyên Bảng 4-32 : Danh sách phương thức lớp Streets 88 Chương : Phân tích – Thiết kế ứng dụng o Lớp NodePosition : NodePositi on ArcID FromBegin IsNodeStart Pos ToEnd X Y NodePositi on() drawPosi tion() Hình 4-31 : Thiết kế lớp NodePosition STT Thuộc tính Ý nghĩa ArcID Sơ Id cung chứa nút FormBegin Khoảng cách từ nút đến điểm đầu cung ToEnd Khoảng cách từ nút đến nút điểm cuối cung IsNodeStart Cờ cho biết lộ trình đia qua điểm đầu cung hay điểm cuối cung Pos Thức tự đoạn chứa nút cung X Tọa độ X nút Y Tọa độ Y nút Bảng 4-33 : Danh sách thuộc tính lớp NodePosition STT Phương thức Ý nghĩa NodePosition Phương thức khởi tạo NodePosition drawPosition Phương thức vẽ nút hình Bảng 4-34 : Danh sách phương thức lớp NodePosition 89 Chương : Phân tích – Thiết kế ứng dụng Các sơ đồ mức thiết kế o Hiển thị đồ : : MainMIDlet : SplashScreen : MainCanvas : Districts : Places : Streets : User 1: 2: SplashScreen( ) 3: MainCanvas( ) Run application 4: paint( ) 5: drawDistrict(Graphics) 6: drawPlaces(Graphics) 7: drawStreets(Graphics, Boolean) 8: drawStreetName(Integer, Font) Hình 4-32 : Sequence diagram Hiển thị đồ (mức thiết kế) 1: 2: Spl ashScreen( ) : MainMIDlet : SplashScreen : User Run application 8: drawStreetName(Integer, Font) 3: MainCanvas( ) 4: paint( ) 7: drawStreets(Graphi cs, Boolean) : Streets : MainCanvas 6: drawPlaces(Graphics) 5: drawDistrict(Graphi cs) : Districts : Places Hình 4-33 : Collaboration diagram Hiển thị đồ (mức thiết kế) 90 Chương : Phân tích – Thiết kế ứng dụng o Tìm địa điểm : : MainMIDlet : IndexList : FindObjectForm : MainCanvas Select "Find Place" from menu : User 1: 2: IndexList( ) Select an item kind from the list 3: 4: Fi ndObjectForm(Displ ayable, Integer) 5: 6: moveTo(Bool ean, Integer) Select a place from the list 7: setCurrent( ) Hình 4-34 : Sequence diagram Tìm địa điểm (mức thiết kế) 91 Chương : Phân tích – Thiết kế ứng dụng 1: commandActi on( ) : MainMIDlet : User 3: itemStateChanged( ) 5: itemStateChanged( ) 2: Fi ndObjectForm(Di splayabl e, Integer) 4: isChil d(Integer, Byte[]) 7: setCurrent( ) 6: moveTo(Bool ean, Integer) : FindObjectForm : MainCanvas Hình 4-35 : Collaboration diagram Tìm địa điểm (mức thiết kế) 92 Chương : Phân tích – Thiết kế ứng dụng o Tìm đường theo tên : MainMIDlet : FindObjectForm : MainCanvas : User Select "Find Street" from menu 1: 2: Fi ndObjectForm(Di splayabl e, Integer) Enter street's name to search 3: 4: isChil d(Integer, Byte[]) 5: 6: moveTo(Bool ean, Integer) Select a street from the list 7: setCurrent( ) Hình 4-36 : Sequence diagram Tìm đường theo tên (mức thiết kế) 1: : MainMIDlet Enter street's name to search Select a street from the list : User Select "Find Street" from menu 3: 5: 2: FindObjectForm(Displayable, Integer) 4: isChil d(Integer, Byte[]) 7: setCurrent( ) 6: moveT o(Boolean, Integer) : FindObjectForm : MainCanvas Hình 4-37 : Collaboration diagram Tìm đường theo tên (mức thiết kế) 93 Chương : Phân tích – Thiết kế ứng dụng o Search shortest path : : MainMIDlet : MainCanvas : MessageBox : Streets : User 1: 2: trafficGuiding( ) 3: Show(String, String, Boolean) Select "Find Shortest Street" from the menu This function is run by another thread 4: findShortestPath( ) 5: run( ) 6: showResult( ) 7: Show(String, String, Boolean) Hình 4-38 : Sequence diagram Search shortest path (mức thiết kế) 5: run( ) Select "Find Shortest Street" from the menu : Streets : User 6: showResult( ) 1: 4: findShortestPath( ) 3: Show(String, String, Boolean) 7: Show(String, String, Boolean) 2: trafficGuiding( ) : MainMIDlet : MainCanvas : MessageBox Hình 4-39 : Collaboration diagram Search shortest path (mức thiết kế) 94 Chương : Một số cải tiến nhằm tối ưu hóa chương trình Chương : MỘT SỐ CẢI TIẾN NHẰM TỐI ƯU HĨA CHƯƠNG TRÌNH 5.1 Nội dung ý nghĩa việc tối ưu hóa : Để đảm bảo tính hiệu quả, phần mềm phát triển cần tối ưu hóa Đối với ứng dụng J2ME, việc tối ưu hóa chương trình có ý nghĩa quan trọng thiết bị di động có tài nguyên hệ thống hạn chế : tốc độ xử lý chậm, dung lượng nhớ nhỏ khả lưu trữ thấp Căn vào hạn chế nêu trên, việc tối ưu hóa chương trình tập trung chủ yếu vào ba nội dung : Tối ưu hóa kích thước chương trình Tối ưu hóa mặt tốc độ Tối ưu hóa việc sử dụng nhớ 5.2 Tối ưu hóa kích thước chương trình : 5.2.1 Các nguyên tắc tối ưu kích thước thiết kế chương trình : Giảm lớp khơng cần thiết : Bước để giảm kích thước chương trình loại bỏ việc tạo lớp không cần thiết Chỉ nên tách lớp điều thực quan trọng có ý nghĩa Các lớp có nhiều xử lý, nhiều thơng tin tương tự nên kết hợp lại thành lớp chung Khi lớp tạo ra, trình biên dịch bổ sung thêm nhiều thông tin lớp, định nghĩa thêm số, tạo bảng tra biến cục (LocalVariableTable), bổ sung hàm tạo mặc định… Chúng ta thấy rõ điều thơng qua ví dụ lớp tối thiểu sau : public class DoNothing { } 95 Chương : Một số cải tiến nhằm tối ưu hóa chương trình Tập tin DoThing.java sau biên dịch thành tập tin DoNothing.class có kích thước 257 bytes có bytes bytecode Chúng ta xem thơng tin lớp cách thực dịng lệnh : javap –v DoNothing Hạn chế sử dụng inner class anonymous class : Một lớp nên loại bỏ lớp nội (inner classes) lớp vô danh (anonymous classes) Trong ngôn ngữ Java, anonymous classes thường dùng để cài đặt xử lý cho kiện (event listener) Nếu thực cần thiết, khai báo lớp chung để xử lý tất kiện nhiều đối tượng sử dụng chung nhiều listener khác Lớp tạo khai báo implements interfaces cần thiết ví dụ CommandListener, ItemStateListener v.v…, nhờ vào tham số truyền cho phương thức commandAction itemStateChanged, phân biệt đối tượng cần xử lý hành động Các inner classes làm tăng thêm kích thước chương trình compiler phải tạo thêm biến phương thức đặc biệt để giúp cho lớp truy xuất thuộc tính phương thức private lớp chứa nó, ngược lại, giúp cho lớp chứa inner class truy xuất thành phần private lớp Giảm kế thừa : Trong thiết kế cần hạn chế việc kế thừa nhiều cấp không sử dụng lớp trừu tượng không cần thiết Giảm chiều dài định danh (identifiers) : Nên đặt tên ngắn cho hằng, biến, phương thức tên lớp Ngoài ra, ứng dụng J2ME đóng gói riêng rẽ nên lớp nhiều ứng dụng khác thiết bị di động xung đột Vì thế, lớp khơng phải xây dựng để trở thành thành phần thư viện không cần thiết 96 Chương : Một số cải tiến nhằm tối ưu hóa chương trình phải đặt lớp package (khơng dùng từ khóa package đầu tập tin mã nguồn) Điều có tác dụng giảm số lượng bytes lớp Hạn chế sử dụng getter / setter : Khi cần cho phép đối tượng lớp khác truy xuất thuộc tính lớp, nên khai báo thuộc tính mức public thay sử dụng hàm get, set Thực ra, phong cách lập trình tốt, nhiên loại bỏ hàm get, set giúp giảm kích thước lớp Lưu ý khởi tạo mảng : Nên tránh khởi tạo trực tiếp phần tử mảng Thông thường, biết trước giá trị phần tử mảng, khai báo ví dụ sau int[] arr = {11, 22, 33, 44, 55, 66}; Khi viết dòng lệnh trên, hi vọng Java chép giá trị khởi gán vào vùng nhớ vừa cấp phát cho mảng Tuy nhiên, dịch ngược bytecode đoạn chương trình (cú pháp : javap –c tên_lớp) kết sau : 97 Chương : Một số cải tiến nhằm tối ưu hóa chương trình 4: aload_0 5: bipush 7: newarray int 9: dup 10: iconst_0 Kết chứng tỏ Java không chép trực tiếp vào vùng nhớ mảng mà thực câu lệnh tương ứng sau : 11: bipush 11 13: iastore 14: dup arr[0] = 11; 15: iconst_1 arr[1] = 22; 16: bipush 22 arr[2] = 33; 18: iastore arr[3] = 44; 19: dup arr[4] = 55; 20: iconst_2 arr[5] = 66; 21: bipush 33 23: iastore 24: dup 25: iconst_3 26: bipush 44 28: iastore Do vậy, kích thước tập lớp sau biên dịch tăng lên đáng kể phải chứa nhiều byte code lặp lặp lại để gán giá trị cho phần tử mảng 29: dup 30: iconst_4 31: bipush 55 33: iastore 34: dup 35: iconst_5 36: bipush 66 38: iastore 98 Chương : Một số cải tiến nhằm tối ưu hóa chương trình Tóm lại, kích thước mảng lớn, không nên khởi tạo trực tiếp giá trị ban đầu phần tử mảng, thay vào đó, lưu liệu tập tin tài nguyên xây dựng hàm đọc gán giá trị cho mảng thực thi Giảm kích thước tập tin tài nguyên : Nên cố gắng giảm kích thước tập tin tài nguyên files liệu, icons, tập tin hình ảnh Thơng thường, hạn chế kích thước hình ảnh, giảm tập tin dạng khác Hạn chế sử dụng gói thư viện bổ sung : Các gói thư viện hãng thứ ba đóng gói vào ứng dụng, bao gồm lớp mà khơng cần đến Vì thế, khơng nên sử dụng khơng thực cần thiết 5.2.2 Tối ưu kích thước chương trình đóng gói : • Phân tích q trình đóng gói ứng dụng : Source code ( ja v a ) Java compiler Byte code (.class) Archive builder JAD JAR Resources Hình 5-1 : Mơ hình q trình đóng gói ứng dụng J2ME Các files mã nguồn trình java compiler biên dịch dạng byte code Mỗi lớp mã nguồn (bao gồm inner class) biên dịch thành tập tin class riêng rẽ Các tập tin này, với icons, tập tin liệu, hình ảnh v.v… trình đóng gói kết hợp lại nén chung tập tin JAR (Java 99 Chương : Một số cải tiến nhằm tối ưu hóa chương trình Archive) hay cịn gọi MIDlet Suite Ngồi ra, trình đóng gói tạo tập tin mô tả ứng dụng – JAD (Java Application Descriptor) nhằm cung cấp cho phần mềm quản lý ứng dụng thiết bị di động thông tin cần thiết để phầm mềm xác định ứng dụng có thích hợp để thực thi thiết bị hay không Như vậy, xét tồn q trình biên dịch đóng gói ứng dụng, thấy ngồi biện pháp giúp giảm kích thước chương trình trình bày phần trước, cịn có thêm hội giảm kích thước ứng dụng (có thể) giảm kích thước tập tin class, có nghĩa giảm số byte code tập tin class sau biên dịch Tuy nhiên, việc sửa đổi byte code việc làm khó khăn nguy hiểm Dù vậy, chúng giảm số lượng bytes định cách giảm đến mức tối đa số ký tự dùng để đặt tên cho biến thành phần, số phương thức Phân tích tập tin class : Để xem danh sách biến thành phần, số phương thức lớp, sử dụng cơng cụ javap có jdk Cú pháp sau : javap –private tên_tập_tin_class Xét ví dụ lớp Districts (tập tin Districts.class) chương trình Sau decompiled, lớp Districts có dạng sau : // Imports import javax.microedition.lcdui.Graphics; public final class Districts { // Fields private static int[] _$551; private static short[] _$552; private static String[] _$548; private static byte[] _$550; private static short[] _$555; private static short[] _$556; 100 Chương : Một số cải tiến nhằm tối ưu hóa chương trình private static short[] _$553; private static short[] _$554; private static short[] _$547; private static short[] _$549; // Constructors public Districts() { } // Methods public static final void destroy() { } public static final void drawDistrictNames(Graphics g) { } public static final void drawDistricts(Graphics g) { } } Nhận xét : - Đối với phương thức thuộc tính khai báo mức private, tên chúng trình biên dịch thay mã có dạng _$xxx - Đối với phương thức thuộc tính khai báo mức public, tên thành phần giữ nguyên chúng đối tượng lớp khác truy xuất đến Ý tưởng thực : - Rút ngắn số ký tự dùng để đặt tên cho thành phần mức private - Đặt lại tên cho phương thức thuộc tính khai báo mức public cho tối ưu (số ký tự khơng trùng với thành phần lớp khác) Sử dụng obfuscator : Trên thị trường có nhiều phần mềm hỗ trợ giúp thực việc tối ưu kích thước cho tập tin JAR (được gọi obfuscator) Các phần mềm đa số hoạt động dựa theo nguyên tắc giảm chiều dài thuộc tính phương thức lớp nêu phần Các phần mềm công cụ phần lớn miễn phí Tiêu biểu proguard (http://proguard.sourceforge.net), retroguard (http://www.retrologic.com/retroguard-main.html) Sơ đồ sử dụng obfuscator : 101 Chương : Một số cải tiến nhằm tối ưu hóa chương trình Source code (.java) Java compiler Byte code (.class) Archive builder JAD JAR Resources JAD JAR Obfuscator Hình 5-2 : Sơ đồ sử dụng Obfuscator Ví dụ : Xét tập tin District.class sau sử dụng proguard 3.2 (lớp Districts obfuscator đổi tên thành g 102 ... cụ javap có jdk Cú pháp sau : javap –private tên_tập_tin_class Xét ví dụ lớp Districts (tập tin Districts.class) chương trình Sau decompiled, lớp Districts có dạng sau : // Imports import javax.microedition.lcdui.Graphics;... PathArcs, hỗ trợ cho việc truy xuất mảng PathArcs 27 SL Vị trí góc trái hình hiển thị đồ 28 ST Vị trí góc hình hiển thị đồ 29 SR Vị trí góc phải hình hiển thị đồ 30 SB Vị trí góc duới hình hiển thị đồ. .. paint( ) 7: drawStreets(Graphi cs, Boolean) : Streets : MainCanvas 6: drawPlaces(Graphics) 5: drawDistrict(Graphi cs) : Districts : Places Hình 4-3 3 : Collaboration diagram Hiển thị đồ (mức thiết