Tái cấu trúc mã nguồn: Chia nhỏ mã nguồn

405

Bài viết được sự cho phép của BBT Tạp chí Lập trình

Tách phương thức: Tách từ một phương thức dài lấy một phương thức mới nhỏ hơn. Việc chia từ một phương thức dài thành nhiều phương thức nhỏ sẽ làm mã tốt hơn như: dễ hiểu, để bảo trì, dễ tái sử dụng hơn.

  9 mã nguồn mở cho file upload field
  Tái cấu trúc mã nguồn

Các bước:

  1. Tạo phương thức mới có tên phù hợp với chức năng.
  2. Sao và dán đoạn mã muốn tách từ phương thức ban đầu vào phương thức mới.
  3. Tìm tất cả các tham chiếu ở đoạn mã sao tới các biến của phương thức ban đầu. Các biến này sẽ là các biến cục bộ và tham số của phương thức mới.
  4. Khai báo biên cục bộ cho tất cả các biến tạm ở đoạn mã sao.
  5. Tìm tất cả các biến ở hàm gốc bị thay đổi giá trị ở đoạn mã sao. Nếu chỉ có một bị thay đổi thì có thể truyền giá trị đó vào bằng đối số và gán cho giá trị tương ứng. Nhưng nếu có nhiều hơn thì phải chú ý!
  6. Truyền tất cả mọi biến được tham chiếu chỉ để đọc ở mã được sao vào phương thức mới như tham số.
  7. Biên dịch để kiểm tra xem mọi biến cục bộ đã được xử lý.
  8. Thay đoạn mã đã sao bằng phương thức mới.
  9. Biên dịch và kiểm thử.

Ví dụ:

[sourcecode language=”java”] void printOwing() {
Enumeration e = _orders.elements();
double outstanding = 0.0;

// print banner
System.out.println ("**************************");
System.out.println ("***** Customer Owes ******");
System.out.println ("**************************");

// calculate outstanding
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}

//print details
System.out.println ("name:" + _name);
System.out.println ("amount" + outstanding);
}

[/sourcecode]

Dễ dàng tách đoạn mã hiển thị tiêu đề bằng các cắt và dãn

[sourcecode language=”java”] void printOwing() {
Enumeration e = _orders.elements();
double outstanding = 0.0;

printBanner();

// calculate outstanding
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}

//print details
System.out.println ("name:" + _name);
System.out.println ("amount" + outstanding);
}

void printBanner() {
// print banner
System.out.println ("**************************");
System.out.println ("***** Customer Owes ******");
System.out.println ("**************************");
}

[/sourcecode]

Ví dụ có biến cục bộ chỉ để đọc: Trong trường hợp này ta đơn giản là truyền chúng theo tham số. Ở ví dụ trên ta có thể tách phương thức để in ra thông tin chi tiết từ phương thức printOwning

[sourcecode language=”java”] void printOwing() {

Enumeration e = _orders.elements();
double outstanding = 0.0;

printBanner();

// calculate outstanding
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}

printDetails(outstanding);
}

void printDetails (double outstanding) {
System.out.println ("name:" + _name);
System.out.println ("amount" + outstanding);
}

[/sourcecode]

Và bạn có thể truyền vào số lượng biến cục bộ tùy thích.

Ví dụ có gán giá trị cho biến cục bộ:

Trong trường hợp này chúng ta chỉ đề cập tới trường hợp biến cục bộ của hàm gốc, nếu là có thay đổi giá trị cho tham số thì xem kỹ thuật tái cấu trúc xóa gán cho tham số.

Từ phương thức printOwing có ở trên:

[sourcecode language=”java”] void printOwing() {

Enumeration e = _orders.elements();
double outstanding = 0.0;

printBanner();

// calculate outstanding
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}

printDetails(outstanding);
}

[/sourcecode]

Ta có thể tách thành:

[sourcecode language=”java”] void printOwing() {
printBanner();
double outstanding = getOutstanding();
printDetails(outstanding);
}

double getOutstanding() {
Enumeration e = _orders.elements();
double outstanding = 0.0;
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}
return outstanding;
}

[/sourcecode]
  • Tách lớp: tách một phần của lớp đã tồn tại thành một lớp mới. Một lớp có kích thước tăng dần và tới trở nên khó hiểu và khó bảo trì. Lúc đó ta phải tách nhỏ lớp đó ra.

    Các bước:

  1. Cách chia trách nhiệm của các lớp
  2. Tạo lớp mới để chia sẻ trách nhiệm với lớp ban đầu
  3. Tạo một liên kết từ lớp ban đầu tới lớp mới
  4. Thực hiện viên di chuyển từng trường và phương thức từ lớp cũ sang lớp mới
  5. Biên dịch và kiểm thử.

Ví dụ:Ta phải tách một lớp đơn giản:

[sourcecode language=”java”] class Person…
public String getName() {
return _name;
}
public String getTelephoneNumber() {
return _officeAreaCode + " " + _officeNumber;
}
String getOfficeAreaCode() {
return _officeAreaCode;
}
void setOfficeAreaCode(String arg) {
_officeAreaCode = arg;
}
String getOfficeNumber() {
return _officeNumber;
}
void setOfficeNumber(String arg) {
_officeNumber = arg;
}

private String _name;
private String _officeAreaCode;
private String _officeNumber;

[/sourcecode]
  1. Cách chia trách nhiệm của các lớp: ta muốn chia thành một lớp chứa thông tin về số điện thoại.
  2. Tạo lớp mới để chia sẻ trách nhiệm với lớp ban đầu
    [sourcecode language=”java”] class TelephoneNumber {}
    [/sourcecode]
  3. Tạo một liên kết từ lớp Person tới lớp TelephoneNumber

    [sourcecode language=”java”] class Person
    private TelephoneNumber _officeTelephone = new TelephoneNumber();[/sourcecode]

  4. Thực hiện viên di chuyển từng trường và phương thức từ lớp cũ sang lớp mới
    [sourcecode language=”java”] class Person…
    
    public String getName() {
    
    return _name;
    
    }
    
    public String getTelephoneNumber(){
    
    return _officeTelephone.getTelephoneNumber();
    
    }
    
    TelephoneNumber getOfficeTelephone() {
    
    return _officeTelephone;
    
    }
    
    private String _name;
    private TelephoneNumber _officeTelephone = new TelephoneNumber();
    class TelephoneNumber…
    public String getTelephoneNumber() {
    return ("(" + _areaCode + ") " + _number);
    }
    String getAreaCode() {
    return _areaCode;
    }
    void setAreaCode(String arg) {
    _areaCode = arg;
    }
    String getNumber() {
    return _number;
    }
    void setNumber(String arg) {
    _number = arg;
    }
    private String _number;
    private String _areaCode;
    
    [/sourcecode]
  5. Biên dịch và kiểm thử.

Bài viết gốc được đăng tải tại tapchilaptrinh.vn

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev