1. Trang chủ
  2. » Công Nghệ Thông Tin

Tái cấu trúc cho mọi người docx

46 221 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 46
Dung lượng 313,96 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Tái cấu trúc cho mọi người Làm thế nào và tại sao lại sử dụng các tính năng tái cấu trúc được tự động hóa của Eclipse David Gallardo, Tư vấn phần mềm Tóm tắt: Eclipse cung cấp tập các p

Trang 1

Tái cấu trúc cho mọi người

Làm thế nào và tại sao lại sử dụng các tính năng tái cấu trúc được tự động hóa của Eclipse

David Gallardo, Tư vấn phần mềm

Tóm tắt: Eclipse cung cấp tập các phép tái cấu trúc (refactoring) tự động mạnh

mẽ, so với những thứ khác, cho phép bạn đổi tên các phần tử Java™, di chuyển các lớp và các gói, tạo các giao diện từ các lớp cụ thể, chuyển các lớp lồng nhau vào các lớp mức cao nhất và lấy ra một phương thức mới từ các đoạn mã trong một phương thức cũ Việc trở nên quen thuộc với các công cụ tái cấu trúc của Eclipse là một cách hay để cải thiện năng suất của bạn Tổng quan về tính năng tái cấu trúc của Eclipse này, kèm với các ví dụ, giải thích cách thức và lí do sử dụng từng tính năng

Lí do cần tái cấu trúc?

Tái cấu trúc (Refactoring) là thay đổi cấu trúc của một chương trình mà không làm

thay đổi chức năng của nó Tái cấu trúc là một kỹ thuật mạnh, nhưng nó cần được thực hiện cẩn thận Mối nguy hiểm chính là các lỗi vô ý có thể được đưa vào, đặc biệt là khi tái cấu trúc được thực hiện bằng tay Mối nguy hiểm này dẫn đến một

sự chỉ trích thường xuyên về tái cấu trúc: tại sao lại sửa chữa mã nếu nó không bị hỏng?

Có một vài lý do để bạn có thể muốn tái cấu trúc mã Đầu tiên là bắt nguồn của câu chuyện cổ tích: cơ sở mã rất cổ của sản phẩm đáng kính được kế thừa hoặc nếu không thì xuất hiện bí ẩn Nhóm phát triển ban đầu đã biến mất Một phiên bản mới, với các tính năng mới, phải được tạo ra, nhưng mã không còn hiểu được nữa Nhóm phát triển mới, làm việc cả đêm lẫn ngày, giải mã nó, vẽ bản đồ nó và

Trang 2

sau nhiều kế hoạch và thiết kế, phá hỏng mã hoàn toàn Cuối cùng, cẩn thận, họ đặt nó tất cả trở lại với nhau theo tầm nhìn mới Đây là tái cấu trúc trên quy mô khác thường và một ít vẫn còn hoạt động để nói về chuyện này

Một kịch bản thực tế hơn là một yêu cầu mới được đưa vào cho dự án đòi hỏi thay đổi thiết kế Thật là vụn vặt cho dù yêu cầu này đã được đưa vào do sơ xuất trong

kế hoạch ban đầu hoặc do cách tiếp cận lặp lại (chẳng hạn như phát triển nhanh nhẹn hoặc phát triển dựa vào thử nghiệm) đang được sử dụng để thận trọng đưa vào các yêu cầu trong suốt quá trình phát triển Đây là tái cấu trúc trên một quy

mô nhỏ hơn nhiều và nó thường yêu cầu thay đổi hệ thống phân cấp lớp, có lẽ do đưa vào các giao diện hoặc lớp trừu tượng, chia tách các lớp, sắp xếp lại các lớp và v.v

Một lý do cuối cùng để tái cấu trúc, khi các công cụ tái cấu trúc tự động có sẵn, chỉ đơn giản là một phím tắt để tạo mã ở vị trí đầu tiên một cái gì đó giống như cách sử dụng một chương trình kiểm tra lỗi chính tả (spellchecker) để phân loại một từ khi bạn không chắc cách đánh vần nó Việc sử dụng tái cấu trúc nhàm chán này chẳng hạn để tạo ra các phương thức getter và setter có thể là một bộ tiết kiệm thời gian hiệu quả một khi bạn đã quen thuộc với các công cụ này

