Tải bản đầy đủ (.pdf) (17 trang)

XÂY DỰNG BẢN ĐỒ TRÊN ĐIỆN THOẠI DI ĐỘNG CÓ HỖ TRỢ JAVA - 7 pps

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (533.08 KB, 17 trang )









Chương 4 : Phân tích – Thiết kế ứng dụng

86

STT Thuộc tính Ý nghĩa
1. N_AREA_X Số phần bản đồ được chia theo chiều ngang
2. N_AREA_Y Số phần bản đồ được chia theo chiều dọc
3. TOTAL_ARC Tổng số cung của các con đường trong thành phố
4. TOTAL_NODE Tổng số nút có trong bản đồ
5. TOTAL_STREET Tổng số đường có trong bản đồ
6. nodeEnd Nút kết thúc của lộ trình cần tìm
7. nodeStart Nút bắt đầu của lộ trình cần tìm
8. pathFound Mảng lưu ID của các cung thuộc lộ trình tìm được
9. StreetName Mảng lưu các ký tự tên đường
10. StreetNameIndex Mảng chỉ mục hỗ trợ việc truy xuất mảng StreetName
11. ArcInfo Mảng lưu chìêu dài cung và chiều của cung
12. Arcs Mảng lưu tọa độ của các cung trong bản đồ
13. ArcsIndex Mảng chỉ mục hỗ trợ việc truy xuất mảng Arcs, ArcInfo
14. Areas Mảng lưu chỉ số của các cung nằm trong 1 vùng nhìn
thấy
15. AreaIndex Mảng chỉ 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ẽ bản đồ
20. ID_Path Mảng lưu Id của đường theo id của cung, cho vào id
cung, tra ra id của đường
21. K Giá trị cho biết kích thước mỗi cạnh của một vùng chia
22. lineWidth Giá trị cho biết độ rộng của đường nhỏ
23. lineWidthBold Giá trị cho biết độ rộng của đường lớn (đại lộ)
24. Nodes Mảng cho biết nút bắt đầu, nút kết thúc của một cung








Chương 4 : Phân tích – Thiết kế ứng dụng

87
25. PathArcs Mảng danh sách các cung của mỗi đường
26. PathArcsIndex Mảng chỉ mục, cho biết vị trí bắt đầu, vị trí kết thúc của
mỗi đường trong mảng PathArcs, hỗ trợ cho việc truy
xuất mảng PathArcs
27. SL Vị trí góc trái của màn hình hiển thị bản đồ
28. ST Vị trí góc trên của màn hình hiển thị bản đồ
29. SR Vị trí góc phải của màn hình hiển thị bản đồ
30. SB Vị trí góc duới của màn hình hiển thị bản đồ
31. Scale Tỉ lệ phóng to, thu nhỏ hiện tại của bản đồ
32. StreetIndex Mảng đánh chỉ số tên đường
33. ThreadSearchPath Tiến trình thực hiện chức năng tìm đường ngắn nhất


Bảng 4-31 : Danh sách các thuộc tính lớp Streets

STT Phương thức Ý nghĩa
1. Streets Phương thức khởi tạo Streets
2. drawStreets Phương thức vẽ đường
3. drawStreetName Phương thức vẽ tên đường
4. drawArc Phương thức vẽ 1 cung thuộc đường
5. drawNodes Phương thức vẽ nút bắt đầu, nút kết thúc của lộ trình
cần tìm
6. drawNodeInArc Phương thức vẽ 1 phần của cung, từ vị trí được chọn
trên cung đến 1 đỉnh của cung
7. drawGuidingPath Phương thức vẽ lộ trình đã tìm được
8. findShortestPath Phương thức tìm đường đi ngắn nhất
9. checkSpecialCases Phương thức kiểm tra các trường hợp đặc biệt khi tìm
đường như đi từ 1 chiều sang 2 chiều, 2 chiều sang 1
chiều,…








Chương 4 : Phân tích – Thiết kế ứng dụng

88
10. findNearestArc Phương thức tìm 1 cung gần nhất với 1 điểm được đưa
vào

11. findNearesNode Phương thức tìm 1 nút gần nhất với 1 điểm được đư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 quả tìm đường
14. getStreetPostion Phương thức lấy tọa độ 1 điểm trong đường, dùng
trong chức năng tìm đường đi theo tên
15. getGuideText Hàm tạo ra chuỗi mô tả đường đi
16. getStreetName Phương thức lấy tên đường dựa theo chỉ số được 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 của đường
theo tỉ lệ
19. updateNode Tìm và cập nhật nút bắt đầu hay kết thúc từ một tọa độ
và loại nút được đưa vào.
20. run Phương thức tìm đường đi ngắn nhất giữa hai điểm
21. sqrt Phương thức phần nguyên của căn bậc hai của 1 số
được đư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 các phương thức lớp Streets








