2009-06-20 22 views
9
procedure MyProc(Eval: Boolean); 
begin  
    if not Eval then 
     Exit; 
    /* do stuff */ 
    /* do more stuff */ 
end; 

HOẶCTùy chọn nào tốt hơn?

procedure MyProc(Eval: Boolean); 
begin 
    if Eval then 
     begin 
     /* do stuff */ 
     /* do more stuff */ 
     end; 

    /* no Exit needed, but now we got what I think unpleasing code: 
    having a indentation level and a begin-end statement */ 
end; 
+9

Tại sao bạn không chỉ làm công cụ và nhiều thứ khác trong chức năng của bạn và sau đó đặt câu lệnh if xung quanh lời gọi hàm? Hay tôi đang thiếu thứ gì đó ở đây? –

+0

Tomas, bạn có thể kiếm được điểm ... Nhận xét này tốt bằng câu trả lời. Và nó đã được upvoted bởi một vài ... –

+0

Thaks Thomas bởi formmating! Vâng, tôi biết nó phá vỡ sự gắn kết, nhưng chúng ta hãy nói rằng hai stufs xử lý hai miền rất khác nhau, vì vậy chúng tôi không thể khóa nó vào một chức năng mới. –

Trả lời

1

Tôi có thể thực hiện một lời cầu xin rằng nếu bạn sử dụng biểu mẫu thứ hai, bạn không thêm mức độ thụt lề ectra vô cớ. Vì vậy, insrtead của:

procedure MyProc(Eval: Boolean); 
begin 
    if Eval then 
     begin 
     /* do stuff */ 
     /* do more stuff */ 
     end; 

    /* no Exit needed, but now we got what I think unpleasing code: 
    having a indentation level and a begin-end statement */ 
end; 

nói:

procedure MyProc(Eval: Boolean); 
begin 
    if Eval then 
    begin 
     /* do stuff */ 
     /* do more stuff */ 
    end; 

    /* no Exit needed, but now we got what I think unpleasing code: 
    having a indentation level and a begin-end statement */ 
end; 
+0

Không có chỉ trích nào được dự định. Vấn đề là rất nhiều người sử dụng các mức thụt lề không cần thiết, và đó là một nỗi đau lớn. Có một phong cách imndenetation C rất khủng khiếp mà là hơi tương tự như ví dụ đầu tiên và cần phải được dẫm lên. –

+0

@Neil Butterworth: Wow người đàn ông, đó là một sai lầm hình thành, xin lỗi về điều đó. Tôi không hoàn toàn có kỹ năng với trình soạn thảo câu trả lời cũng như tiếng Anh của tôi, nhưng dù sao chúng tôi cũng phải xác định/* làm công cụ */và/* làm nhiều thứ hơn * –

16

Có những trường hợp khi một trong hai phương pháp là thích hợp. Thông thường, tuy nhiên, đầu tiên cung cấp mã dễ đọc hơn và luồng điều khiển tốt hơn. Tôi không quen thuộc với lập trình Delphi, nhưng trong C# tôi luôn cố gắng sử dụng cái cũ khi có thể. Bởi cái nhìn của nó, tôi thấy không có lý do gì mà cách tiếp cận nên khác nhau trong Delphi.

Để liệt kê một vài trong số các ưu điểm:

  • Không cần phải thụt đang tiếp theo.
  • Dễ dàng mở rộng đến nhiều điều kiện. (Chỉ cần thêm phần bổ sung nếu các câu lệnh thay vì các toán tử logic, điều này làm cho IMO rõ ràng hơn.)
  • Ý tưởng rằng bạn đang "chọn không tham gia" phương pháp thay vì chọn tham gia là dễ chịu hơn về mặt thẩm mỹ. trường hợp "bình thường".

Tuy nhiên, có những trường hợp tùy chọn thứ hai thích hợp hơn. Đặc biệt, khi phương thức cần được chia thành các phần con (mặc dù đây thường là dấu hiệu cho thấy bạn cần phải cấu trúc lại).

10

Tôi nghĩ đây là vấn đề ưu tiên. Tuy nhiên, nếu bạn có một số kiểm tra mà bạn phải thực hiện trước khi thực hiện 'công việc thực tế' thì biểu mẫu đầu tiên (IMO) trông gọn gàng hơn và dễ dàng hơn để theo dõi luồng. Ví dụ:

procedure MyProc(Eval: Boolean); 
begin 
    if not Eval then 
     Exit; 
    if not Eval2 then 
     Exit; 
    /* do stuff */ 
    /* do more stuff */ 
