Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 16 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
16
Dung lượng
434,68 KB
Nội dung
Kiến trúc tiến hóa và thiết kế nổi dần: Thiết kế nổi dần thông qua các thước đo Sử dụng các thước đo và phép trực quan hoá để tìm và thu thập thiết kế ẩn trong mã của bạn Neal Ford, Kiến trúc phần mềm, ThoughtWorks Tóm tắt: Các thước đo của phần mềm (Software metrics) có thể giúp bạn tìm ra các phần tử thiết kế ẩn trong mã của bạn, cho phép các phần tử đó nổi dần lên như là các mẫu đặc thù. Bài viết này trong loạt bài viết Kiến trúc tiến hóa và thiết kế nổi dần cho thấy việc sử dụng thông minh các thước đo và phép trực quan hoá cho phép bạn phát hiện ra các phần tử mã quan trọng bị che khuất bởi sự phức tạp ngẫu nhiên như thế nào. Một trong những khó khăn đối với thiết kế nổi dần nằm trong việc tìm kiếm các mẫu đặc thù và các phần tử thiết kế khác ẩn trong mã. Các thước đo và phép trực quan hóa giúp bạn xác định các phần quan trọng của mã của bạn, cho phép bạn trích xuất chúng làm các phần tử thiết kế hạng một. Hai thước đo mà tôi tập trung vào trong bài viết này là độ phức tạp chu số và kết dính hướng tâm. Độ phức tạp chu số là một cách đo độ phức tạp tương đối của một phương thức so với phương thức khác. Kết dính hướng tâm là số đếm bao nhiêu lớp khác sử dụng lớp hiện tại. Bạn sẽ tìm hiểu về một số công cụ để trực quan hoá và để hiểu rõ cả hai thước đo này và tìm hiểu sự kết hợp các thước đo đó có thể giúp bạn làm phát lộ ra các đặc điểm của thiết kế như thế nào. Về loạt bài viết này Loạt bài viết này nhằm cung cấp một phối cảnh tươi mới về các khái niệm thường được thảo luận nhưng khó nắm bắt về kiến trúc và thiết kế phần mềm. Thông qua các ví dụ cụ thể, Neal Ford mang đến cho bạn một nền tảng vững chắc cho cách làm thực tế lanh lẹn của kiến trúc tiến hóa và thiết kế nổi dần. Bằng cách trì hoãn các quyết định quan trọng về thiết kế và kiến trúc cho đến thời điểm quyết định cuối cùng, bạn có thể ngăn ngừa được những phức tạp không cần thiết không để chúng ngầm phá hoại các dự án phần mềm của bạn. Tôi đã nói về độ phức tạp chu số trong bài viết "Thiết kế hướng kiểm thử, phần 2," nhưng có một số sắc thái mà tôi đã không thảo luận trong bài viết đó. Một yếu tố làm phức tạp thêm phép đo lường độ phức tạp chu số bằng các công cụ của Java™ là khái niệm đơn vị công việc. Độ phức tạp chu số (CC) là số đo ở mức phương thức, nhưng đơn vị công việc trong lập trình Java là các lớp. Do đó, số đo độ phức tạp chu số thường là tổng số hoặc trung bình của độ phức tạp của tất cả các phương thức trong một lớp. Cả hai thước đo này đều đáng chú ý. Lấy ví dụ: Kịch bản sau đây là có thể xảy ra. Giả sử ta có lớp có một phương thức rất phức tạp (CC = 40), nhưng lớp đó cũng có rất nhiều phương thức rất nhỏ (chẳng hạn như các cặp phương thức get/set rất phổ biến trong mã Java). Với công cụ chẳng hạn như JavaNCSS (xem phần Tài nguyên) mà báo cáo số đo này như là tổng số của tất cả các phương thức, thì độ phức tạp chu số là một con số lớn cho toàn bộ lớp. Nếu bạn sử dụng một công cụ chẳng hạn như Cobertura — báo kết quả độ phức tạp chu số là số trung bình của lớp — thì lớp này sẽ không quá tồi tệ nữa, bởi vì một lô lớn các phương thức đơn giản đã làm giảm nhẹ bớt cho một lớp rất phức tạp. Do sự không phù hợp này của đơn vị công việc, ta cần phải xem xét cả các số đo tổng cộng và số đo trung bình của độ phức tạp chu số. Nếu bạn xem xét chúng một cách độc lập, thì các nhiễu có thể làm nhiễu kết quả. Việc sử dụng cả hai số đo này sẽ giảm bớt khả năng ấy. Các thước đo của phần mềm so với các thước đo vật lý Trong phần mềm, một thước đo dựa vào việc áp dụng phép đo lường khách quan các tạo phẩm phát triển để xác định các đặc trưng ở mức thô hơn. Không giống như các thước đo vật lý (chẳng hạn như một thước đo mét), hầu hết các thước đo phần mềm không phản ánh một đặc tính nào đó trong thế giới thực. Một số đo độ phức tạp chu số, chẳng hạn như số 5 không có đơn vị đo lường đi kèm; nó sẽ không cho bạn biết gì về bất kỳ đặc tính vật lý nào của mã. Con số này chỉ có ý nghĩa khi so sánh với độ phức tạp chu số của một mã lệnh khác. Các thước đo khác đáng chú ý đối với thiết kế là hai số kết dính: kết dính hướng tâm và kết dính ly tâm. Kết dính ly tâm đo số lượng các lớp mà lớp hiện tại tham chiếu đến. Nó rất dễ dàng xác định thông qua một bước rà soát đơn giản: mở lớp đang nói đến và đếm số lượng tham chiếu (trong các trường và các tham số) đến các lớp khác. Kết dính hướng tâm rất khó xác định và nó có giá trị hơn nhiều. Nó đo xem bao nhiêu lớp khác sử dụng lớp hiện tại. Bạn có thể sử dụng dòng lệnh fu để xác định số này, hoặc sử dụng một trong các công cụ hiểu được thước đo này. Một công cụ như vậy là ckjm, là một công cụ mã nguồn mở để chạy bộ các thước đo hướng đối tượng Chidamber & Kemerer (xem phần Tài nguyên). Mặc dù có chút phức tạp khi thiết lập và chạy công cụ này, nhưng nó cung cấp cả độ phức tạp chu số (báo kết quả là tổng các độ phức tạp chu số của tất cả các phương thức của một lớp) lẫn cả hai số kết dính hướng tâm và ly tâm. Tuy nhiên, một khi bạn có những con số đó thì chúng có ý nghĩa gì, đặc biệt là về mặt thiết kế? Các con số được tạo ra là các thước đo cung cấp chỉ một chiều (khía cạnh) của thông tin về mã của bạn, và bản thân các con số thô ấy thường là không nhiều ý nghĩa. Bạn có thể tạo ra các thông tin hữu ích từ các các thước đo này theo hai cách. Một là xem cách một giá trị cụ thể thay đổi theo thời gian và có xu hướng như thế nào. Hoặc là hoặc bạn có thể kết hợp các thước đo để làm phong phú thêm mật độ thông tin, đó là cách tiếp cận tôi sẽ cho bạn thấy trong bài viết này. Các thước đo và thiết kế Tôi đã tra khảo cơ sở mã Struts trong một số bài viết trong loạt bài viết này - không phải vì tôi thiên vị Struts, mà vì nó là một dự án mã nguồn mở nổi tiếng. Hãy tin tôi đi: Bạn có thể nhận được các đặc tính thiết kế kém hấp dẫn từ hầu hết các mã mà bạn có thể tìm thấy trên thế giới! Vì đã bắt đầu với Struts, tôi sẽ tiếp tục sử dụng nó để minh họa các quan điểm của tôi. Kết quả đầu ra của ckjm thuộc dạng văn bản, có thể chuyển đổi thành XML (và thông qua nhiều phép biến đổi với XSLT, thành các định dạng khác). Hình 1 cho thấy sự kết hợp của một số thước đo của ckjm, ở đây WMC (Weight Methods per Class – Đo các phương thức theo từng lớp) là tổng độ phức tạp chu số của các phương thức của lớp và Ca là số kết dính hướng tâm: Hình 1. Kết quả các thước đo của ckjm trong một bảng Hình 2 cho thấy cùng bảng đó, được sắp xếp theo WMC: Hình 2. Các thước đo của ckjm, được sắp xếp theo WMC Chỉ cần nhìn vào kết quả này, bạn có thể nói rằng DoubleListUIBean là lớp phức tạp nhất trong cơ sở mã Struts. Điều đó cho thấy rằng nó là một ứng cử viên tốt cho việc cấu trúc lại mã để loại bỏ một số phức tạp và xem bạn có thể tìm thấy một số mẫu lặp lại, có thể trừu tượng hóa lên. Tuy nhiên, số WMC không cho bạn biết liệu việc đầu tư cấu trúc lại mã cho lớp này để có một thiết kế tốt hơn có đáng bỏ thì giờ làm hay không. Bạn lưu ý rằng số Ca cho lớp này là 3. Chỉ có ba lớp khác sử dụng lớp này, điều đó cho thấy rằng nó không đáng để đầu tư nhiều thời gian để cải thiện thiết kế của lớp. Hình 3 cho thấy cùng kết quả ckjm, lần này được sắp xếp theo Ca: Hình 3. Kết quả của ckjm, được sắp xếp theo số kết dính hướng tâm Khung nhìn kết hợp này cho thấy rằng lớp được sử dụng nhiều nhất trong Struts là lớp Component (điều này không đáng ngạc nhiên, nếu biết rằng Struts là một khung công tác Web). Mặc dù lớp Component không phức tạp lắm, nó được sử dụng bởi 177 lớp khác, làm cho nó trở thành một ứng cử viên tốt để cải thiện thiết kế. Làm cho thiết kế của lớp Component tốt hơn sẽ có tác dụng đến một số lượng lớn các lớp khác. Tổ hợp của WMC và Ca là cách tốt nhất để đọc phối cảnh được cung cấp trong Hình 3. Phối cảnh này cho bạn biết cả hai vấn đề: Cái gì là quan trọng và cái gì là phức tạp trong cơ sở mã, trong một khung nhìn duy nhất. Nếu bạn đến với cơ sở mã này mà không biết trước điều gì, thì khung nhìn này cung cấp cho bạn cái nhìn thấu suốt vào nơi mà các nỗ lực của bạn có khả năng mang lại kết quả tốt nhất. Mặc dù đây không phải là điều không thể sai lầm, bây giờ bạn có thêm nhiều thông tin hơn về cơ sở mã này so với cái bạn có thể rút ra nếu chỉ nhìn vào hàng tập giấy in mã lệnh. Các thước đo bằng số cung cấp cái nhìn thấu suốt vào mã của bạn, nhưng chúng chỉ có ở mức khá thấp, cung cấp thông tin về các lớp cụ thể, chứ không nhiều đối với một khung nhìn toàn diện của một cơ sở mã. Bây giờ ta có rất nhiều công cụ có sẵn để lấy các số đo ở mức tiếp theo thông qua trực quan hoá. Phép trực quan hoá các thước đo Các phép trực quan hoá các thước đo cung cấp các khung nhìn thay thế khác về các chiều (dimension) cụ thể, hoặc của một chiều đơn lẻ hoặc của một gộp nhóm một số chiều. Cộng đồng Smalltalk đã tạo ra một số lượng lớn các trực quan hoá của các thước đo (và thậm chí đã tạo ra một nền tảng, được gọi là Moose, để cho phép thực hiện các phép trực quan hoá này; xem phần Tài nguyên). Rất nhiều kỹ thuật đo được phát triển bởi cộng đồng Smalltalk đã được di trú sang cho lập trình Java. iPlasma và các tiêu chuẩn công nghiệp Một số câu hỏi phổ biến liên quan đến độ phức tạp chu số là "Mã của tôi so với các mã khác như thế nào?" và "số đo cho một lớp cụ thể bao nhiêu là tốt?" Dự án iPlasma trả lời những câu hỏi này (xem phần Tài nguyên). iPlasma là một nền tảng, được tạo ra như một dự án của một trường đại học ở Rumani, để đánh giá chất lượng của thiết kế hướng đối tượng. Nó sinh ra một hình kim tự tháp, hiển thị các các thước đo then chốt của dự án của bạn cùng với phép so sánh với các dải phạm vi theo tiêu chuẩn công nghiệp cho các số đo được ấy. Khi bạn chạy iPlasma, bạn trỏ đến một thư mục mã nguồn, và nó khuấy động một chút, rồi sinh ra một hình kim tự tháp các thước đo như cái hiển thị trong hình 4, là kết quả dựa trên cơ sở mã Struts 2.0.11: Hình 4. Kim tự tháp các thước đo của iPlasma Kim tự tháp này gói nhiều thông tin, một khi bạn hiểu cách đọc chúng như thế nào. Mỗi hàng có một tỷ lệ phần trăm được tô màu; tỷ lệ phần trăm này được tính ra qua tỷ số của số trên dòng này và số ở dòng dưới. Bảng 1 mô tả cho ta biết các con số nói lên điều gì, bắt đầu từ đỉnh: Bảng 1. Hiểu các mô tả về mã của kim tự tháp iPlasma Mã Mô tả NDD Số các hậu thế trực tiếp HIT Chiều cao của cây thừa kế NOP Số lượng gói NOC Số lượng lớp NOM Số lượng phương thức LOC Số dòng mã CYCLO Độ phức tạp chu số CALL Số lần gọi của từng phương thức FOUT Hệ số phân đầu ra (Số lượng các phương thức khác được gọi bởi phương thức đã cho) Các con số chỉ ra các tỷ lệ; các màu sắc cho biết ở đâu tỷ lệ này phù hợp với các dải phạm vi theo tiêu chuẩn công nghiệp (có nguồn gốc từ rất nhiều dự án mã nguồn mở). Mỗi tỷ lệ được tô màu: hoặc là màu xanh lá cây (nằm trong phạm vi), hoặc màu xanh da trời (nằm dưới phạm vi), hoặc màu đỏ (vượt quá phạm vi). Đối với cơ sở mã Struts, NDD và Cyclo vượt ra ngoài các tiêu chuẩn công nghiệp cho những giá trị này, và LOC và NOM ở dưới phạm vi đó. Các dải phạm vi đã sử dụng được minh hoạ trong bảng 2: Bảng 2. Các phạm vi công nghiệp của iPlasma của các thước đo Thấp Trung Cao CYCLO / Dòng 0.16 0.20 0.24 LOC / Phương thức 7 10 13 NOM / Lớp 4 7 10 NOC / Gói 6 17 26 CALLS /Phương thức 2.01 2.62 3.20 FANOUT / Lần gọi 0.56 0.62 0.68 iPlasma cũng sinh ra lời khuyên dựa trên kim tự tháp này, các lời khuyên hiện ra trong màn hình hiển thị của iPlasma ngay sát bên dưới kim tự tháp. Hình 5 minh hoạ các lời khuyên cho khung công tác Struts: Hình 5. Các lời khuyên của iPlasma [...]... hợp nhỏ các loại trực quan hoá có sẵn cho mã Java Việc sử dụng khôn ngoan chúng cho phép bạn thu hẹp trọng tâm của bạn một cách nhanh chóng đến các khía cạnh thiết kế của bạn, ẩn trong đầm lầy của mã của dự án Việc tìm các mẫu đặc thù là một trong những điều then chốt cho phép thiết kế nổi dần, và các công cụ để cho thấy các mẫu ấy (cả tốt lẫn xấu) một cách dễ dàng sẽ giảm bớt một cách đáng kể các nỗ... sâu của cây thừa kế, số lượng các phương thức trong mỗi lớp, số lượng dòng mã lệnh của mỗi phương thức, và số lượng các lời gọi của mỗi phương thức Các phụ thuộc Thiết kế nổi dần đòi hỏi cần phải nhìn vào các mối quan hệ và các phép trừu tượng hóa ở mức cao khác trong mã của bạn Việc cố gắng để thấy các khái niệm ở mức cao này trong mã nguồn làm ta nhớ đến câu chuyện “thầy bói xem voi” Mỗi phần của con... bao gồm các khung nhìn dạng biểu đồ cắt bánh hình tròn về sự phụ thuộc giữa các lớp, như trong hình 7, cho khung công tác Struts: Hình 7 Trực quan hoá của X-Ray cho các phụ thuộc của lớp Mỗi phần tử dọc theo mép của vòng tròn là một lớp, và các đo n thẳng nối chúng chỉ ra các phụ thuộc giữa các lớp Độ đậm nhạt của các đo n thẳng cho thấy mức phụ thuộc Khi bạn nhấn chuột vào lớp sẽ hiển thị thông tin... hình trực quan trước, khi bạn nhấn vào một trong các hộp sẽ đưa bạn đến các lớp trong Eclipse Khung nhìn này của mã của bạn cung cấp một phối cảnh duy nhất khó có thể có được bằng cách xem mã Việc tìm lỗ hổng trong thiết kế về các khía cạnh cụ thể trở nên dễ dàng hơn nếu bạn có thể nhanh chóng lọc theo các chiều nhất định, như vậy thu hẹp được các phần mã mà bạn cần kiểm tra thêm Tóm tắt X-Ray và iPlasma... để cho thấy các mẫu ấy (cả tốt lẫn xấu) một cách dễ dàng sẽ giảm bớt một cách đáng kể các nỗ lực tra soát, giúp bạn có nhiều thời gian hơn để tái cấu trúc mã của bạn, làm cho nó tốt hơn Mục lục Các thước đo và thiết kế Phép trực quan hoá các thước đo Tóm tắt ... trên xuống dưới, kích thước của hộp cho biết số dòng mã trong lớp, và chiều rộng của hộp cho biết số lượng phương thức Hình 9 cho thấy hình trực quan về tính phức tạp của hệ thống: Hình 9 Khung nhìn về tính phức tạp của hệ thống của X-Ray Khung nhìn này cũng cho thấy các lần gọi đi (kết dính ly tâm) dưới dạng các đường màu hồng và các lần gọi đến (kết dính hướng tâm) dưới dạng các đường màu đỏ Cũng... hiển thị thông tin về lớp đó, và khi nhấn đúp, nội dung của lớp sẽ được mở trong trình biên tập Eclipse Tất nhiên, khung nhìn này bao gồm cả thông tin không có ích May mắn thay, bạn có thể phóng to nhìn gần hơn để xem các dòng riêng lẻ Dòng in đậm chỉ ra các phụ thuộc mạnh giữa các lớp (kết dính ly tâm), có thể chỉ ra một lỗ hổng về thiết kế khi hai lớp quá liên quan mật thiết với nhau X-Ray cũng bao... quá lớn và chỉ ra thiết kế có vấn đề ở mức phương thức Với mục đích so sánh, hình 6 cho thấy một kim tự tháp iPlasma của dự án Vuze, một trình khách BitTorrent mã nguồn mở được viết bằng ngôn ngữ Java (xem phần Tài nguyên): Hình 6 Kim tự tháp iPlasma cho dự án Vuze Vuze là một dự án lớn (hơn 500.000 dòng mã), với các vấn đề về thiết kế tiềm năng liên quan đến chiều sâu của cây thừa kế, số lượng các phương.. .Các số mà iPlasma sinh ra phục vụ cho một số mục đích Trước tiên, chúng cho phép bạn so sánh cơ sở mã của bạn với các cơ sở mã khác theo một số phương diện Thứ hai, những con số này chỉ ra những nơi mà bạn có thể muốn tiếp tục các nỗ lực để cải thiện mức sạch sẽ của mã và cải tiến thiết kế Lấy ví dụ, đối với Struts, iPlasma chỉ ra rằng chiều sâu của cây thừa kế là khá cao và có những phương... voi thì quá phiến diện để cho phép có một cái nhìn toàn diện Việc xác định các phụ thuộc giữa các lớp và các đối tượng cũng gặp phải cùng vấn đề về định vị Các công cụ như iPlasma cho phép bạn thấy các tóm tắt của các đặc tính tổng thể của mã được xem xét, nhưng chúng không cho bạn biết các vị trí cụ thể để kiểm tra May mắn thay, các công cụ khác có thể giúp bạn “xem voi” dưới một ánh sáng khác Cộng đồng . Kiến trúc tiến hóa và thiết kế nổi dần: Thiết kế nổi dần thông qua các thước đo Sử dụng các thước đo và phép trực quan hoá để tìm và thu thập thiết kế ẩn trong mã của bạn Neal Ford, Kiến. là các mẫu đặc thù. Bài viết này trong loạt bài viết Kiến trúc tiến hóa và thiết kế nổi dần cho thấy việc sử dụng thông minh các thước đo và phép trực quan hoá cho phép bạn phát hiện ra các. vững chắc cho cách làm thực tế lanh lẹn của kiến trúc tiến hóa và thiết kế nổi dần. Bằng cách trì hoãn các quyết định quan trọng về thiết kế và kiến trúc cho đến thời điểm quyết định cuối cùng,