Chương 4 : Phân tích – Thiết kế ứng dụng


89
o Lớp NodePosition :
NodePosition
ArcID
FromBegin
IsNodeStart
Pos
ToEnd
X
Y
NodePosition()
drawPosition()

Hình 4-31 : Thiết kế lớp NodePosition

STT Thuộc tính Ý nghĩa
1. ArcID Sô Id của cung chứa nút này
2. FormBegin Khoảng cách từ nút đó đến điểm đầu cung
3. ToEnd Khoảng cách từ nút đến nút điểm cuối cung
4. IsNodeStart Cờ cho biết lộ trình đia qua điểm đầu cung hay điểm cuối
cung.
5. Pos Thức tự của đoạn chứa nút này trong cung
6. X Tọa độ X của nút
7. Y Tọa độ Y của nút

Bảng 4-33 : Danh sách các thuộc tính lớp NodePosition


STT Phương thức Ý nghĩa
1. NodePosition Phương thức khởi tạo NodePosition

2. drawPosition Phương thức vẽ nút ra màn hình

Bảng 4-34 : Danh sách các phương thức lớp NodePosition









Chương 4 : Phân tích – Thiết kế ứng dụng

90
 Các sơ đồ mức thiết kế

o Hiển thị bản đồ :
: User
: MainMIDlet : MainCanvas : Districts : Pl aces : Streets : Splas hScreen
1:
2: SplashScreen( )
3: MainCanvas( )
4: paint( )
5: drawDistrict(Graphics)
6: drawPlaces(Graphics)
7: drawStreets(Graphics, Boolean)
8: drawStreetName(Integer, Font)
Run
application


Hình 4-32 : Sequence diagram Hiển thị bản đồ (mức thiết kế)

: User
: MainMIDlet
: MainCanvas
: SplashScreen
: Districts
: Places
: Streets
8: drawStreetName(Integer, Font)
1:
2: SplashScreen( )
3: MainCanvas( )
4: paint( )
5: drawDistrict(Graphics)
6: drawPlaces(Graphics)
7: drawStreets(Graphics, Boolean)
Run
application

Hình 4-33 : Collaboration diagram Hiển thị bản đồ (mức thiết kế)









Chương 4 : Phân tích – Thiết kế ứng dụng

91
o Tìm địa điểm :
: User
: MainMIDlet : IndexList : FindObjectForm : MainCanvas
1:
2: IndexList( )
3:
4: FindObjectForm(Displayable, Integer)
5:
6: moveTo(Boolean, Integer)
7: setCurrent( )
Select "Find
Place" from
menu
Select a place
from the list
Select an item
kind from the
list

Hình 4-34 : Sequence diagram Tìm địa điểm (mức thiết kế)










Chương 4 : Phân tích – Thiết kế ứng dụng

92
: User
: MainMIDlet
: FindObjectForm : MainCanvas
4: isChild(Integer, Byte[]) 7: setCurrent( )
1: commandAction( )
3: itemStateChanged( )
5: itemStateChanged( )
2: FindObjectForm(Displayable, Integer)
6: moveTo(Boolean, Integer)

Hình 4-35 : Collaboration diagram Tìm địa điểm (mức thiết kế)










Chương 4 : Phân tích – Thiết kế ứng dụng

93
o Tìm đường theo tên

: User
: MainMIDlet : FindObjectForm : MainCanvas
1:
2: FindObjectForm(Displayable, Integer)
3:
4: isChild(Integer, Byte[])
5:
6: moveTo(Bool ean, Integer)
7: setCurrent( )
Select "Find
Street" from
menu
Enter street's
name to search
Select a street
from the list

Hình 4-36 : Sequence diagram Tìm đường theo tên (mức thiết kế)

: User
: MainMIDlet
: FindObjectForm : MainCanvas
4: isChild(Integer, Byte[]) 7: setCurrent( )
Select "Find
Street" from
menu
Enter street's
name to search
Select a street
from the list

1:
3:
5:
2: Fi nd Obj ectFo rm(Di spl ayab l e, In teg er)
6: moveTo(Boolean, Integer)

Hình 4-37 : Collaboration diagram Tìm đường theo tên (mức thiết kế)








Chương 4 : Phân tích – Thiết kế ứng dụng