Các công cụ tái cấu trúc của Eclipse không được dự kiến để sử dụng cho phép tái cấu trúc tại một quy mô khác thường một vài công cụ có nhưng chúng là vô giá để làm thay đổi mã trong quá trình diễn biến của một ngày làm việc của lập trình viên trung bình, cho dù điều đó liên quan đến các kỹ thuật phát triển nhanh nhẹn hay không Cuối cùng, bất kỳ hoạt động phức tạp nào có thể được tự động hóa đều là nhàm chán, cần tránh Việc biết các công cụ tái cấu trúc Eclipse có sẵn những gì và cách sử dụng đã dự kiến của chúng, sẽ cải thiện rất nhiều năng suất của bạn

Trang 3

Có hai cách quan trọng để bạn có thể làm giảm nguy cơ làm hỏng mã Một cách là phải có một bộ đầy đủ các bài thử nghiệm bộ phận cho mã đó: mã phải vượt qua các bài thử nghiệm cả trước và sau khi tái cấu trúc Cách thứ hai là sử dụng một công cụ tự động hoá, chẳng hạn như các tính năng tái cấu trúc của Eclipse, để thực hiện phép tái cấu trúc này

Cách kết hợp thử nghiệm kỹ lưỡng và tái cấu trúc tự động đặc biệt mạnh mẽ và đã chuyển nghệ thuật bí ẩn này thành một công cụ thường ngày, có ích Khả năng thay đổi cấu trúc mã của bạn mà không cần thay đổi chức năng của nó, theo cách nhanh chóng và an toàn, thêm chức năng hoặc cải thiện việc bảo trì của nó có thể ảnh hưởng đáng kể đến cách bạn thiết kế và phát triển mã, cho dù bạn kết hợp nó vào một phương thức nhanh nhẹn chính thức hay không

Các kiểu tái cấu trúc trong Eclipse

Các công cụ tái cấu trúc của Eclipse có thể được nhóm lại thành ba thể loại rõ ràng (và đây là thứ tự mà chúng xuất hiện trong trình đơn Refactoring):

1 Thay đổi tên và tổ chức vật lý của mã, bao gồm đổi tên các trường, các biến, các lớp và các giao diện và di chuyển các gói và các lớp

2 Thay đổi tổ chức logic của mã ở mức lớp, gồm việc chuyển các lớp ẩn danh thành các lớp lồng nhau, chuyển các lớp lồng nhau thành các lớp mức cao nhất, tạo ra các giao diện từ các lớp cụ thể và di chuyển các phương thức hoặc các trường từ một lớp đến lớp con hoặc siêu lớp

Trang 4

3 Thay đổi mã trong một lớp, gồm chuyển các biến chuyển địa phương thành các trường lớp, chuyển mã chọn trong phương thức thành một phương thức tách biệt và tạo ra các phương thức getter và setter cho các trường

Một số phép tái cấu trúc gần như không khớp với ba thể loại này, đặc biệt là Thay đổi chữ kí phương thức (Change Method Signature), có trong thể loại thứ ba ở đây Ngoài những trường hợp ngoại lệ này, các phần theo sau sẽ thảo luận về các công cụ tái cấu trúc của Eclipse theo thứ tự này

Tổ chức lại và đổi tên lại vật lý

Bạn rõ ràng có thể đổi tên hoặc di chuyển các tệp xung quanh trong hệ thống tệp

mà không cần một công cụ đặc biệt, nhưng làm như vậy với các tệp mã nguồn Java có thể đòi hỏi bạn phải chỉnh sửa nhiều tệp để cập nhật các câu lệnh import (nhập khẩu) hoặc package (gói) Tương tự như vậy, bạn có thể dễ dàng đổi tên các lớp, các phương thức và các biến bằng cách sử dụng một trình soạn thảo văn bản

để tìm kiếm và thay thế chức năng, nhưng bạn cần phải làm điều này cẩn thận, vì các lớp khác nhau có thể có các phương thức hoặc các biến cùng tên; có thể rất nhàm chán để duyệt qua tất cả các tệp trong một dự án để đảm bảo chắc chắn rằng mọi cá thể được xác định và được thay đổi chính xác

Di chuyển và Đổi tên (Rename and Move) của Eclipse có thể thực hiện các thay đổi này một cách thông minh, trong suốt toàn bộ dự án, mà không có sự can thiệp của người dùng, vì Eclipse hiểu mã theo ngữ nghĩa và có thể xác định các tham chiếu đến một phương thức, biến cụ thể, hoặc các tên lớp Việc thực hiện nhiệm

vụ này dễ dàng giúp đảm bảo rằng phương thức, biến và các tên lớp thể hiện rõ ràng ý định của chúng

Trang 5

