Từ thợ đến thầy - Refactor
Software Engineering
36
White

Ngoc Dao viết ngày 22/03/2016

Khi chương trình tiến hoá, sẽ cần suy tính lại những quyết định cũ và bắt tay sửa lại chương trình. Việc sửa lại, cấu trúc lại chương trình mà giữ nguyên tính năng gọi là refactor. Việc này trên lí thuyết hoàn toàn tự nhiên, nhưng thực tế lại rất phức tạp. Cấp quản lí bảo:

  • Ê, chương trình chạy được sao lại phải sửa?
  • Này, sửa lại sẽ mất thời gian, thay vì mất thời gian sửa chẳng thêm được tí tính năng nào, hãy tập trung thêm tính năng mới
  • ĐM, người mới cứ sửa mã của người cũ thế này thì loạn

Why

Ngụy biện thường gặp:

  • Thời hạn giao hàng thường là lí do được đưa ra để trốn refactor: xong project rồi refactor sau => Xong project này sẽ có project khác.
  • Premature optimize is the root of all evil => Refactor không phải là optimize.
  • Từ từ, khi nào mã nhiều nhiều sẽ refactor => Nếu không refactor sớm, sẽ đến lúc việc thêm tính năng mới mất rất nhiều công sức, lúc này refactor sẽ mất công hơn. Giống xây nhà: phía dưới đã yếu, thì sẽ đến lúc không thể xây thêm, xây thêm sẽ gây sụp đổ toàn bộ. Có câu: refactor early, refactor often. Có best practice: họp để code review hàng tuần để refactor.

Theo thời gian độ phức tạp của mã sẽ tăng. Theo đó, thiết kế kém và mã xấu bắt đầu xuất hiện. Hãy chấp nhận sự thật khách quan là chúng luôn tồn tại như khối ung thư, cần được loại bỏ.

When

  • Trùng lặp. Khi cứ phải copy cả khối mã từ chỗ này sang chỗ kia, là lúc bạn vi phạm nguyên tắc DRY. Hãy bắt chước học sinh cấp 2, đặt khối mã chung này thành nhân tử chung.
  • Thiết kế không trực giao.
  • Chậm. Thường phải chuyển tính năng từ chỗ này sang chỗ kia để tăng tốc độ.

How

Bản chất của refactor là redesign. Hiển nhiên, cần hết sức thận trọng khi refactor.

  • Đừng vừa refactor vừa thêm tính năng.
  • Nên có test tự động trước rồi hẵng refactor. Cần chạy test thường xuyên để đảm bảo refactor không gây lỗi.
  • Refactor từng chút từng chút một, giới hạn khu vực ảnh hưởng càng nhỏ càng tốt.

Refactor là loại bỏ khối u ung thư: càng phẫu thuật sớm càng tốt. Đợi đến khi mã xấu lan rộng mới phẫu thuật thì tốn công, dễ mất kiên nhẫn. Hãy đưa refactor vào schedule, nếu không làm được ngay thì cũng chắc là nó được ghi nhớ và thực hiện càng sớm càng tốt.

Phẫu thuật thì phải đau. Điều quan trọng là xử lí nỗi đau như thế nào. Hãy nhớ kinh nghiệm "cửa sổ vỡ" của cảnh sát New York (nơi tỉ lệ tội phạm cao nhất Mỹ): nếu giải quyết vụ án "cửa sổ vỡ" (nhỏ) ngay, thì số lượng án mạng lớn giảm hẳn.

Ví dụ

Đoạn mã sau đã được thay đổi nhiều lần trong vài năm, nhưng cấu trúc chưa được cải tiến. Hãy refator.

if (state == TEXAS) {
rate = TX_RATE;
amt = base * TX_RATE;
calc = 2*basis(amt) + extra(amt)*1.05;
}
else if ((state == OHIO) || (state == MAINE))
rate = (state == OHIO) ? OH_RATE : MN_RATE];
amt = base * rate;
calc = 2*basis(amt) + extra(amt)*1.05;
if (state == OHIO)
points = 2;
}
else {
rate = 1;
amt = base;
calc = 2*basis(amt) + extra(amt)*1.05;
}

Cần sửa để dễ dàng thêm nhiều loại hình dạng. Hãy refactor.

public class Shape {
public static final int SQUARE = 1;
public static final int CIRCLE = 2;
public static final int RIGHT_TRIANGLE = 3;

private int shapeType;
private double size;

public Shape(int shapeType, double size) {
this.shapeType = shapeType;
this.size = size;
}

// ... other methods ...

public double area() {
switch (shapeType) {
case SQUARE: return size*size;
case CIRCLE: return Math.PI*size*size/4.0;
case RIGHT_TRIANGLE: return size*size/2.0;
}
return 0;
}
}

Hãy refactor để đoạn mã sau tổng quát hơn.

public class Window { 
public Window(int width, int height) { ... }
public void setSize(int width, int height) { ... }
public boolean overlaps(Window w) { ... }
public int getArea() { ... }
}

Nguồn: From Journeyman to Master

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Ngoc Dao

102 bài viết.
252 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
56 6
Làm thế nào để nâng cấp trang web mà không làm gián đoạn dịch vụ? Đây là câu hỏi phỏng vấn các công ty lớn thường hỏi khi bạn xin vào vị trí làm lậ...
Ngoc Dao viết 2 năm trước
56 6
White
32 0
Bài viết này giải thích sự khác khác nhau giữa hai ngành khoa học máy tính (computer science) và kĩ thuật phần mềm (software engineering), hi vọng ...
Ngoc Dao viết gần 2 năm trước
32 0
White
28 1
Nếu là team leader, giám đốc công ty hay tướng chỉ huy quân đội, vấn đề cơ bản bạn gặp phải là “hướng mọi người đi theo con đường bạn chỉ ra”. Thử...
Ngoc Dao viết gần 2 năm trước
28 1
Bài viết liên quan
White
1 1
Lập trình đôi (pair programming) là hình thức lập trình trong đó 2 người cùng hợp tác làm việc trên cùng màn hình (có thể khác bàn phím v.v.). Bài ...
Ngoc Dao viết gần 2 năm trước
1 1
White
5 1
Trong quyển sách Beyond Java, xuất bản vài năm trước có đoạn:Java has characteristics that many of us take for granted. You can find good Java deve...
Ngoc Dao viết gần 2 năm trước
5 1
White
3 0
Lập trình viên quá cố người Mỹ Phil Karlton có câu nổi tiếng: There are only two hard things in Computer Science: cache invalidation and naming th...
Ngoc Dao viết gần 2 năm trước
3 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
102 bài viết.
252 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!