94
o Search shortest path :
: User
: MainMIDlet : MainCanvas : Streets : MessageBox
1:
2: trafficGuiding( )
4: findShortestPath( )
3: Show(String, String, Boolean)
5: run( )
6: showResult( )
7: Show(String, String, Boolean)
Select "Find
Shortest Street"

from the menu
This function is
run by another
thread

Hình 4-38 : Sequence diagram Search shortest path (mức thiết kế)

: User
: MainMIDlet : MainCanvas
: Streets
: MessageBox
5: run( )
Select "Find
Shortest Street"
from the menu
1:
2: trafficGuiding( )
4: findShortestPath( )
6: showResult( )
3: Show(String, String, Boolean)
7: Show(String, String, Boolean)

Hình 4-39 : Collaboration diagram Search shortest path (mức thiết kế)









Chương 5 : Một số cải tiến nhằm tối ưu hóa chương trình

95
Chương 5 : MỘT SỐ CẢI TIẾN NHẰM TỐI ƯU HÓA CHƯƠNG TRÌNH
5.1. Nội dung và ý nghĩa của việc tối ưu hóa :
Để đảm bảo tính hiệu quả, mọi phần mềm khi được phát triển luô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àng có ý nghĩa quan
trọng do các thiết bị di động có tài nguyên hệ thống rất hạn chế : tốc độ
xử lý chậm,
dung lượng bộ nhớ rất nhỏ và khả năng lưu trữ thấp.
Căn cứ vào các hạn chế nêu trên, việc tối ưu hóa chương trình sẽ 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 về mặt tốc độ
 Tối ưu hóa việc sử dụng bộ 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 trong thiết kế chương trình :

 Giảm các lớp không cần thiết :
Bước đầu tiên để giảm kích thước của chương trình đó là loại bỏ việc tạo
những lớp không cần thiết. Chỉ nên tách lớp mới khi điều đó thực sự quan trọng và
có ý nghĩa. Các lớp có nhiều xử lý, nhiều thông tin tương tự nhau thì nên kết hợp lại
thành một lớp chung. Khi một lớp được tạo ra, trình biên dịch sẽ
bổ sung thêm rất
nhiều thông tin về lớp, định nghĩa thêm các hằng số, tạo bảng tra biến cục bộ
(LocalVariableTable), bổ sung hàm tạo mặc định… Chúng ta có thể thấy rõ điều
này thông qua ví dụ về một lớp tối thiểu như sau :
public class DoNothing

{
}









Chương 5 : Một số cải tiến nhằm tối ưu hóa chương trình

96
Tập tin DoThing.java sau khi được biên dịch thành tập tin DoNothing.class
sẽ có kích thước là 257 bytes trong đó chỉ có 5 bytes là bytecode. Chúng ta có thể
xem thông tin về lớp này bằng cách thực hiện dòng lệnh :
javap –v DoNothing

 Hạn chế sử dụng inner class và anonymous class :
Một trong những lớp nên loại bỏ đó là các lớp nội (inner classes) và các lớp
vô danh (anonymous classes). Trong ngôn ngữ Java, các anonymous classes thường
được dùng để cài đặt xử lý cho các sự kiện (event listener). Nếu thực sự cần thiết,
chúng ta có thể khai báo một lớp chung để xử lý tất cả các sự kiện bởi vì nhiều đối
tượng có thể sử dụng chung nhiều listener khác nhau. Lớp đượ
c tạo ra sẽ khai báo
implements các interfaces cần thiết ví dụ như CommandListener, ItemStateListener
v.v…, nhờ vào tham số được truyền cho các phương thức commandAction và
itemStateChanged, chúng ta có thể phân biệt đối tượng nào cần được xử lý hành
động.

Các inner classes cũng làm tăng thêm kích thước của chương trình do
compiler phải tạo thêm các biến và các phương thức đặc biệt để giúp cho lớp này có
thể truy xuất các thuộc tính và phương thức private của lớp đang chứa nó, và ngượ
c
lại, giúp cho các lớp đang chứa inner class có thể truy xuất các thành phần private
của lớp này.
 Giảm cây kế thừa :
Trong thiết kế cần hạn chế việc kế thừa nhiều cấp và không sử dụng lớp trừu
tượng nếu không cần thiết.
 Giảm chiều dài các định danh (identifiers) :