Thật dễ dàng tìm ra mã có các tên không phù hợp hoặc gây hiểu nhầm vì mã đã được thay đổi để thực hiện khác so với kế hoạch ban đầu đã lập Ví dụ, một

chương trình tìm kiếm các từ cụ thể trong một tệp có thể được mở rộng để làm việc với các trang Web bằng cách sử dụng lớp URL để có được một InputStream (luồng đầu vào) Nếu trước tiên người ta đã gọi file (tệp) cho luồng đầu vào này, thì nó cần được thay đổi để phản ánh tính chất tổng quát mới hơn của nó, có lẽ là sourceStream (luồng nguồn) Các nhà phát triển thường không tạo ra các thay đổi như thế này vì nó có thể là quá trình lộn xộn và nhàm chán Tất nhiên, điều này làm cho mã khó hiểu với nhà phát triển tiếp theo, tức người phải tiếp tục làm việc với nó

Để đổi tên một phần tử Java, chỉ cần nhấn vào nó trong khung nhìn Package

Explorer (Trình thám hiểm gói) hoặc chọn nó trong một tệp nguồn Java, sau đó

chọn Refactor > Rename Trong hộp thoại, chọn tên mới và chọn xem Eclipse có

cần thay đổi các tham chiếu đến tên không Các trường chính xác được hiển thị tùy thuộc vào kiểu phần tử mà bạn chọn Ví dụ, nếu bạn chọn một trường có phương thức getter và setter, bạn cũng có thể cập nhật các tên của các phương thức này để phản ánh trường mới Hình 1 chỉ ra một ví dụ đơn giản

Hình 1 Đổi tên một biến địa phương

Trang 6

Giống như tất cả các phép tái cấu trúc Eclipse, sau khi bạn đã xác định mọi thứ

cần thiết để thực hiện tái cấu trúc, bạn có thể nhấn Preview (Xem trước) để xem

sự thay đổi mà Eclipse đề xuất thực hiện, trong một hộp thoại so sánh, nó cho phép bạn bác bỏ hoặc chấp nhận từng thay đổi trong mỗi tệp bị tác động tới Nếu

bạn tin vào khả năng của Eclipse để thay đổi đúng, bạn có thể chỉ cần nhấn OK

Tất nhiên, nếu bạn không chắc chắn phép tái cấu trúc sẽ làm gì, trước tiên bạn sẽ muốn xem trước, nhưng với các phép tái cấu trúc đơn giản như Đổi tên và Di chuyển thì điều này thường không cần thiết

Di chuyển thực hiện rất nhiều việc giống như với Đổi tên: Bạn chọn một phần tử Java (thường là một lớp), xác định vị trí mới của nó và xác định liệu các tham

khảo có nên được cập nhật không Sau đó bạn có thể chọn Preview để kiểm tra các thay đổi hoặc nhấn OK để thực hiện ngay lập tức phép tái cấu trúc như trong

Hình 2

Trang 7

Hình 2 Di chuyển một lớp từ một gói này sang một gói khác

Trên một số nền tảng (đặc biệt là Windows), bạn cũng có thể di chuyển các lớp từ một gói hoặc thư mục đến gói hoặc thư mục khác bằng cách kéo và thả chúng vào khung nhìn Package Explorer Tất cả các tài liệu tham khảo sẽ được cập nhật tự động

Trang 8

Định nghĩa lại các mối quan hệ lớp

Một tập nhiều phép tái cấu trúc của Eclipse cho phép bạn thay đổi các mối quan hệ lớp của bạn tự động Các phép tái cấu trúc này không có ích lợi chung như các kiểu tái cấu trúc mà Eclipse phải cung cấp, nhưng có giá trị vì chúng thực hiện nhiệm vụ khá phức tạp Khi chúng được dùng, chúng rất có ích

Tăng cường lớp ẩn danh và lồng nhau

Hai phép tái cấu trúc, Chuyển đổi lớp ẩn danh thành lớp lồng nhau (Convert

Anonymous Class to Nested) và Chuyển đổi lớp lồng nhau tới lớp mức cao nhất (Convert Nested Type to Top Level), là như nhau trong đó chúng di chuyển một lớp ngoài hướng của nó tới nơi có cơ hội để bao bọc

Lớp ẩn danh là loại viết nhanh cú pháp, cho phép bạn thuyết minh một lớp thực hiện một lớp hay giao diện trừu tượng ở nơi bạn cần đến nó, không cần phải cho

nó một tên lớp rõ ràng Điều này thường được sử dụng khi tạo các người nghe trong giao diện người sử dụng chẳng hạn Trong Liệt kê 1, giả định rằng Bag là một giao diện được định nghĩa ở nơi khác để khai báo hai phương thức, get() và set()

