2009-11-29 36 views
11

Đây có phải là thực tiễn mã hóa có thể chấp nhận được không?Sử dụng toán tử bậc ba với 4 biểu thức

public class MessageFormat { 
    private static final Color DEFAULT_COLOR = Color.RED; 

    private Color messageColor = DEFAULT_COLOR; 

    public MessageFormat(Person person) { 
     Color color = person.getPreferredColor(); 
     messageColor = (color != null) ? color : messageColor; // this line 
    } 
} 

hay tôi khấm khá hơn đi với cổ điển ...

if (color != null) { 
    messageColor = color; 
} 
+1

Đó là chính thức các operator__ __conditional, [ theo JLS] (http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.25). Về mặt kỹ thuật, có thể có các toán tử bậc ba khác, giống như có nhiều toán tử nhị phân, mặc dù Java hiện không có bất kỳ toán tử nào. – Pops

Trả lời

24

Việc sử dụng toán tử?: Phải được giới hạn để làm cho mã dễ đọc hơn. Ví dụ cổ điển:

a = sprintf("There are %i green bottle%s on the wall.", i, (i==1?"":"s")); 

Trong trường hợp này, mã sẽ ít có thể đọc được nếu bạn chia nhỏ thành 5 dòng nếu/khác.

Tôi thường đặt các dấu ngoặc quanh toàn bộ toán tử để khi đọc nó, tôi phân tích cú pháp nó như một giá trị duy nhất.

messageColor = (color != null ? color : messageColor); 

biến thể khác là

messageColor = color || messageColor; 

Mà trong một số ngôn ngữ sẽ đánh giá để "màu, trừ màu đánh giá là 'false', trong trường hợp giá trị của messageColor. Theo tôi đây nên tránh như nó có thể nhầm lẫn giữa người.

điều quan trọng nhất là phải phù hợp để người tiếp theo đọc mã của bạn (ngay cả khi đó là bạn) có overhead nhận thức tối thiểu.

+0

ví dụ tuyệt vời. Dễ hiểu. –

0

vẻ tốt với tôi (tôi sử dụng nhà điều hành ternary Python của rất nhiều), nhưng loại này của vấn đề phong cách thường rất chủ quan . Nếu dự án có tài liệu kiểu mã hóa, bạn có thể muốn kiểm tra điều đó.

1

Tôi thích thứ hai vì nó thể hiện rõ ràng ý của bạn: bạn chỉ muốn thay đổi màu nếu nó không phải là rỗng. Phương pháp đầu tiên không làm cho điều này rõ ràng.

2

Việc sử dụng toán tử bậc ba thường là vấn đề nhạy cảm, cùng với các tiêu chuẩn mã hóa khác. Việc sử dụng nó có thể được xác định tốt nhất bằng các tiêu chuẩn mã hóa tại trang web của bạn.

Tuy nhiên, trong trường hợp cụ thể này, tôi chắc chắn sẽ đề xuất tùy chọn thứ hai; không chỉ là nó rõ ràng hơn, nhưng việc sử dụng các nhà điều hành ternary là hoàn toàn không cần thiết ở đây. Không cần phải gán lại MessageColor cho chính nó, vì vậy hàm duy nhất của toán tử ternary trong tình huống cụ thể này là mã obfuscation.

1

Nhà khai thác mạng thường bị lạm dụng vì mã họ sản xuất có vẻ thông minh và nhỏ gọn.

Thực tế, chúng làm cho mã dễ đọc hơn và dễ bị lỗi hơn. Bất cứ khi nào có thể, bạn nên sử dụng phiên bản dài hơn của

if (<condition>) { 
    <action> ; 
} 

Thay vì cú pháp bậc ba.

+0

không hoàn toàn đúng: các toán tử bậc ba có thể làm cho mã dễ đọc hơn (không phải lúc nào, tôi đồng ý) –

2