Nên đặt tên ngắn cho các hằng, biến, các phương thức và tên lớp. Ngoài ra,
do mỗi ứng dụng J2ME đều
được đóng gói riêng rẽ nên các lớp trong nhiều ứng
dụng khác nhau trên thiết bị di động không thể xung đột nhau. Vì thế, nếu một lớp
không phải xây dựng để trở thành một thành phần trong thư viện thì không cần thiết








Chương 5 : Một số cải tiến nhằm tối ưu hóa chương trình

97
phải đặt lớp này trong một package (không dùng từ khóa package ở đầu tập tin mã
nguồn). Điều này có tác dụng giảm được một số lượng bytes trong lớp.
 Hạn chế sử dụng getter / setter :
Khi cần cho phép các đối tượng của lớp khác được truy xuất một thuộc tính

của lớp, nên khai báo thuộc tính này ở mức public thay vì sử dụng các hàm get, set.
Thực ra, đây không phải là một phong cách lập trình tốt, tuy nhiên loại bỏ
hàm get,
set cũng giúp chúng ta giảm được kích thước của lớp.
 Lưu ý khi khởi tạo mảng :
Nên tránh khởi tạo trực tiếp các phần tử của mảng. Thông thường, nếu chúng
ta biết trước giá trị của từng phần tử trong mảng, chúng ta sẽ khai báo như ví dụ sau
int[] arr = {11, 22, 33, 44, 55, 66};

Khi viết dòng lệnh trên, chúng ta hi vọng rằng Java sẽ sao chép các giá trị
được khởi gán vào vùng nhớ vừa được cấp phát cho mảng. Tuy nhiên, nếu chúng ta
dịch ngược bytecode của đoạn chương trình này (cú pháp : javap –c tên_lớp) sẽ
được kết quả như sau :








Chương 5 : Một số cải tiến nhằm tối ưu hóa chương trình

98

Kết quả trên chứng tỏ rằng Java không sao chép
trực tiếp vào vùng nhớ của mảng mà thực hiện lần lượt
các câu lệnh tương ứng như sau :











Do vậy, kích thước của tập lớp sau khi biên
dịch sẽ tăng lên đáng kể vì phải chứa rất nhiều byte
code được lặp đi lặp lại để gán giá trị cho từng phần tử
củ
a mảng.


4: aload_0
5: bipush 6
7: newarray int
9: dup
10: iconst_0
11: bipush 11
13: iastore
14: dup
15: iconst_1
16: bipush 22
18: iastore
19: dup
20: iconst_2
21: bipush 33
23: iastore

24: dup
25: iconst_3
26: bipush 44
28: iastore
29: dup
30: iconst_4
31: bipush 55
33: iastore
34: dup
35: iconst_5
36: bipush 66
38: iastore

arr[0] = 11;
arr[1] = 22;
arr[2] = 33;
arr[3] = 44;
arr[4] = 55;
arr[5] = 66;








Chương 5 : Một số cải tiến nhằm tối ưu hóa chương trình

99

Tóm lại, khi kích thước của mảng lớn, chúng ta không nên khởi tạo trực tiếp
giá trị ban đầu của các phần tử trong mảng, thay vào đó, lưu các dữ liệu này trên
một tập tin tài nguyên và xây dựng hàm đọc rồi gán giá trị cho mảng khi thực thi.
 Giảm kích thước các tập tin tài nguyên :
Nên cố gắng giảm kích thước các tập tin tài nguyên như các files dữ liệu,
icons, các tập tin hình ảnh. Thông thường, chúng ta chỉ có thể hạn chế kích thướ
c
của hình ảnh, ít khi giảm được trên các tập tin dạng khác.
 Hạn chế sử dụng các gói thư viện bổ sung :
Các gói thư viện của hãng thứ ba sẽ được đóng gói vào trong ứng dụng, bao
gồm cả những lớp mà chúng ta không cần đến. Vì thế, không nên sử dụng nếu
không thực sự cần thiết.
5.2.2. Tối ưu kích thước chương trình khi đóng gói :

• Phân tích quá trình đóng gói ứng dụng :

