Chia nhỏ mã nguồn

Chia nhỏ mã

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.

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 chép 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ụ:

 

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);

}

 

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

 

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 ("**************************");

}

 

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

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);

}

 

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 cải tiến xóa gán cho tham số.

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

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);

}

 

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

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;

}

 

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:

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;

 


 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

class TelephoneNumber {}

 3. Tạo một liên kết từ lớp Person tới lớp TelephoneNumber

class Person

   private TelephoneNumber _officeTelephone = new TelephoneNumber();

 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

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;

  5. Biên dịch và kiểm thử.