Toán tử bậc ba phổ biến hơn trong số các lập trình viên C. Trong C nếu bạn tránh các cấu trúc điều khiển, bạn thường có thể nhận được pipelining tốt hơn, vì không có dự đoán nhánh nào bị sai. Tôi nghi ngờ bạn sẽ thấy bất kỳ sự khác biệt về hiệu suất trong Java, và mô hình if-null-then-assign là phổ biến hơn nhiều so với ternary. Tuy nhiên, nếu bạn đang duy trì một codebase hiện tại, tốt nhất là nên duy trì tính nhất quán với mã hiện có.

Nếu bạn thấy mình làm việc này rất nhiều, bạn có thể viết hàm defaultIfNull, firstNonNull hoặc coalesce có thể làm cho mã ngắn gọn hơn. Apache Commons Lang includes a defaultIfNull function.

Một số ngôn ngữ bao gồm toán tử ||=, là thành ngữ thông thường để đặt giá trị mặc định bằng các ngôn ngữ đó.

+0

Sử dụng toán tử điều kiện trong C không "tránh cấu trúc điều khiển". Hãy xem đầu ra trình biên dịch của bạn. –

+0

Tôi đã xem xét đầu ra trình biên dịch của mình. http://www.theeggeadventure.com/wikimedia/index.php/Ternary_Operator_in_C Hóa ra trình biên dịch C gcc có thể tạo một assembly giống nhau bất kể bạn sử dụng cấu trúc bậc ba hoặc nếu/thì/khác. – brianegge

+1

Đúng vậy, trình biên dịch có thể tạo mã chi nhánh miễn phí nếu nó có thể, cho câu lệnh 'if' hoặc toán tử điều kiện. Nếu không thể, thì một trong hai câu lệnh sẽ được tạo ra với các nhánh. Tôi đang đề cập đến ý nghĩa của bạn rằng "tránh các cấu trúc điều khiển" là giống như "sử dụng toán tử điều kiện". –

1

Trong trường hợp của bạn, tôi thích việc thực hiện 'cổ điển', bởi vì với tôi nó nhanh hơn để hiểu, rằng bạn chỉ muốn sử dụng một màu mới nếu người đó có một cái được ưa thích hơn.

đôi khi tôi sử dụng nó trong phương thức gọi nếu tôi muốn tránh NPEs, nhưng tôi thường elimate những mảnh xấu xí của mã trong một trong những phép tái cấu trúc tiếp theo;)

4

Độ khó, dễ hiểu, vv đều giống nhau ở trường hợp này (Ý tôi là, hãy truy cập ...). Tôi không thích sự sao chép và phân công rõ ràng trong ví dụ đầu tiên; nó sẽ dịch sang một cái gì đó như:

if (colour != null) {messageColour = colour;} 
    else {messageColour = messageColour;}; 

hơi ngu ngốc.

Tôi thường viết bài thứ hai trong một dòng, nhưng đó là câu hỏi về sự tôn trọng cá nhân ưa thích. hướng dẫn phong cách mã hóa:

if (colour != null) {messageColour = colour;}; 

EDIT (Tôi bây giờ hơn khăng khăng hơn 8 năm trước)

Vì bạn đang tìm kiếm thông lệ tốt nhất:

// Use default visibility by default, especially in examples. 
// Public needs a reason. 
class MessageFormat { 
    static final Color DEFAULT_COLOR = Color.RED; 

    // Strongly prefer final fields. 
    private final Color messageColor; 

    // Protect parameters and variables against abuse by other Java developers 
    MessageFormat (final Person person) { 
     // Use Optionals; null is a code smell 
     final Optional<Color> preferredColor = person.getPreferredColor(); 
     // Bask in the clarity of the message 
     this.messageColor = preferredColor.orElse(DEFAULT_COLOR); 
    } 
} 
+0

Hoặc thậm chí nếu (màu! = Null) messageColour = color; –

Các vấn đề liên quan