Hình 5-1 : Mô hình quá trình đóng gói ứng dụng J2ME
Các files mã nguồn được trình java compiler biên dịch ra dạng byte code.
Mỗi lớp trong mã nguồn (bao gồm cả inner class) sẽ được biên dịch thành các tập
tin .class riêng rẽ. Các tập tin này, cùng với các icons, các tập tin dữ liệu, hình ảnh
v.v… được trình đóng gói kết hợp lại và nén chung trong một tập tin JAR (Java
S
S
o
o
u
u
r
r
c

c
e
e


c
c
o
o
d
d
e
e


(
(
.
.
j
j
a
a
v
v
a
a
)
)



J
J
a
a
v
v
a
a


c
c
o
o
m
m
p
p
i
i
l
l
e
e
r
r
B
B
y

y
t
t
e
e


c
c
o
o
d
d
e
e


(
(
.
.
c
c
l
l
a
a
s
s
s

s
)
)


Archive
builder
R
R
e
e
s
s
o
o
u
u
r
r
c
c
e
e
s
s


.
.
J

J
A
A
D
D


.
.
J
J
A
A
R
R










Chương 5 : Một số cải tiến nhằm tối ưu hóa chương trình

100
Archive) hay còn được gọi là một MIDlet Suite. Ngoài ra, trình đóng gói cũng tạo
ra một 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 trên thiết bị di động các thông tin cần thiết để
phầm mềm này xác định ứng dụng của chúng ta có thích hợp để thực thi trên thiết bị
hay không.
Như vậy, xét toàn bộ quá trình biên dịch và đóng gói ứng dụng, chúng ta có
thể thấy rằng ngoài các biện pháp giúp gi
ảm kích thước chương trình như đã trình
bày ở phần trước, chúng ta vẫn còn có thêm cơ hội giảm kích thước của ứng dụng
nếu (có thể) giảm được kích thước của các tập tin .class, có nghĩa là giảm số byte
code trên tập tin .class sau khi biên dịch. Tuy nhiên, việc sửa đổi byte code là việc
làm rất khó khăn và nguy hiểm. Dù vậy, chúng vẫn có thể giảm được một số lượng
bytes nhất định bằng cách giảm đến m
ức tối đa số ký tự dùng để đặt tên cho các
biến thành phần, các hằng số và các phương thức.
 Phân tích tập tin .class :
Để xem danh sách các biến thành phần, các hằng số và phương thức trong
lớp, chúng ta có thể sử dụng công cụ javap có trong bộ jdk. Cú pháp như sau :
javap –private tên_tập_tin_class

Xét ví dụ lớp Districts (tập tin Districts.class) trong chương trình. Sau khi
được 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;








Chương 5 : Một số cải tiến nhằm tối ưu hóa chương trình

101
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 các phương thức và thuộc tính được khai báo ở mức private, tên của

chúng được trình biên dịch thay thế bằng một mã có dạng _$xxx.
- Đối với các phương thức và thuộc tính được khai báo ở mức public, tên của
các thành phần này được giữ nguyên vì chúng có thể được các đối tượng của những
lớp khác truy xuất đến.
Ý tưởng thực hiện :

- Rút ngắn hơn nữa số ký tự dùng để đặt tên cho các thành phần ở mức private.
- Đặt lại tên cho các phương thức và thuộc tính được khai báo ở mức public sao
cho tối ưu nhất (số ký tự ít nhất và không được trùng với các thành phần của lớp
khác).
 Sử dụng obfuscator :
Trên thị trường hiện nay có rất nhiều phần mềm hỗ trợ giúp chúng ta thực
hiện việc tối ưu kích thướ
c cho tập tin JAR (được gọi là obfuscator). Các phần mềm
này đa số đều hoạt động dựa theo nguyên tắc giảm chiều dài các thuộc tính và
phương thức của lớp như đã nêu ở phần trên. Các phần mềm công cụ này phần lớn
là miễn phí. Tiêu biểu như proguard (), retroguard
(
Sơ đồ sử dụng obfuscator :









Chương 5 : Một số cải tiến nhằm tối ưu hóa chương trình


102

Hình 5-2 : Sơ đồ sử dụng Obfuscator
Ví dụ :
Xét tập tin District.class sau khi sử dụng proguard 3.2 (lớp Districts đã được
obfuscator đổi tên thành g.

S
S
o
o
u
u
r
r
c
c
e
e


c
c
o
o
d
d
e
e



(
(
.
.
j
j
a
a
v
v
a
a
)
)


J
J
a
a
v
v
a
a


c
c
o

o
m
m
p
p
i
i
l
l
e
e
r
r


B
B
y
y
t
t
e
e


c
c
o
o
d

d
e
e


(
(
.
.
c
c
l
l
a
a
s
s
s
s
)
)


Archive
builder
.
.
J
J
A

A
D
D


.
.
J
J
A
A
R
R


R
R
e
e
s
s
o
o
u
u
r
r
c
c
e

e
s
s




O
O
b
b
f
f
u
u
s
s
c
c
a
a
t
t
o
o
r
r


.

.
J
J
A
A
D
D


.
.
J
J
A
A
R
R


×