Giới thiệu các biến cục bộ bổ sung như thay thế bình luận


12

Đây có phải là phong cách tốt để sử dụng các biến cục bộ bổ sung, kỹ thuật thừa để mô tả những gì đang xảy ra không?

Ví dụ:

bool easyUnderstandableIsTrue = (/* rather cryptic boolean expessions */);

if(easyUnderstandableIsTrue)
{
    // ...
}

Khi nói đến chi phí kỹ thuật, tôi hy vọng trình biên dịch sẽ tối ưu hóa dòng bổ sung này. Nhưng nó có được coi là một sự phình to mã không cần thiết? Trong mắt tôi nó làm giảm nguy cơ bình luận cũ.


10
"Đó có phải là phong cách tốt để sử dụng các biến cục bộ bổ sung, kỹ thuật thừa để mô tả những gì đang xảy ra không?". Đúng. Không có nhiều điều khác có thể được nói ở đây, thực sự.
David Arno

3
Tôi thấy một phong cách như vậy (tức là sử dụng nhiều biến trung gian với tên mô tả) khá hữu ích khi đọc mã của tôi sau này. Tất nhiên bạn có thể viết các biểu thức phức tạp và lưu một vài tên bằng cách không đưa ra các biến trung gian, nhưng tại sao bạn lại muốn? Đọc mã có thể là một thách thức khá lớn ngay cả khi nó được viết tương đối tốt, vì vậy tôi không nghĩ rằng việc phức tạp hóa nó nhiều hơn là một lộ trình hợp lý.
Mael

Tôi tin rằng điều này được gọi là Hợp nhất biểu thức có điều kiện trong danh mục tái cấu trúc của Martin Fowler .
Brandin

Câu trả lời:


16

Chi phí để có một biến bổ sung là gì? Trong hầu hết các ngôn ngữ, không có, cả trong các ngôn ngữ được biên dịch và giải thích.

Lợi ích của việc này là gì?

  • Tương tự như trích xuất biểu thức boolean khó hiểu sang một phương thức riêng biệt, bạn đang giảm rủi ro của mã trùng lặp , nhưng ít hơn một chút so với trường hợp của một phương thức riêng biệt. Nếu biểu thức điều kiện được sử dụng lại bên trong chính phương thức, bạn sẽ có thể sử dụng lại biến đó; nếu biểu thức xuất hiện trong một phương thức khác, bạn sẽ không.

    Lưu ý rằng trừ khi ngôn ngữ lập trình của bạn cho phép bạn có các biến cục bộ bất biến hoặc bạn có cách để thực thi, theo kiểu khôn ngoan, rằng không có biến nào được gán lại, việc tái cấu trúc như vậy có thể gặp rủi ro trong dài hạn. Nếu giá trị của biến bị thay đổi, có thể rất khó để suy luận về mã.

  • Bạn đang giảm nguy cơ tài liệu không đồng bộ với mã . Các nhà phát triển có xu hướng cập nhật tên của các biến và phương thức dễ dàng hơn các bình luận. Vì vậy, không có gì lạ khi thấy mã như:

    // Find if the user is an actual author in order to allow her to edit the message.
    if (currentUser.isAdministrator || (message.author == currentUser && !message.locked))

Biểu thức có thể bắt đầu bằng if (message.author == currentUser), và sau đó được phát triển để xử lý trường hợp tin nhắn bị khóa và quản trị viên không cần phải là tác giả và không quan tâm đến nội dung bị khóa; tuy nhiên, bình luận không phản ánh bất kỳ thay đổi nào.

Cả hai lợi ích không đặc biệt quan trọng, nhưng với chi phí thấp cho các biến bổ sung, bạn thực sự có thể cân nhắc sử dụng chúng.

Lưu ý rằng nếu biểu thức boolean của bạn trở nên quá phức tạp: ²

  • Trích xuất nó sang một phương thức riêng biệt và:
  • Tái cấu trúc nó thành nhiều biểu thức boolean đơn giản.

Ví dụ trên trở thành:

class Message
{
    ...
    public boolean canBeEditedBy(User user)
    {
        ...
        if (user.isAdministrator) {
            return true;
        }

        return this.author == user && !this.locked;
    }
}

...
if (message.canBeEditedBy(currentUser)) // See? Much more readable now!
{
    ...
}

Nguồn: quan sát của riêng tôi về các đồng nghiệp của tôi đang phát triển phần mềm kinh doanh; YMMV. Một nghiên cứu thực sự có thể cho thấy kết quả khác nhau. Cá nhân, tôi cho rằng khi các nhà phát triển đọc mã, họ đang tập trung vào mã và các bình luận là tài liệu, không phải mã; do đó, họ thường không đọc bình luận, vì vậy sẽ rất khó để mong họ cập nhật chúng.

² Ngưỡng quá phức tạp được xác định bằng một công thức đơn giản: nếu một nửa số nhà phát triển xem xét mã của bạn thể hiện ý định giết bạn, thì ngưỡng đó đã đạt được. Biểu thức boolean ở trên đủ đơn giản để yêu cầu tái cấu trúc; tuy nhiên, bốn phần liên tiếp if ((a && b) || (c && d))sẽ khiến nó có khả năng tái cấu trúc. Lưu ý rằng nếu biểu thức là phẳng, số lượng phần lớn không liên quan: if (a || b || c || d || ... || z)có thể đọc được.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.