end; 

v.s.

procedure MyProc(Eval: Boolean); 
begin 
    if Eval then 
    begin 
     if Eval2 then 
     begin 
      /* do stuff */ 
      /* do more stuff */ 
     end; 
    end; 
end; 
+0

Ví dụ thứ hai không phải là tốt nhất, vì bạn có thể sử dụng toán tử logic để đơn giản hóa nó. – Noldorin

+0

@Noldorin: Điểm công bằng, nhưng tôi không muốn quá phức tạp ví dụ. Tuy nhiên, bạn có thể tưởng tượng các kịch bản trong đó 'Eval2' là một chuỗi các câu lệnh phức tạp hơn mà không thể được kết hợp nhỏ với kiểm tra 'Đánh giá'. – DaveR

+0

Vâng, đủ công bằng. Tôi vẫn rất đồng ý với điểm chung của bạn. – Noldorin

4

Có những người sẽ cho rằng bạn chỉ nên có một điểm xuất cảnh trong chức năng của bạn nhưng tôi không ở trong trại đó.

Tôi thường xuyên sử dụng nhiều trả lại và nó không ảnh hưởng đến khả năng đọc của các chức năng suy nghĩ ngắn vì vậy tôi chỉ nói cho bất cứ điều gì bạn nghĩ là dễ đọc hơn.

Tôi đã có mã refactor người tôi đã viết để làm theo "quy tắc" và nó hầu như luôn luôn kết thúc với một morass của mã không đọc được do chủ yếu là thụt lề quá mức. Họ nên để nó hoặc làm nó một cách đúng đắn, phá vỡ nó thành nhiều chức năng hơn.

Một ít phiền toái đặc biệt tôi thấy là thích của "else" trong:

if (some condition) 
    return false; 
else 
    keep going; 

Họ nghĩ rằng dòng chảy của kiểm soát được bằng cách nào đó sẽ thoát khỏi mệnh đề "then"?

+0

Tôi đồng ý rằng kiểu chữ thường quá hạn. –

3

Tôi sử dụng biểu mẫu đầu tiên rất nhiều. Nó là một chương trình bital của các điều kiện trước, đặc biệt bởi vì khi mã được chèn vào giữa các kiểm tra thực tế trong ví dụ thứ hai, các điều kiện chính xác ít rõ ràng hơn.

Tôi cố gắng hạn chế sử dụng EXIT để kiểm tra điều kiện đầu tiên của quy trình, để tránh quá nhiều spaghetti, nhưng tôi nghĩ biểu mẫu đầu tiên sạch hơn so với vòng để nhảy để duy trì điểm thoát đó.

Và nó dường như được sử dụng rất nhiều, xem xét thực tế rằng exit (returnValue) đã được bổ sung trong D2009 (và FPC có nó trong một thập kỷ)

0

Thực tế là điều này là quá đơn giản một ví dụ để nói láo trên . Bạn sẽ chọn cách tiếp cận của bạn dựa trên quy ước hiện tại của bạn - và ví dụ này là quá đơn giản để đưa ra quyết định về quy ước. Điều thú vị hơn là phải làm gì với nhiều tùy chọn get-out-now và câu lệnh IF lồng nhau - đó là một vùng màu xám thực sự.

Vậy quy ước của tôi là gì? Ah ... Tôi thực dụng, tôi không có bất kỳ quy tắc nào. Nếu nó có thể nhảy ra ngoài cửa sổ trong vài dòng đầu tiên, tôi lấy nó, bởi vì tôi không phải nhớ bất cứ khi nào tôi chỉnh sửa mã mà một số "cuộc gọi hàm không được đáp lại" vẫn có thể hoạt động ở bất kỳ thời điểm nào trong hàm.

Theo thời gian, chức năng này sẽ được đúc và nhào bằng các lỗi và cải tiến. Bạn có nhiều khả năng để giới thiệu một lỗi mới với cách tiếp cận thứ hai hơn so với trước đây, bởi vì lối thoát nhanh là hiển nhiên ngay từ đầu, trong khuôn mặt của bạn, và bạn không cần phải lo lắng về nó "quên" 50 dòng xuống chức năng . Trong kinh nghiệm giới thiệu lỗi của tôi, tất nhiên.