Liệt kê 1 Lớp Bag

public class BagExample

{

Trang 10

}

}

Khi lớp ẩn danh trở nên lớn đến mức mã trở nên khó đọc, bạn nên nghĩ đến việc tạo cho lớp ẩn danh một lớp thích hợp; để giữ gìn sự bao bọc (nói cách khác, để ẩn giấu nó khỏi các lớp bên ngoài không cần biết về nó), bạn nên tạo cho lớp này một lớp lồng nhau chứ không phải là một lớp cao nhất Bạn có thể làm điều này bằng

cách nhấn vào bên trong lớp ẩn danh và chọn Refactor > Convert Anonymous Class to Nested Nhập tên cho lớp này, chẳng hạn như BagImpl, khi được nhắc và sau đó chọn Preview hoặc OK Việc này sẽ thay đổi mã như trong Liệt kê 2

Liệt kê 2 Lớp Bag được tái cấu trúc

public class BagExample

Trang 12

Chuyển đổi lớp lồng nhau tới lớp mức cao nhất là có ích khi bạn muốn tạo một lớp lồng nhau có sẵn cho các lớp khác Bạn có thể, ví dụ, đang sử dụng một đối tượng giá trị bên trong một lớp chẳng hạn như lớp BagImpl ở trên Nếu sau này bạn quyết định rằng dữ liệu này nên được dùng chung giữa các lớp, thì phép tái cấu trúc này sẽ tạo một tệp lớp mới từ lớp lồng nhau Bạn có thể làm điều này bằng cách làm nổi bật tên lớp trong tệp nguồn (hoặc nhấn vào tên lớp trong khung nhìn

Outline) và chọn Refactor > Convert Nested Type to Top Level

Phép tái cấu trúc này sẽ yêu cầu bạn cung cấp một tên cho cá thể kèm theo Nó có thể đưa ra đề nghị, như example (ví dụ), mà bạn có thể chấp nhận Ý nghĩa của

việc này sẽ được làm rõ trong giây lát Sau khi nhấn OK, mã cho lớp BagExample

kèm theo sẽ được thay đổi như thể hiện trong Liệt kê 3

Liệt kê 3 Lớp Bag được tái cấu trúc

public class BagExample

Trang 13

}

}

Lưu ý rằng khi một lớp được lồng nhau, nó có quyền truy cập tới các thành viên của lớp bên ngoài Để duy trì chức năng này, phép tái cấu trúc sẽ bổ sung một cá

thể của lớp BagExample kèm theo vào lớp đã lồng nhau trước đây Đây là biến

của cá thể mà trước đây bạn đã được yêu cầu cung cấp một tên cho nó Nó cũng

tạo ra một hàm tạo để thiết lập biến của cá thể này Lớp mới BagImpl do phép tái

cấu trúc tạo ra được hiển thị trong Liệt kê 4

Liệt kê 4 Lớp BagImpl

final class BagImpl implements Bag

Trang 14

Di chuyển thành viên trong hệ thống phân cấp lớp

Trang 15

Hai phép tái cấu trúc khác, Đẩy xuống (Push Down) và Kéo lên (Pull Up), di chuyển các phương thức lớp hoặc các trường từ một lớp đến lớp con hoặc siêu lớp của nó, tương ứng Giả sử bạn có một lớp trừu tượng Vehicle (xe cộ), được xác định như sau trong Liệt kê 5

Liệt kê 5 Lớp trừu tượng Vehicle

public abstract class Vehicle

{

protected int passengers;

protected String motor;

Trang 16

Liệt kê 6 Lớp Automobile

public class Automobile extends Vehicle

{

Trang 17

private String make;

private String model;

public String getMake()

Trang 18

}

}

Chú ý rằng một thuộc tính của Vehicle là motor (động cơ) Thật tốt nếu bạn biết rằng bạn sẽ chỉ luôn đề cập đến các loại xe cơ giới có động cơ, nhưng nếu bạn muốn cho phép những thứ như các thuyền có mái chèo (rowboat), bạn có thể muốn đẩy thuộc tính motor xuống từ lớp Vehicle vào trong lớp Automobile Để

làm điều này, chọn motor trong khung nhìn Outline, rồi chọn Refactor > Push Down

Eclipse đủ thông minh để nhận ra rằng bạn không thể luôn luôn di chuyển một

trường bằng chính nó và cung cấp một nút Add Required, nhưng điều này không

