Giảng viên hướng dẫn: Nguyễn Thanh Bình
BÁO CÁO CƠNG NGHỆ PHẦN MỀM
Đề Tài: Tìm Hiểu Về Refactoring
1
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Mục Lục
Chương 1.Giới thiệu...............................................................................................................................................................................................................5
Chương 2.Các nguyên lý về refactoring...............................................................................................................................................................................6
2.1.
Định nghĩa refactoring...............................................................................................................................................................................................6
2.2.
Tại sao cần refactor?..................................................................................................................................................................................................6
2.2.1. Refactoring giúp cải thiện thiết kế.........................................................................................................................................................................6
2.2.2. Refactoring giúp phần mềm dễ hiểu hơn...............................................................................................................................................................7
2.2.3. Refactoring giúp bạn lập trình nhanh hơn..............................................................................................................................................................7
Chương 3.Tiêu chí đánh giá source code tiêu chuẩn và thời điểm thích hợp để refactoring..........................................................................................9
3.1.
Source code là gì ?.....................................................................................................................................................................................................9
3.2.
Tiêu chí đánh giá source code đạt tiêu chuẩn ?..........................................................................................................................................................9
3.2.1. Code chạy được! chạy được! chạy được!...............................................................................................................................................................9
3.2.2. Code chạy đứng......................................................................................................................................................................................................9
3.2.3. Giải quyết được vấn đề khách hàng yêu cầu........................................................................................................................................................10
3.2.4. Code có thể mở rộng............................................................................................................................................................................................10
3.3.
Thời điểm tốt để refactoring code ?.........................................................................................................................................................................10
3.3.1. Khi thêm chức năng mới vào source cũ...............................................................................................................................................................10
3.3.2. Khi tiến hành xem lại code và nâng cấp, tối ưu code...........................................................................................................................................11
3.3.3. Khi cần bàn giao lại..............................................................................................................................................................................................11
Chương 4.Các kỹ thuật Refactoring...................................................................................................................................................................................12
4.1.
Composing Methods................................................................................................................................................................................................12
2
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
4.1.1. Kỹ thuật này dùng để làm gì ?.............................................................................................................................................................................12
4.1.2. Các kỹ thuật chính trong nhóm này.....................................................................................................................................................................12
4.1.3. Khi nào nên dùng kỹ thuật này ?..........................................................................................................................................................................12
4.2.
Moving features between objects............................................................................................................................................................................13
4.2.1. Kỹ thuật này dùng để làm gì ?.............................................................................................................................................................................13
4.2.2. Các kỹ thuật chính trong nhóm này.....................................................................................................................................................................13
4.2.3. Khi nào nên dùng kỹ thuật này ?..........................................................................................................................................................................14
4.3.
Organizing data........................................................................................................................................................................................................14
4.3.1. Kỹ thuật này dùng để làm gì ?.............................................................................................................................................................................14
4.3.2. Các kỹ thuật chính trong nhóm này.....................................................................................................................................................................14
4.3.3. Khi nào nên dùng kỹ thuật này ?..........................................................................................................................................................................15
4.4.
Simplifying Conditional Expressions......................................................................................................................................................................16
4.4.1. Kỹ thuật này dùng dể làm gì?..............................................................................................................................................................................16
4.4.2. Các kỹ thuật chính của nhóm này........................................................................................................................................................................16
4.4.3. Khi nào nên sử dụng kỹ thuật này ?.....................................................................................................................................................................17
4.5.
Simplifying Method Calls........................................................................................................................................................................................17
4.5.1. Kỹ thuật này dùng để làm gì?..............................................................................................................................................................................17
4.5.2. Các kỹ thuật chính của nhóm này........................................................................................................................................................................17
4.5.3. Khi nào nên sử dụng kỹ thuật này ?.....................................................................................................................................................................18
4.6.
Dealing With Generalizations..................................................................................................................................................................................19
4.6.1. Kỹ thuật này làm gì?............................................................................................................................................................................................19
4.6.2. Các kỹ thuật chính của nhóm này........................................................................................................................................................................19
4.6.3. Khi nào nên sử dụng kỹ thuật này ?.....................................................................................................................................................................20
Chương 5.Các công cụ Refactoring và Demo....................................................................................................................................................................21
3
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
5.1.
Tại sao cần sử dụng công cụ để Refactoring...........................................................................................................................................................21
5.2.
Giới thiệu các công cụ Refactoring được tích hợp sẵn vào các IDEs......................................................................................................................22
5.2.1. Đối với IDEs Inteliji IDEA..................................................................................................................................................................................22
5.2.1.a. Gọi chức năng Refactoring.................................................................................................................................................................................22
5.2.2. Đối với IDE Visual Studio Code..........................................................................................................................................................................25
5.2.3. Đối với IDE Visual Studio...................................................................................................................................................................................26
5.3.
Các Plug-in hay sử dụng trong cac IDE...................................................................................................................................................................27
5.3.1. Một số Plug-in cho IDE Visual Studio Code.......................................................................................................................................................28
5.3.2. Một số Plug-in cho IDE Visual Studio.................................................................................................................................................................29
5.4.
Nhược điểm của các công cụ Refactoring...............................................................................................................................................................29
4
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Chương 1.
Giới thiệu
Refactoring là quá trình thay đổi một hệ thống phần mềm nhằm cái tiến cấu trúc bên trong nhưng không làm biến đổi hành vi
bên ngồi của nó. Refactoring là việc dọn dẹp mã nguồn một cách có tổ chức sao cho tối thiểu hoá khả năng gây ra lỗi. Về bản
chất refactoring là nâng cấp thiết kế của mã nguồn sau khi nó đã được viết ra.
Trong những hiểu biết thơng thường về công nghệ phần mềm, chúng ta thiết kế trước sau đó mới cài đặt. Cần có thiết kế tốt
trước sau đó mới có cài đặt tốt. Qua thời gian, mã nguồn bị sửa đổi và sự nhất quán của hệ thống, cấu trúc của nó theo thiết kế, dần
dần mờ nhạt. Quá trình cài đặt chuyển dần từ chế tạo sang chắp vá.
Refactoring là cách làm ngược lại. Khi refactor bạn có thể lấy một thiết kế tồi, thậm chí là hỗn loạn, và làm lại để nó trở thành
một mã nguồn được thiết kế tốt. Mỗi bước đều đơn giản, thậm chí rất đơn giản. Bạn chỉ chuyển một trường từ lớp này sang lớp
khác, lấy vài đoạn mã ra khỏi phương thức để tạo ra phương thức riêng và đẩy vài đoạn mã lên hay xuống cây thừa kế. Tuy nhiên
tác động tích luỹ của những thay đổi nhỏ đó có thể cái thiện đáng kể thiết kế. Đó là sự đảo ngược của khái niệm software decay.
Khi refactor bạn sẽ nhận thấy sự phân phối cơng việc thay đổi. Thiết kế thay vì diễn ra đầu tiên, lại diễn ra liên tục trong suốt
quá trình phát triển. Bạn học được cách cải tiến thiết kế từ việc xây dựng hệ thống. Kết quả của sự tương tác này dẫn đến một
chương trình với thiết kế ln tốt khi q trình phát triển tiếp diễn.
Qua q trình phát triển của cơng nghệ phần mềm, cùng với sự phát triển mạnh
mẽ của phần cứng thì yêu cầu về hiệu suất xử lý ngày càng ít quan trọng thay vào
đó, tính dễ hiểu được đề cao. Do đó các kỹ thuật refactoring cũng ngày càng được
chú ý nhằm nâng cao chất lượng phần mềm.
Thực tế học tập của sinh viên Việt Nam cho thấy các phần mềm được viết trên
ghế nhà trường thường khơng có được thiết kế tốt ngay từ ban đầu. Dẫn đến tình
trạng này có rất nhiều nguyên nhân chủ quan lẫn khách quan như thiếu kinh
nghiệm, thiếu thời gian, chưa chú trọng đến quy trình phát triển phần mềm v.v...
Để những phần mềm này vượt ra khỏi phạm vi của những bài tập lớn, đồ án môn
học, đồ án tốt nghiệp... tiếp tục phát triển thành sản phẩm thực tế và thành công
trong cuộc sống thì kỹ năng refactoring là rất cần thiết.
5
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Chương 2.
2.1.
Các nguyên lý về refactoring
Định nghĩa refactoring
Thuật ngữ refactoring được phát minh bởi Ward Cunningham và Kent Beck vào khoảng những năm 1980 khi làm việc với
ngôn ngữ Smalltalk. Trong cuốn sách “Refactoring: Improving the Design of Existing Code” cung cấp hai định nghĩa như sau:
Refactoring (danh từ): một sự thay đổi ở cấu trúc bên trong của phần mềm giúp nó dễ hiểu và dễ sửa đổi hơn mà không làm
thay đổi hành vi bên ngoài.
Refactor (động từ): tái cấu trúc phần mềm bằng cách áp dụng một loạt thao tác refactoring mà khơng làm thay đổi hành vi bên
ngồi.
Trong một số tài liệu tiếng Việt, refactoring được chuyển ngữ thành “cải tiến mã nguồn” tuy nhiên cách nói này khá dài dịng
và cũng khơng diễn tả được hết ý nghĩa của thuật ngữ. Tài liệu này sẽ để nguyên thuật ngữ tiếng Anh với hai dạng như trên, ngoài
ra refactoring cũng được hiểu là tổng hợp các phương pháp và công cụ để tiến hành refactor phần mềm nói chung.
Như vậy, hiểu theo nghĩa nào đó refactor chỉ đơn giản là dọn dẹp mã nguồn. Tuy nhiên bằng cách áp dụng những phương
pháp, công cụ của refactoring, việc dọn dẹp mã nguồn sẽ hiệu quả hơn đáng kể.
Cần phân biệt refactoring và tối ưu hố hiệu năng (performance optimization). Mục đích của refactoring là làm cho phần mềm
dễ hiểu và dễ sửa chữa hơn. Tối ưu hố hiệu năng cũng khơng làm thay đổi hành vi bên ngoài của phần mềm (trừ tốc độ) mà chỉ
thay đổi cấu trúc bên trong tuy nhiên việc tối ưu hoá thường dẫn đến những đoạn mã nguồn khó hiểu và khó sửa chữa.
Một đặc tính quan trọng nữa của refactoring là khơng thay đổi hành vi bên ngoài của phần mềm. Phần mềm vẫn phải thực hiện
những chức năng giống hệt những gì nó làm trước đó. Người dùng, kể cả end user và lập trình viên, khơng thể nhận ra rằng có gì
đó vừa thay đổi.
2.2.
Tại sao cần Refactor?
2.2.1.
Refactoring giúp cải thiện thiết kế
Khơng có refactoring, thiết kế của phần mềm sẽ phân rã (software decay). Khi mã nguồn được thay đổi để hiện thực hoá
6
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
những mục tiêu ngắn hạn hoặc thay đổi mà không hiểu đầy đủ thiết kế, mã nguồn mất dần cấu trúc. Ngày càng khó nhận ra thiết
kế bằng cách đọc mã nguồn. Refactoring giống như sắp xếp lại mã nguồn. Bạn xếp lại những gì khơng ở đúng chỗ của nó. Sự mất
cấu trúc của mã nguồn có hiệu ứng tích luỹ. Càng khó nhận ra thiết kế từ mã nguồn thì càng khó duy trì thiết kế đó. Refactoring
thường xun có thể giúp mã nguồn giữ được hình dạng.
Mã nguồn được thiết kế không tốt thường chữa nhiều đoạn mã làm cùng một việc, thông thường là do mã nguồn hay làm cùng
một việc ở những chỗ khác nhau. Vì thế một khía cạnh quan trọng của cải tiến thiết kế là xoá bỏ những đoạn mã trùng lặp. Tầm
quan trọng của việc này nằm ở những thay đổi mã nguồn trong tương lai. Giảm lượng mã không giúp hệ thống chạy nhanh hơn
chút nào nhưng lại khiến việc sửa đổi dễ dàng hơn rất nhiều. Có ít mã cần phải hiểu hơn và chỉ cần sửa ở một nơi sự thay đổi sẽ
được áp dụng trên toàn bộ hệ thống.
2.2.2.
Refactoring giúp phần mềm dễ hiểu hơn
Lập trình giống như cuộc trị chuyện với máy tính. Bạn viết mã để bảo máy tính cần phải làm gì và nó sẽ trả lời bằng cách làm
chính xác điều bạn bảo. Bạn cần xố bỏ khoảng cách giữa điều bạn muốn máy tính làm với điều bạn nói với nó. Lập trình theo
cách hiểu này chỉ đơn giản là nói chính xác điều bạn muốn. Tuy nhiên cịn có những người khác cần sử dụng mã nguồn của bạn.
Ai đó sẽ thử đọc mã nguồn của bạn trong thời gian vài tháng để có thể sửa đổi vài chỗ. Chúng ta dễ quên mất người sử dụng bổ
sung đó, trong khi họ thực ra lại là những người quan trọng nhất. Ai bận tâm nếu máy tính mất thêm vài xung nhịp để dịch? Nhưng
sự khác biệt sẽ rất lớn nếu một lập trình viên mất một tuần để thực hiện một sự sửa đổi trong khi đáng lẽ mất vài giờ nếu anh ta
hiểu mã nguồn của bạn.
Bạn cũng có thể sử dụng refactoring như một cách để hiểu những đoạn mã của người khác. Đọc một vài dòng mã và cố gắng
thay đổi nó để phản ánh đúng hơn cách hiểu của bạn sau đó thử chạy lại xem nó cịn làm việc hay khơng. Với cách làm này dần
dần bạn sẽ có hiểu biết chắc chắn về hệ thống và việc trở lại những đoạn mã đã được refactoring sẽ dễ dàng hơn nhiều.
2.2.3.
Refactoring giúp bạn lập trình nhanh hơn
Điều này nghe như một nghịch lý. Để nâng cao chất lượng mã nguồn, chúng ta cần đầu tư thời gian vào việc refactoring, chẳng
phải việc đó sẽ làm giảm năng suất?
Thực tế chứng minh rằng thiết kế tốt là rất quan trọng đối với tốc độ phát triển phần mềm. Khơng có một thiết kế tốt, bạn có thể
7
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
tiến nhanh một lúc nhưng sau đó sẽ sớm chậm lại. Bạn phải dành thời gian tìm và sửa lỗi thay vì thêm chức năng mới. Việc sửa
đổi lâu hơn vì bạn phải cố hiểu hệ thống và tìm những đoạn mã trùng lặp.
Thiết kế tốt là điều kiện cần để duy trì tốc độ phát triển phần mềm và refactoring giúp bạn chống lại sự phân rã (decay) của
thiết kế, thậm chí cịn cải thiện thiết kế nữa.
8
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Chương 3.
3.1.
Tiêu chí đánh giá source code tiêu chuẩn và thời điểm thích hợp để refactoring.
Source code là gì ?
Source code hay mã nguồn là những bộ mã chương trình được tạo ra bởi lập trình viên khi sử dụng ngơn ngữ lập trình. Chúng
ta thường thấy source code được hiển thị ở dưới dạng văn bản.
Trong source code sẽ tập hợp những dòng lệnh để tạo nên một thao tác nào đó trên website.
Website quảng bá được coi như là bộ mặt của công ty nên các công ty thường không ngại chi một khoản không nhỏ để phát triển
source code riêng của họ. Nói đến đây thì chúng ta đã hiểu được tầm quan trọng của source code.
3.2.
Tiêu chí đánh giá source code đạt tiêu chuẩn ?
Để tạo nên những phần mềm ứng dụng cho công việc và đời sống, hơn hết những dòng code phải thật sự chất lượng và những
người viết code cũng thật sự hiểu chúng. Để đánh giá một source code tốt hay xấu, bằng cảm tính có thể thấy dễ dàng khi chạy
phần mềm. Dưới đây là một số quy tắc định tính để đánh giá source code có đạt tiêu chuẩn hay khơng?
3.2.1.
Code chạy được! chạy được! chạy được!
Điều quan trọng phải nhắc đến 3 lần, “chạy được” là vấn đề tiên quyết để khẳng định sự tồn tại của phần mềm.Nếu viết một
chương trình dài 1000m trên không nhưng bị lỗi cơ bản như: lỗi biên dịch, tràn bộ nhớ,… thì tất nhiên cơng sức code cũng tan
thành mây khói. Là người phát triển phần mềm, hơn ai hết, chúng ta đều hy vọng code chạy được. Để hy vọng khơng thành “tuyệt
vọng” thì phải trải qua khổ luyện và kinh nghiệm nghiên cứu và thực hành để sửa các lỗi.
3.2.2.
Code chạy đứng
Đúng ở đây là đúng với mục đích người code muốn đạt được. Để đạt được điều này, người lập trình phải nắm vững các kiến
thức cơ bản và nâng cao về chuyên mơn của họ. Khơng phải ngẫu nhiên, những nền móng cơ bản cho người lập trình là cấu trúc
dữ liệu, phân tích và thiết kế giải thuật, cơ sở dữ liệu, … Đó là nền tảng cơ bản để người lập trình có được tư duy logic hay nói
cách khác là điều khiển được code của mình chạy đúng ý mình.
9
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
3.2.3.
Giải quyết được vấn đề khách hàng yêu cầu
Code chạy đúng ý của người viết ra code nhưng mục tiêu viết ra phần mềm là hướng tới người dùng. Những yêu cầu của khách
hàng là những bài tốn bắt buộc chúng ta phải có lời giải đúng và chính xác nhất. Để thực sự đáp ứng được nghiệp vụ mà khác
hàng yêu cầu. Làm rõ những thắc mắc và thực hiện những trao đổi giữa các bên liên quan (khách hàng, dev, tester, … ) để tất cả
cùng hiểu đúng “đầu ra” của sản phẩm.
3.2.4.
Code có thể mở rộng
Một phần mềm khi được viết ra thường được sử dụng cho mục đích hiện tại và cả trong tương tai ln ln có sự thay đổi. Vì
thế quy mơ phần mềm thường lớn dần địi hỏi người lập trình cũng phải mở rộng code của mình. Những phần mềm ln ln duy
trì hoạt động nâng cấp và mở rộng từng phút từng giờ như Facebook, Google, Twitter,… Vậy nên tiêu chí đánh giá code có thể dễ
mở rộng là tiêu chí quan trọng để đánh giá một source code có thực sự tốt hay khơng?
3.3.
Thời điểm tốt để refactoring code ?
Với những tiêu chí đánh giá code như trên thì việc refactoring code là vơ cùng quan trọng để ngày càng tiệm cận với độ hồn
hảo đạt được các tiêu chí. Vậy chúng ta có thể refactoring khi nào và thời điểm nào là hoàn hảo nhất để thực hiện refactoring? Câu
trả lời là bất cứ lúc nào, bạn cũng có thể refactoring code của mình để code mình trơng dễ hiểu, dễ sử dụng. Sau đây là một vài
thời điểm “vàng” để refactoring.
3.3.1.
Khi thêm chức năng mới vào source cũ
Ứng với tiêu chí đánh giá thứ tư của một source code đạt tiêu chuẩn: code dễ mở rộng thì việc thêm một chức năng mới vào
source cũ là thời điểm tốt để refactoring.
Yêu cầu khách hàng thường chỉ có tăng chứ khơng giảm. Bất chợt đang sắp hoàn thành sản phẩm nhưng khách hàng yêu cầu
thêm 1 tác vụ, 1 chức năng nữa thì bạn phải viết thêm code. Hoặc một source code bạn viết sẵn đã lâu không đụng đến, nay phải
lôi ra và viết thêm 1 chức năng mới gì đấy. Đây là thời điểm bạn phải đọc lại source code cũ để dễ hiêu và thêm vào 1 phần mới,
có thể phần mới này sẽ ảnh hưởng cả đến những phần source cũ thi đây là thời điểm thích hợp để refactoring.
10
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
3.3.2.
Khi tiến hành xem lại code và nâng cấp, tối ưu code
Ứng với tiêu chí đánh giá thứ nhất và thứ hai của một source code đạt tiêu chuẩn: việc tiến hành xem lại code, và tối ưu code là
thời điểm tốt để refactoring.
Lắm lúc chúng ta muốn code không bị cồng kềnh, cần tối ưu, thu gọn code của mình thì điều đầu tiên đặt ra là vẫn phải hồn
thiện tiêu chí “chạy được” và “chạy đúng”. Có thể xảy ra vài trường hợp khá bực tức là sau khi thu gọn, tối ưu thì các chức năng
đã viết bị ảnh hưởng dẫn đến việc mất đi mối liên kết của phần mềm với người dùng. Do đó, đây cũng là thời điểm tốt để
refactoring code. Làm cho code trở nên đơn giản nhưng vẫn giữ được bản chất, chức năng vốn có của phần mềm.
3.3.3.
Khi cần bàn giao lại
Ứng với tiêu chí thứ 3 của một source code đạt tiêu chuẩn: luôn ln hướng đến khách hàng.
Sản phẩm thì ln đến tay người tiêu dùng. Vậy khách hàng phải là người hiểu và biết cách sử dụng cũng như tự canh chỉnh, thay
đổi để thuận tiện việc quản lí và sử dụng. Có những đoạn code rắc rối, phức tạp chỉ người viết hiểu nên khi bàn giao lại cho khách
hàng, người mới sử dụng sẽ gây khó khăn nên đây là thời điểm tốt để refactoring. Đây là vấn đề thường gặp của các bên thứ ba,
bán và mua phần mềm để phục vụ cho doanh nghiệp, công ty,…
11
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Chương 4.
Các kỹ thuật Refactoring
Có rất nhiều kỹ thuật refactoring khác nhau, mỗi kỹ thuật đôi khi chỉ làm thay đổi một chút nho nhỏ mã nguồn, nhưng những
thay đổi nhỏ đó được tích luỹ dần theo thời gian thì tạo nên một ảnh hưởng rất lớn, giúp cho hệ thống của chúng ta trở nên tốt
hơn.Dưới đây là các nhóm kỹ thuật dùng để refactoring.
4.1.
Composing Methods
4.1.1.
Kỹ thuật này dùng để làm gì ?
Trong hầu hết các trường hợp, các phương thức quá dài là gốc rễ của mọi vấn đề phát sinh (exception,bug... ). Những phương
thức này khiến cho chương trình trở nên khó hiểu, che giấu tính logic, thứ tự thực hiện, khó khăn cho cơng tác bảo trì. Nhóm kỹ
thuật này để hợp lý hóa các phương thức, loại bỏ sự trùng lặp code, mở đường cho các cải tiến trong tương lai.
4.1.2.
Các kỹ thuật chính trong nhóm này
Extract Method (Tách phương thức)
Inline Method (Gộp phương thức)
Extract Variable (Tách biến)
Inline Temp (Gộp biến tạm thời)
Substitute Algorithm (Thay thế thuật toán)
Replace Temp with Query (Thay biến tạm bằng phương thức)
Split Temporary Variable (Tách biến tạm)
Remove Assignments to Parameters (Không thay đổi tham số)
Replace Method with Method Object (Thay phương thức bằng phương thức của đối tượng)
12
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
4.1.3.
Khi nào nên dùng kỹ thuật này ?
Nếu phương thức của bạn quá dài do gộp quá nhiều tác vụ vào, gây mơ hồ khi đọc => Dùng kỹ thuật Extract Method.
Nếu phần thân của phương thức rõ ràng hơn tên của nó => Dùng kỹ thuật Inline Method
Nếu bạn có những biểu thức khó hiểu => Dùng kỹ thuật Extract Variable
Nếu bạn có một biến tạm thời được gán cho một phương thức đơn giản => Dùng kỹ thuật Inline Temp
Nếu bạn muốn một kết quả dùng được cho nhiều phương thức thay vì một phương thức => Dùng kỹ thuật Replace Temp
with Query
Nếu bạn chỉ có một biến tạm để lưu kết quả cho tất cả các biểu thức => Dùng kỹ thuật Split Temporary Variable
Nếu bạn muốn tránh việc thay đổi tham số truyền vào => Dùng kỹ thuật Remove Assignments to Parameters
Nếu bạn có một phương thức quá dài với những biến cục bộ đan xen mà không thể dùng kỹ thuật Extract Method => Dùng
kỹ thuật Replace Method with Method Object.
Nếu bạn muốn thay đổi thuật toán hiện tại => Dùng kỹ thuật Substitute Algorithm
4.2.
Moving features between objects
4.2.1.
Kỹ thuật này dùng để làm gì ?
Mặc dù bạn có thể dùng chung các phương thức cho các class khác nhau nhưng trong một số trường hợp, việc này không phải là
cách tốt nhất.
Nhóm kỹ thuật này chỉ ra cách di chuyển các feature giữa các class một cách an toàn, tạo các lớp mới và ẩn các triển khai chi
tiết khỏi các truy cập công khai.
13
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
4.2.2.
Các kỹ thuật chính trong nhóm này
Move Method (Di chuyển phương thức)
Move Field (Di chuyển trường/thuộc tính)
Extract Class (Tách lớp)
Inline Class (Gộp lớp)
Hide Delegate (Ẩn uỷ quyền)
Remove Middle Man (Loại bỏ trung gian)
Introduce Foreign Method (Giới thiệu phương thức ngoài)
Introduce Local Extension (Giới thiệu tiện ích nội bộ)
4.2.3.
Khi nào nên dùng kỹ thuật này ?
Nếu một phương thức được sử dụng ở class khác nhiều hơn class chứa nó => Dùng kỹ thuật Move Method
Nếu một trường được sử dụng ở class khác nhiều hơn class chứa nó => Dùng kỹ thuật Move Field
Nếu một class làm 2 việc trở lên => Dùng kỹ thuật Extract Class
Nếu một class hầu như khơng chịu trách nhiệm bất cứ việc gì mà chỉ ủy quyền cho class khác => Dùng kỹ thuật Inline
Class
Nếu bạn không muốn cho client biết về chuỗi kết nối giữa các class => Dùng kỹ thuật Hide Delegate
Nếu bạn thấy việc gọi class này thông qua class khác là không cần thiết => Dùng kỹ thuật Remove Middle Man
14
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Nếu một lớp tiện ích hay lớp được định nghĩa trước(predefined class) khơng có phương thức bạn cần, mà bạn khơng thể
thêm phương thức này vào lớp đó => Dùng kỹ thuật Introduce Foreign Method
Nếu một lớp tiện ích hay lớp được định nghĩa trước khơng có một số phương thức bạn cần nhưng bạn không thể thêm các
phương thức này vào lớp đó => Dùng kỹ thuật Introduce Local Extension
4.3.
Organizing data
4.3.1.
Kỹ thuật này dùng để làm gì ?
Các kỹ thuật tái cấu trúc này giúp xử lý dữ liệu, thay thế các nguyên thủy bằng method class phong phú. Một kết quả quan
trọng khác là gỡ rối các liên kết giữa các class, điều này làm cho các class linh động hơn và có thể tái sử dụng.
4.3.2.
Các kỹ thuật chính trong nhóm này
Change Value to Reference (Thay đổi giá trị thành tham chiếu)
Change Reference to Value (Thay đổi tham chiếu thành giá trị)
Duplicate Observed Data (Trùng lặp dữ liệu quan sát)
Self Encapsulate Field (Trường tự đóng gói)
Replace Data Value with Object (Thay thế dữ liệu bằng đối tượng)
Replace Array with Object (Thay thế mảng bằng đối tượng)
Change Unidirectional Association to Bidirectional (Thay đổi liên kết một chiều thành hai chiều)
Change Bidirectional Association to Unidirectional (Thay đổi liên kết hai chiều thành một chiều)
Encapsulate Field (Đóng gói trường)
Encapsulate Collection (Đóng gói bộ)
15
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Replace Magic Number with Symbolic Constant (Thay thế số bằng hằng số)
Replace Type Code with Class (Thay thế loại mã bằng lớp)
Replace Type Code with Subclasses (Thay thế loại mã bằng lớp con)
Replace Type Code with State/Strategy (Thay thế loại mã bằng trạng thái)
Replace Subclass with Fields (Thay thế lớp con bằng trường)
4.3.3.
Khi nào nên dùng kỹ thuật này ?
Nếu bạn có nhiều trường hợp giống hệt nhau trong 1 class mà bạn cần thay thế chung bằng một đối tượng duy nhất =>
Dùng kỹ thuật Change Value to Reference
Nếu bạn có một đối tượng tham chiếu quá nhỏ và không thường xuyên được thay đổi để phù hợp với việc quản lý vịng
đời của đối tượng đó => Dùng kỹ thuật Change Reference to Value
Nếu dữ liệu được lưu trữ các lớp chịu trách nhiệm về GUI => Dùng kỹ thuật Duplicate Observed Data
Nếu bạn sử dụng truy cập trực tiếp đến các thuộc tính riêng tư => Dùng kỹ thuật Self Encapsulate Field
Nếu một class (hoặc một nhóm các class) chứa một trường dữ liệu mà trường đó có hành vi riêng tư và dữ liệu liên quan
=> Dùng kỹ thuật Replace Data Value with Object.
Nếu bạn có một mảng chứa nhiều kiểu dữ liệu => Dùng kỹ thuật Replace Array with Object.
Nếu bạn có 2 class mà mỗi class cần sử dụng tính năng của class kia nhưng liên kết giữa chúng chỉ là một chiều => Dùng
kỹ thuật Change Unidirectional Association to Bidirectional.
Nếu bạn có 2 class mà liên kết giữa chúng là 2 chiều nhưng chỉ có một class cần sử dụng tính năng của class kia => Dùng
kỹ thuật Change Bidirectional Association to Unidirectional
Nếu bạn có các trường/thuộc tính cơng khai => Dùng kỹ thuật Encapsulate Field
Nếu có một class chứa một trường tập hợp và một getter và setter đơn giản để làm việc với tập hợp => Dùng kỹ thuật
Encapsulate Collection.
16
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Nếu bạn có một số có ý nghĩa và muốn thay đổi thành hằng số => Dùng kỹ thuật Replace Magic Number with Symbolic
Constant.
Nếu một class có một thuộc tính chứa mã kiểu. Các giá trị của loại này không được sử dụng trong các điều kiện của tốn
tử và khơng ảnh hưởng đến hoạt động của chương trình => Dùng kỹ thuật Replace Type Code with Class
Nếu bạn có kiểu được mã hóa ảnh hưởng trực tiếp đến hành vi của chương trình (các giá trị của trường này kích hoạt
nhiều mã khác nhau trong điều kiện) => Dùng kỹ thuật Replace Type Code with Subclass
Nếu có một loại được mã hóa ảnh hưởng đến hành vi nhưng bạn khơng thể sử dụng các subclass để loại bỏ nó => Dùng
kỹ thuật Replace Type Code with State/Strategy.
Nếu có các lớp con chỉ khác nhau về phương thức( trả về không đổi) => Dùng kỹ thuật Replace Subclass with Fields.
4.4.
Simplifying Conditional Expressions
4.4.1.
Kỹ thuật này dùng dể làm gì?
Các điều kiện có xu hướng ngày càng trở nên phức tạp hơn trong logic của chúng và kỹ thuật này dùng để chống lại điều này.
4.4.2.
Các kỹ thuật chính của nhóm này
Consolidate Conditional Expression (Hợp nhất biểu thức có điều kiện)
Consolidate Duplicate Conditional Fragments (Hợp nhất các đoạn điều kiện trùng lặp)
Decompose Conditional (Phá hủy điều kiện)
Replace Conditional with Polymorphism (Thay thế điều kiện bằng tính đa hình)
Remove Control Flag (Loại bỏ cờ điều khiển)
Replace Nested Conditional with Guard Clauses (Thay thế điều kiện lồng nhau bằng các điều khoản bảo vệ)
Introduce Null Object (Giới thiệu đối tượng rỗng)
Introduce Assertion (Giới thiệu khẳng định)
17
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
4.4.3.
Khi nào nên sử dụng kỹ thuật này ?
Nếu có nhiều điều kiện dẫn đến cùng một hành động hoặc kết quả => Dùng Consolidate Conditional Expression.
Nếu có các đoạn mã giống hệt nhau được tìm thấy trong các nhánh điều kiện => Dùng Consolidate Duplicate
Conditional Fragments
Nếu có những điều kiện quá phức tạp => Dùng Decompose Conditional
Nếu bạn có các điều kiện thực hiện những hành động khác nhau dựa vào kiểu đối tượng hoặc thuộc tính => Dùng kỹ
thuật Replace Conditional with Polymorphism.
Nếu có 1 biến boolean hành động như cờ điều khiển cho nhiều biểu thức Boolean.
Nếu có một nhóm các điều kiện lồng nhau và khó xác định quy trình thực thi mã bình thường.
Nếu bạn không muốn trả về null mà trả về đối tượng null thể hiện hành vi mặc định => Dùng kỹ thuật Introduce Null
Object
Nếu bạn muốn các điều kiện hoặc giá trị đều phải dung => Dùng kỹ thuật Introduce Assertion.
4.5.
Simplifying Method Calls
4.5.1.
Kỹ thuật này dùng để làm gì?
Kỹ thuật này khiến cho việc gọi phương thức trở nên đơn giản và dễ hiểu hơn. Điều này làm đơn giản hóa giao diện cho sự
tương tác giữa các class.
4.5.2.
Các kỹ thuật chính của nhóm này
Add Parameter (Thêm tham số)
Remove Parameter (Xóa tham số)
18
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Rename Method (Đổi tên phương thức)
Separate Query from Modifier (Tách truy vấn khỏi công cụ sửa đổi )
Parameterize Method (Tham số hóa)
Introduce Parameter Object (Giới thiệu đối tượng tham số)
Preserve Whole Object (Giữ toàn bộ đối tượng)
Remove Setting Method (Loại bỏ phương thức cài đặt)
Replace Parameter with Explicit Methods (Thay thế tham số bằng rõ ràng)
Replace Parameter with Method Call (Thay thế tham số bằng phương thức gọi)
Hide Method (Ẩn phương thức)
Replace Constructor with Factory Method (Thay thế phương thức khởi tạo bằng phương thức nhà máy)
Replace Error Code with Exception (Thay thế code lỗi bằng ngoại lệ)
Replace Exception with Test (Thay thế ngoại lệ bằng kiểm tra)
4.5.3.
Khi nào nên sử dụng kỹ thuật này ?
Nếu một phương thức khơng có đủ dữ liệu để thực hiện các hành động nhất định => Dùng kỹ thuật Add Parameter
Nếu một tham số không được sử dụng trong phương thức => Dùng kỹ thuật Remove Parameter
Nếu tên của phương thức khơng giải thích được điều nó thực sự làm => Dùng kỹ thuật Rename Method
Nếu bạn có một phương thức trả về một giá trị nhưng bên trong nó có một thứ gì đó bị thay đổi => Dùng kỹ thuật
Separate Query from Modifier
Nếu có phương thức chỉ khác nhau về giá trị, số hoặc phép toán => Dùng kỹ thuật Parameterize Method
Nếu phương thức của bạn chứa nhóm tham số lặp => Dùng kỹ thuật Introduce Parameter Object
19
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Nếu bạn nhận một số giá trị từ 1 đổi tượng và sau đó chuyển chúng dưới dạng tham số cho một phương thức => Dùng
kỹ thuật Preserve Whole Object
Nếu bạn muốn xóa các phương thức đặt thuộc tính => Dùng kỹ thuật Remove Setting Method.
Nếu có một phương thức được chia thành nhiều phần và mỗi phần hành động dựa vào giá trị của tham số => Dùng kỹ
thuật Replace Parameter with Explicit Methods
Nếu gọi một phương thức truy vấn và truyền kết quả của nó như một tham số cho phương thức khác, trong khi phương
thức đó có thể gọi truy vấn trực tiếp => Dùng kỹ thuật Replace Parameter with Method Call
Nếu một phương thức không được sử dụng bởi các lớp khác hoặc chỉ được sử dụng trong hệ thống phân cấp lớp của
chính nó => Dùng kỹ thuật Hide Method.
Nếu bạn có một phương thức khởi tạo phức tạp không chỉ là thiết lập các giá trị tham số trong các thuộc tính => Dùng
kỹ thuật Replace Constructor with Factory Method.
Nếu có một phương thức trả về một lỗi => Dùng kỹ thuật Replace Error Code with Exception.
Nếu bạn ném một ngoại lệ đến nơi kiểm tra ngoại lệ đó => Dùng kỹ thuật Replace Exception with Test.
4.6.
Dealing With Generalizations
4.6.1.
Kỹ thuật này làm gì?
Trừu tượng có một nhóm kỹ thuật tái cấu trúc riêng, chủ yếu liên quan đến việc di chuyển chức năng dọc theo hệ thống phân
cấp kế thừa lớp, tạo ra các lớp và giao diện mới, đồng thời thay thế kế thừa bằng ủy quyền và ngược lại.
4.6.2.
Các kỹ thuật chính của nhóm này
Pull Up Field (Đẩy thuộc tính lên)
20
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Pull Up Method (Đẩy phương thức lên)
Pull Up Constructor Body (Đẩy hàm khởi tạo lên)
Push Down Field (Đẩy thuộc tính xuống)
Push Down Method (Đẩy phương thức xuống)
Extract Subclass (Tách lớp con)
Extract Superclass (Tách lớp cha)
Extract Interface (Tách interface)
Collapse Hierarchy (Gộp biểu mẫu phân tách)
Form Template Method (Phương thức mẫu thay thế)
Replace Inheritance with Delegation (Thay thế kế thừa bằng ủy quyền)
Replace Delegation with Inheritance (Thay thế ủy quyền bằng kế thừa)
4.6.3.
Khi nào nên sử dụng kỹ thuật này ?
Nếu 2 lớp có cùng thuộc tính => Dùng kỹ thuật Pull Up Field.
Nếu các lớp con có các phương thức hoạt động như nhau => Dùng kỹ thuật Pull Up Method.
Nếu các lớp con có các hàm khởi tạo với các mã hầu như giống nhau => Dùng kỹ thuật Pull Up Constructor Body.
Nếu chỉ có một lớp con sử dụng thuộc tính này => Dùng kỹ thuật Push Down Field.
Nếu một phương thức chỉ được sử dụng trong một lớp con => Dùng kỹ thuật Push Down Method.
Nếu một lớp có chức năng chỉ được sử dụng trong một số trường hợp nhất định => Dùng kỹ thuật Extract Subclass.
Nếu có 2 lớp có trường và phương thức chung => Dùng kỹ thuật Extract Superclass.
21
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Nếu nhiều máy khách đang sử dụng cùng 1 phần của lớp giao diện hoặc một phần của lớp giao diện trong 2 lớp là như
nhau => Dùng kỹ thuật Extract Interface.
Nếu bạn có một hệ thống phân cấp trong đó một lớp con giống với lớp cha => Dùng kỹ thuật Collapse Hierarchy,
Nếu các lớp con triển khai các thuật toán chứa các bước tương tự theo cùng một thứ tự => Dùng kỹ thuật Form
Template Method.
Nếu có một lớp con chỉ sử dụng một phần các phương thức của lớp cha(hoặc không thể kể thừa dữ liệu của lớp cha) =>
Dùng kỹ thuật Replace Inheritance with Delegation.
Nếu có một lớp chứa nhiều phương thức đơn giản ủy quyền cho các phương thức khác => Dùng kỹ thuật Replace
Delegation with Inheritance.
22
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Chương 5.
5.1.
Các cơng cụ Refactoring và Demo
Tại sao cần sử dụng công cụ để Refactoring
Như chúng ta đã biết, kĩ thuật Refactoring loại bỏ những “Code Smells” khỏi mã nguồn của dự án. Nó có rất nhiều lợi ích cho
kế hoạch lâu dài của dự án. Khi thực hiện Refactoring cho dự án, chúng ta cần chỉnh sửa rất nhiều mã lệnh. Nếu chúng ta theo một
trong những quy chuẩn Refactoring như trên thì ta phải sửa rất nhiều vị trí mà các vị trí đó có cách sửa như nhau. Vậy nên các
cơng cụ Refactoring được sinh ra để xử lí các tác vụ Refactoring nhanh hơn, chính xác hơn, tránh sai sót cho người phát triển dự
án.
Như hình trên, chương trình nguồn của dự án tồn tại rất nhiều lỗi (Bad Smells) mà con người khơng thể tìm ra hết để xử lí. Các
cơng cụ Refactoring can thiệp trực tiếp vào mơi trường phát triển ứng dụng (IDEs) để thực hiện chức năng Refactoring. Ứng với
từng môi trường phát triển ứng dụng sẽ có các cơng cụ Refactoring được phát triển, giúp cho q trình Refactoring trên các mơi
trường thuận tiện và hiệ quả.
Khi sử dụng các cơng cụ Refactoring, nó có thể chỉ ra trong chương trình nguồn đó các vị trí mà nên Refactoring với các kĩ
thuật Refactoring theo quy chuẩn và được cập nhật mới nhất, phục vụ cho việc Refactoring trở nên nhanh hơn, chính xác hơn, hiệu
quả hơn.
23
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
Các cơng cụ Refactoring được phân thành hai nhóm chính:
Các cơng cụ Refactoring được tích hợp sẵn vào các IDEs do nhà phát triển IDEs cung cấp.
Các công cụ Refactoring do bên thứ 3 phát triển (Plug-in)
5.2.
Giới thiệu các công cụ Refactoring được tích hợp sẵn vào các IDEs
Hiện nay, có rất nhiều IDEs được sử dụng cho nhiều dự án với các ngôn ngữ khác nhau. Trong bài báo cáo này sẽ giới thiệu
một số cơng cụ Refactoring được tích hợp sẵn trong các IDEs phổ biến như: Inteliji IDEA, Visual Studio Code, Visual Studio.
5.2.1.
Đối với IDEs Inteliji IDEA
5.2.1.a. Gọi chức năng Refactoring
1. Chọn phần code cần refactoring (có thể chọn các files, các thư mục trong dự án hoặc các đoạn lệnh, dịng lệnh trong IDE)
2. Nhấn phím tắt Ctrl + Alt + T để mở danh sách các chức năng Refactoring do nhà cung cấp viết sẵn.
Hình ảnh sau khi gọi chức năng Refactoring của IDE Inteliji IDEA
24
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)
Giảng viên hướng dẫn: Nguyễn Thanh Bình
5.2.1.b. Xem trước thay đổi sau khi Refactoring
1. Để xem thay đổi, bấm vào nút Preview trong cửa sổ Refactoring.
Cửa sổ Refactoring
2. Trong khi xem trước những thay đổi sau khi Refactoring, bạn có thể xố (sử dụng phím Delete) hoặc di chuyển (sử dụng tổ hợp
phím Ctrl + X) những thành phần đang có vấn đề.
Xem trước những thay đổi code sau khi Refactoring
25
SVTH: Dương Thanh Dũng (102180060), Nguyễn Lê Anh Minh(102180083), Nguyễn Bá Vũ(102180109), Nguyễn Nhật Minh(102180029)