Đây là một cuộc gọi phức tạp hơn nếu bạn thiết lập mọi thứ và phải xé chúng xuống khi nhảy ra ngoài có thể buộc bạn phải sắp xếp 17 trạng thái mèo của Schrodinger trong đầu khi thực hiện thay đổi.

+0

Tôi nghĩ rằng một tá lồng nhau nếu các câu lệnh thường có nghĩa là mã gắn kết ít hơn, vì vậy chúng tôi phải cấu trúc lại nó, ít nhất là dễ đọc hơn. –

+1

"một cuộc gọi phức tạp hơn nếu bạn thiết lập mọi thứ và phải xé chúng xuống khi nhảy ra có thể buộc bạn phải ..." - không, không thực sự. Vì các ngoại lệ có thể khiến mã thoát sớm, nên việc rách xuống phải được mã hóa bằng cách sử dụng tính toán tham chiếu cuối cùng hoặc tự động. Nếu nó hoạt động đúng với các ngoại lệ, nó cũng sẽ làm việc với lối ra. – mghie

+0

mghie - true chỉ khi thoát qua ngoại lệ và tôi không thích sử dụng ngoại lệ để mô hình hóa mọi lần thoát mã, cộng với "rách xuống" của tôi không nhất thiết có nghĩa là các đối tượng. cũng tùy thuộc vào việc ngôn ngữ của bạn có ngoại lệ hay không - ví dụ: người dùng vba có chút thay đổi về điều này. Tôi biết câu hỏi là Delphi, nhưng nó hoạt động như một câu hỏi chung, đó là cách tôi tiếp cận nó. Tôi cũng phải làm việc trong một môi trường khác không có ngoại lệ và hỗ trợ chức năng kém, vì vậy tôi luôn đối phó với điều này. Tôi không có quy tắc nhanh chóng - chỉ cần triển khai những gì có vẻ đúng lúc đó. –

0

Theo ý kiến ​​của tôi, không phải là câu trả lời đúng.

Giải pháp đúng là chỉ bao gồm các phần "làm công cụ" và "thực hiện nhiều nội dung khác" trong quy trình. Sau đó, bọc các thủ tục gọi trong một tuyên bố nếu, chỉ gọi nó khi cần thiết.

Nếu, như bạn nói trong nhận xét của bạn, "làm công cụ" và "làm nhiều thứ hơn" bao gồm hai tên miền khác nhau, có thể bạn muốn hai thủ tục - một để "làm công cụ" và một "làm nhiều thứ hơn" . Nếu bạn thực hiện cả hai thủ tục với nhau thường xuyên đủ, bạn cũng có thể bao gồm một thủ tục thứ ba mà chỉ đơn giản là gọi hai thủ tục khác.

+0

@Thomas: Có ý nghĩa! Nhưng đôi khi, chúng tôi có những thứ phức tạp như vậy có vẻ tốt để gói gọn trong nhiều phần nhỏ như thủ tục, chức năng hoặc "truy vấn", nhưng mặt khác có vẻ tệ hơn để tạo hạt quá sâu, ngay cả khi cách này gắn kết sự gắn kết qui định. –

+0

Chừng nào mã không quá chi tiết đến mức khó hiểu, nó hoàn toàn ổn. Ngoài ra, một chức năng duy nhất không bao giờ nên thực hiện hai nhiệm vụ riêng biệt. –

2

Tôi nghĩ rằng điểm lối ra ít một đoạn mã có thì càng tốt vì vậy nó dễ dàng hơn để đọc và hiểu được. Lưu ý là tồi tệ hơn việc gỡ lỗi chức năng 100 dòng của người khác và phát hiện có 12 tình huống khác nhau được rải rác bên trong nó có thể khiến nó trở lại sớm.

+0

@Hardwareguy: Tôi hoàn toàn đồng ý với bạn. Một tạo phẩm mã phải có chỉ một điểm thoát, vì khi mọi thứ xảy ra sai, chúng tôi đã nhận được ngoại lệ. –

3

tôi thích:

if not Eval then Exit; 

vì mã trông sạch hơn theo cách đó.

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