luôn hoạt động đúng trong Eclipse 2.1 Bạn cần phải xác minh rằng các phương thức bất kỳ phụ thuộc vào trường này cũng bị đẩy xuống Trong trường hợp này,

có hai, phương thức getter và setter đi cùng trường motor, như trong Hình 3

Trang 19

Hình 3 Thêm các thành viên cần thiết

Sau khi nhấn OK, trường motor và các phương thức getMotor() và setMotor() sẽ

được chuyển đến lớp Automobile Liệt kê 7 cho thấy hình dạng của lớp

Automobile sau phép tái cấu trúc này

Liệt kê 7 Lớp Automobile được tái cấu trúc

public class Automobile extends Vehicle

{

Trang 20

private String make;

private String model;

protected String motor;

public String getMake()

Trang 22

lớp Bus Một cách thể hiện mối quan hệ như vậy là tạo ra một giao diện,

Motorized, trong đó Automobile và Bus sẽ thực hiện, nhưng RowBoat thì không

Cách dễ nhất để tạo ra giao diện Motorized là sử dụng tái cấu trúc Lấy ra giao diện (Extract Interface) trên Automobile Để làm điều này, chọn lớp Automobile trong

khung nhìn Outline và sau đó chọn Refactor > Extract Interface từ trình đơn

Hộp thoại sẽ cho phép bạn chọn những phương thức nào bạn muốn đưa vào trong giao diện như trong Hình 4

Hình 4 Lấy ra giao diện Motorized

Sau khi chọn OK, một giao diện được tạo ra, như được hiển thị trong Liệt kê 8

Liệt kê 8 Giao diện Motorized

Trang 23

public interface Motorized

{

public abstract String getMotor();

public abstract void setMotor(String string);

}

Và việc khai báo lớp cho Automobile được thay đổi như sau:

public class Automobile extends Vehicle implements Motorized

Sử dụng một siêu kiểu (supertype)

Phép tái cấu trúc cuối cùng có trong thể loại này là Sử dụng siêu kiểu ở nơi có thể (Use Supertype Where Possible) Hãy xem xét một ứng dụng quản lý hàng tồn kho

ô tô Từ đầu đến cuối, nó sử dụng các đối tượng của kiểu Automobile Nếu bạn muốn có thể xử lý tất cả các kiểu xe cộ, bạn có thể sử dụng phép tái cấu trúc này

để thay đổi các tham chiếu đến Automobile thành các tham chiếu đến Vehicle (xem Hình 5) Nếu bạn thực hiện bất kỳ việc kiểm tra kiểu nào trong mã của bạn bằng cách sử dụng toán tử instanceof, bạn sẽ cần phải xác định xem nó có phù hợp

để sử dụng các kiểu cụ thể hoặc siêu kiểu không và kiểm tra tùy chọn đầu tiên Sử dụng siêu kiểu đã chọn trong các biểu thức 'instanceof', cho phù hợp

Ngày đăng: 07/08/2014, 10:22

HÌNH ẢNH LIÊN QUAN

Hình 1. Đổi tên một biến địa phương - Tái cấu trúc cho mọi người docx
Hình 1. Đổi tên một biến địa phương (Trang 5)
Hình 2. Di chuyển một lớp từ một gói này sang một gói khác - Tái cấu trúc cho mọi người docx
Hình 2. Di chuyển một lớp từ một gói này sang một gói khác (Trang 7)
Hình 3. Thêm các thành viên cần thiết - Tái cấu trúc cho mọi người docx
Hình 3. Thêm các thành viên cần thiết (Trang 19)
Hình 4. Lấy ra giao diện Motorized - Tái cấu trúc cho mọi người docx
Hình 4. Lấy ra giao diện Motorized (Trang 22)
Hình 5. Thay đổi Automobile sang siêu kiểu của nó, Vehicle - Tái cấu trúc cho mọi người docx
Hình 5. Thay đổi Automobile sang siêu kiểu của nó, Vehicle (Trang 24)
Hình 6. Không thay thế tất cả các thể hiện của biểu thức được chọn - Tái cấu trúc cho mọi người docx
Hình 6. Không thay thế tất cả các thể hiện của biểu thức được chọn (Trang 29)
Hình 7. Bao bọc một trường - Tái cấu trúc cho mọi người docx
Hình 7. Bao bọc một trường (Trang 36)
Hình 8. Các tùy chọn thay đổi Chữ kí phương thức - Tái cấu trúc cho mọi người docx
Hình 8. Các tùy chọn thay đổi Chữ kí phương thức (Trang 41)

TỪ KHÓA LIÊN QUAN

w